How to set up two default routes in linux

26,500

Solution 1

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.

Solution 2

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.

Solution 3

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

Share:
26,500

Related videos on Youtube

Tanmay
Author by

Tanmay

I am powerful.

Updated on September 18, 2022

Comments

  • Tanmay
    Tanmay almost 2 years

    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)

  • c4f4t0r
    c4f4t0r about 5 years
    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