Disable rp_filter on unix

Sometimes in a more complicated network setups you want to disable rp_filtering.

For a good explanation of what rp_filter is and why it is enabled see this excellent slashroot article here.

I came across a situation where one box had two NICs:

# grep -Ev '^#.*$' /etc/network/interfaces

auto lo
iface lo inet loopback

auto eth1
iface eth1 inet static

auto eth2
iface eth2 inet static
up route add default gw

From another box that was in the same range I could only access this machine over its ip address. When I tried a ping, curl, wget, ssh, telnet or whatever to I got nothing.

A tcpdump on this box showed that packets on the interface were received but my machine had trouble sending the return packets causing the above described behaviour. You get; Nothing.

And whenever I tried to access this box from a machine in the network I got the same behaviour but with the ip.

The routing table on this box looks like the following:

# ip route dev eth1  proto kernel  scope link  src dev eth2  proto kernel  scope link  src 
default via dev eth2 
default via dev eth1  metric 100

Since you cannot have two default routes the kernel tries to sent packets back over the wrong interface.

I solved this by disabling reverse path filtering.

To get your current kernel configuration run:

sysctl -a | grep \\.rp_filter

To enable rp_filtering (persisted up until the next reboot)

sysctl -w net.ipv4.conf.all.rp_filter=1
sysctl -w net.ipv4.conf.default.rp_filter=1
sysctl -w net.ipv4.conf.lo.rp_filter=1

# Replace eth1 and eth2 with your interface names
sysctl -w net.ipv4.conf.eth2.rp_filter=1
sysctl -w net.ipv4.conf.eth1.rp_filter=1

To disable rp_filtering (persisted up until the next reboot)

sysctl -w net.ipv4.conf.all.rp_filter=0
sysctl -w net.ipv4.conf.default.rp_filter=0
sysctl -w net.ipv4.conf.lo.rp_filter=0

# Replace eth1 and eth2 with your interface names
sysctl -w net.ipv4.conf.eth2.rp_filter=0
sysctl -w net.ipv4.conf.eth1.rp_filter=0

If you want to disable rp_filtering permanently create a file 90-disable-rp_filter.conf inside /etc/sysctl.d with the following contents:

# cat /etc/sysctl.d/90-disable-rp_filter.conf