6

TL;DR

How to set up two default routes in linux (corresponding to two interfaces), such that incoming traffic from both interfaces is accepted.

Scenario

I have a host having two NICs eth0 and eth1. Its connected to two networks, say:

  • Dev: eth0, IP: 1.1.1.4, Netmask: 255.255.255.0, Gateway: 1.1.1.1

  • Dev: eth1, IP: 2.2.2.4, Netmask: 255.255.255.0, Gateway: 2.2.2.1

(Both networks are connected to the internet.)

The routes are (ip route show):

default via 1.1.1.1 dev eth0 metric 1
default via 2.2.2.1 dev eth1 metric 2
1.1.1.0/24 dev eth0 src 1.1.1.4
2.2.2.0/24 dev eth1 src 2.2.2.4

(Lower metric means higher priority.)


Now when someone pings 2.2.2.4 from some external host (say 4.4.4.4), there is no reply.

The output of tcpdump -i eth1 on my host is:

22:41:27.431539 IP 4.4.4.4 > 2.2.2.4: ICMP echo request, id 8625, seq 4, length 64
22:41:28.439492 IP 4.4.4.4 > 2.2.2.4: ICMP echo request, id 8625, seq 5, length 64
22:41:29.447666 IP 4.4.4.4 > 2.2.2.4: ICMP echo request, id 8625, seq 6, length 64
22:41:30.455528 IP 4.4.4.4 > 2.2.2.4: ICMP echo request, id 8625, seq 7, length 64

After some research, it turns out that when linux network stack receives a packet from 4.4.4.4, it checks its routing table to see what interface should have been used for 4.4.4.4 (which is eth0 in the routing table). Now, since the packet came from eth1 interface, linux simply discards it (This policy is probably to prevent IP spoofing).


What I want is is:

  • Outgoing traffic (locally originated) should use eth0 interface by default.

  • Incoming traffic should be accepted from both interfaces. (So 4.4.4.4 should be able to ping both 1.1.1.4 and 2.2.2.4)

Tanmay
  • 225
  • 1
  • 2
  • 9
  • 1
    Use `iptables` for marking packets based on source address, and let route using this mark. There are a plenty of howtos on internet. http://lartc.org/howto/lartc.netfilter.html – Ipor Sircer Dec 28 '16 at 17:39

3 Answers3

9

Using iproute2 you can do something like this:

echo "1 admin" >> /etc/iproute2/rt_tables
echo "2 users" >> /etc/iproute2/rt_tables

ip rule add from 192.168.122.40/32 dev eth0 table admin
ip rule add from 192.168.123.41/32 dev eth1 table users

ip route add default via 192.168.122.1 dev eth0 table admin
ip route add default via 192.168.123.1 dev eth1 table users

Now you will have two routing table with two gateways.

c4f4t0r
  • 5,149
  • 3
  • 28
  • 41
3

This phenomena is called unicast rpf (reverse path forwarding) as a standard but reverse path filter in Linux. You may disable this without any important negative consequences (unless you're an isp.. and a router).

echo 0 > /proc/sys/net/ipv4/conf/default/rp_filter

Then your example should work as you want it to.

Jonas Bjork
  • 376
  • 1
  • 4
1

In case your application binds to 0.0.0.0 it is also required to add rules like:

ip rule add from 0.0.0.0/32 to 192.168.122.0/24 dev eth0 table admin

ip rule add from 0.0.0.0/32 to 192.168.123.0/24 dev eth1 table users

hargut
  • 3,848
  • 6
  • 10
  • 1
    0.0.0.0/32 is the very first host address of the Internet, and, as part of the 0.0.0.0/8 network it is reserved, I think you mean 0.0.0.0/0 – c4f4t0r Jun 02 '19 at 20:30
  • 1
    0.0.0.0/0 would mean the whole ipv4 range in cidr notation. The so called "unspecified" address is in ipv4 0.0.0.0/32, or in ipv6 :: /128. These addresses are used to indicate that there is no address available. The 0.0.0.0/8 block is reserved and only valid for source addresses. – hargut Jun 02 '19 at 20:59