This article describes a Linux server set up with 2 interfaces (eth0) and (eth1). Each interface has a separate ISP, network details and default gateway. eth0 has two sets of network details on the same interface and so a virtual interface (eth0:0) must be created to handle the second IP.
By default, Linux only allows for one default gateway. Let’s see what happens if we try to use multiple uplinks with 1 default gateway. Assume eth0 is assigned 192.168.1.2/24 and eth1 is assigned 172.16.1.5/16. Let’s say our default gateway is 192.168.1.1 (which of course is found through eth0) but there’s also a 172.16.0.1 gateway on eth1 which we can’t enter as Linux only allows for the one.
Our routing table now looks like this:
root@www1:~# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.1.1 0.0.0.0 UG 0 0 0 eth0 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0 172.16.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth1
If a packet comes in to us, routed through the 172.16.0.1 gateway from say 126.96.36.199, our machine will receive it. When it tries to reply to 188.8.131.52 however, it runs down the routing table and sees that it’s not local to eth0 or eth1 and therefore will get routed out through the default gateway (192.168.1.1) – the problem is, this is the wrong gateway and so the target machine will ignore our response due to it being out of sequence and from the wrong IP.
Using iproute2, Linux can track multiple routing tables and therefore multiple default gateways. If the packet comes in through one interface and to one IP, it will go out via a specific default gateway. The script to achieve this is as follows:
IP1="192.168.1.10" #interface IP NM1="255.255.255.0" #interface netmask NW1="192.168.1.0" #interface network address PR1="24" #interface prefix (based on netmask) GW1="192.168.1.1" #interface gateway IP2="10.4.50.4" NM2="255.0.0.0" NW2="10.0.0.0" PR2="8" GW2="10.0.0.1" IP3="172.16.5.4" NM3="255.255.0.0" NW3="172.16.0.0" PR3="16" GW2="172.16.0.1" #down the interfaces and wipe the existing config ifconfig eth0 down ifconfig eth1 down #set ips ifconfig eth0 up ifconfig eth1 up ifconfig eth0 $IP1 netmask $NM1 ifconfig eth0:0 $IP2 netmask $NM2 ifconfig eth1 $IP3 netmask $NM3 #add default gw route add default gw $GW1 # set gw1 as system's default gw #create tables echo "103 WAN3" >> /etc/iproute2/rt_tables echo "102 WAN2" >> /etc/iproute2/rt_tables echo "101 WAN1" >> /etc/iproute2/rt_tables #iproute2 routing ip route add $NW1/$PR1 dev eth0 src $IP1 table WAN1 ip route add default via $GW1 table WAN1 ip route add $NW1/$PR1 dev eth0 src $IP1 ip rule add from $IP1 table WAN1 #-- ip route add $NW2/$PR2 dev eth0:0 src $IP2 table WAN2 ip route add default via $GW2 table WAN2 ip route add $NW2/$PR2 dev eth0:0 src $IP2 ip rule add from $IP2 table WAN2 #-- ip route add $NW3/$PR3 dev eth1 src $IP3 table WAN3 ip route add default via $GW3 table WAN3 ip route add $NW3/$PR3 eth1 src $IP3 ip rule add from $IP3 table WAN3
Rules and tables can also be shown and verified with:
ip route list table route2 ip rule show
Your Linux box can now correctly handle traffic coming in through any of the 3 IPs. iproute2 can in fact do a whole lot more than manage multiple default gateways, however this is one of it’s most common use cases.