Multiple Gateway

When there are several ways out of a firewall, there is a way to route traffic towards one route or the other, with iptables / Netfilter rules. A machine can then, for instance, simultaneously use a VPN for some connections, and an ADSL or fibre connection for others. This process is a little bit more complex on Linux than on BSD: we will cover the first case. All along the article, the command lines are preceded by a hash in order to avoid dangerous cut-paste.

To create multiple gateways, the advanced routing has to be activated on the kernel; that already is the case on the Linux kernel of most standard distributions. The second step is to define several routing tables, and then assign each chosen traffic to the chosen table. It can be done depending on the source IP, the destination IP, the port used, or even the type of traffic (icmp, upd, tcp).

Let’s go! We will take as an example a dynamic routing with a VPN on the one side and a fibre link on the other.

  • The gateway of the fibre link is on the eth0
  • The eth0 is
  • The local IP range is on the eth1

Step 1: set up multiple routing tables

Let us start by setting up the first table, for the fibre link. We will call it “tbl_fibre” .

#ip rule del from all fwmark 1 2>/dev/null
#ip route flush table tbl_fibre
#ip route add table tbl_fibre default dev eth0 via
#ip route add table tbl_fibre dev eth1 src
#ip route add table tbl_fibre dev eth0 src
#ip rule add from table tbl_fibre
#ip rule add fwmark 0x1 table tbl_fibre

Then comes the second table, for the VPN link (“tbl_vpn” ). The parameters of such a link are fluctuating, so we have to get them through a script.

#export TUNIP=`ifconfig | grep tun -A1 | grep “addr:” | cut -f2 -d “:” |cut -f1 -d ” “`
#export TUNDEV=`ifconfig | grep tun| awk ‘{ print $1 }’`
#export TUNROUTE=`route -n | grep tun| awk ‘{ print $1 }’`ip rule del from all fwmark 2 2>/dev/null
#ip route flush table tbl_vpn
#ip route add table tbl_vpn default dev $TUNDEV via $TUNIP
#ip route add table tbl_vpn $TUNROUTE dev $TUNDEV src $TUNIP
#ip route add table tbl_vpn dev eth1 src
#ip route add table tbl_vpn dev eth0 src
#ip rule add from $TUNIP table tbl_vpn
#ip rule add fwmark 0x2 table tbl_vpn
#for i in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > “$i”; done

Second step: configure Iptables 

Let us continue our example. The following configuration will allow you, in a LAN, to set up the following elements:

Multiple gateways
  • All traffic from IP 168.1.120 will be routed to the VPN.
  • Traffic from IP 168.1.3 will be routed to the fibre link, except packets going through port 49995, which will be routed to the VPN.
#iptables -t mangle -Fiptables -t mangle -X
#ip route flush cacheiptables -t mangle -A PREROUTING -s -j MARK –set-mark 2
#iptables -t mangle -A PREROUTING -s -p tcp –dport 49995 -j MARK –set-mark 2
#iptables -t mangle -A POSTROUTING -j CONNMARK –restore-markiptables -t mangle -A POSTROUTING -m mark ! –mark 0 -j ACCEPT
#iptables -t mangle -A POSTROUTING -o eth0 -j MARK –set-mark 1
#iptables -t mangle -A POSTROUTING -o $TUNDEV -j MARK –set-mark 2
#iptables -t mangle -A POSTROUTING -s -m conntrack –ctstate NEW -j MARK –set-mark 2
#iptables -t mangle -A POSTROUTING -j CONNMARK –save-mark

Source: Philippe Humeau

Lucie Saunois
Lucie Saunois
IT aficionado, specifically when it comes to cybersecurity, since she joined OT Group in 2015, Lucie specializes in making technical, and often complex, topics understandable by anyone.