Load balancing & NAT-ing multiple uplinks on Linux

LAN: eth0:

IP1: eth1:, gateway:

IP2: eth2:, gateway:

So here is how I would do by using iptables method:

Route tables

First edit the /etc/iproute2/rt_tables to add a map between route table numbers and ISP names

10 IP1 
20 IP2 

So table 10 and 20 is for ISP1 and ISP2, respectively. I need to populate these tables with routes from main table with this code snippet (which I have taken from hxxp://

#!/bin/bash ip route show table main | grep -Ev '^default' | while read ROUTE ; do 
ip route add table IP1 $ROUTE 

And add default gateway to ISP1 through that ISP1’s gateway:

ip route add default via table IP1 

Do the same for IP2

So now I have 2 route tables, 1 for each IP.


OK now I use iptables to evenly distribute packets to each route tables. More info on how this work can be found here ( and here (

# iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark 
# iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j ACCEPT 
# iptables -t mangle -A PREROUTING -j MARK --set-mark 10 
# iptables -t mangle -A PREROUTING -m statistic --mode random --probability 0.5 -j MARK --set-mark 20 
# iptables -t mangle -A PREROUTING -j CONNMARK --save-mark 


Well NAT is easy:

# iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE 
# iptables -t nat -A POSTROUTING -o eth2 -j MASQUERADE

1 comment to Load balancing & NAT-ing multiple uplinks on Linux

  • Valeriy

    Thanks, but in order to force google services to work correctly I’ve modified mark rules in the following way:

    iptables -A PREROUTING -t mangle -i $LAN_IF -m state –state NEW -j MARK –set-mark 10
    iptables -A PREROUTING -t mangle -i $LAN_IF -m state –state NEW -m statistic –mode random –probability 0.5 -j MARK –set-mark 20

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>