Currently I’m testing GlusterFS as a replicating network filesystem. GlusterFS depends on rpcbind package. No problem with that, but I usually want to have the services that run on my machines to only listen on those addresses/interfaces that are needed to fulfill the task. This is especially important, because rpcbind can be abused by remote attackers for rpc amplification attacks (dDoS). So, the rpcbind man page states:
-h : Specify specific IP addresses to bind to for UDP requests. This option may be specified multiple times and is typically necessary when running on a multi-homed host. If no -h option is specified, rpcbind will bind to INADDR_ANY, which could lead to problems on a multi-homed host due to rpcbind returning a UDP packet from a different IP address than it was sent to. Note that when specifying IP addresses with -h, rpcbind will automatically add 127.0.0.1 and if IPv6 is enabled, ::1 to the list.
Ok, although there is neither a /etc/default/rpcbind.conf nor a /etc/rpcbind.conf nor a sample-rpcbind.conf under /usr/share/doc/rpcbind, some quick websearch revealed a sample config file. I’m using this one:
# /etc/init.d/rpcbind
OPTIONS=””# Cause rpcbind to do a “warm start” utilizing a state file (default)
# OPTIONS=”-w “# Uncomment the following line to restrict rpcbind to localhost only for UDP requests
OPTIONS=”${OPTIONS} -h 192.168.1.254″
#127.0.0.1 -h ::1″# Uncomment the following line to enable libwrap TCP-Wrapper connection logging
OPTIONS=”${OPTIONS} -l “
As you can see, I want to bind to 192.168.1.254. After a /etc/init.d/rpcbind restart verifying that everything works as desired with netstat is showing…
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 0 2084266 30777/rpcbind tcp6 0 0 :::111 :::* LISTEN 0 2084272 30777/rpcbind udp 0 0 0.0.0.0:848 0.0.0.0:* 0 2084265 30777/rpcbind udp 0 0 192.168.1.254:111 0.0.0.0:* 0 2084264 30777/rpcbind udp 0 0 127.0.0.1:111 0.0.0.0:* 0 2084260 30777/rpcbind udp6 0 0 :::848 :::* 0 2084271 30777/rpcbind udp6 0 0 ::1:111 :::* 0 2084267 30777/rpcbind
Whoooops! Although I’ve specified that rpcbind should only listen to 192.168.1.254 (and localhost as described by the man page) rpcbind is still listening on all addresses. Quick check if the process is using the correct options:
root 30777 0.0 0.0 37228 2360 ? Ss 16:11 0:00 /sbin/rpcbind -h 192.168.1.254 -l
Hmmm, yes, -h 192.168.1.254 is specified. Ok, something is going wrong here…
According to an entry in Ubuntus Launchpad I’m not the only one that experienced this problem. However this Launchpad entry mentioned that upstream seems to have a fix in version 0.2.3, but I experienced the same behaviour in stable as well as in unstable, where the package version is 0.2.3-0.2. Apparently the problem still exists in Debian unstable.
I’m somewhat undecided whether to file a normal bug against rpcbind or if I should label it as a security bug, because it opens a service to the public that can be abused for amplification attacks, although you might have configured rpcbind to just listen on internal addresses.
RTFM
If you read the man page for rpcbind, it says the -h switch is only for udp and if ipv6 is enabled will add localhost and ::1 for that transport. This looks like what happened.
“-h Specify specific IP addresses to bind to for UDP requests. This option may be specified multiple times and is typically necessary when running on a multi-homed host. If no -h option is specified, rpcbind will bind to INADDR_ANY, which could lead to problems on a multi-homed host due to rpcbind returning a UDP packet from a different IP address than it was sent to. Note that when specifying IP addresses with -h, rpcbind will automatically add 127.0.0.1 and if IPv6 is enabled, ::1 to the list.”