Iptables based uplink load balancing

Synopsis

You two uplinks wan1 and wan2. The goal is to have traffic load balanced over them.

Routing policies

iproute2 supports routing policies implemented as multiple routing table and routing rule governing when to use which table. A routing rule can consider the source ip or a firewall mark set by iptables.

To set up a new routing table, edit the /etc/iproute2/rt_tables:
#
# reserved values
#
255     local
254     main
253     default
0       unspec
#
# local
#
#1      inr.ruhep
11   wan1
12   wan2
I've added two new routing tables, wan1 and wan2. These new tables are not used yet, as evident by ip rule list. First, we need to add a rule routing traffic originating from the wan interfaces IP address to the corresponding gateway - this may not be necessary if both gateways provide a route 0.0.0.0 and the static local subnet routes exist forcing selection of the appropriate gateway. When in doubt add the policy rule anyway, the do no harm.
ip rule add from $WAN1_IP table 11
ip rule add from $WAN2_IP table 12
ip rule add fwmark 1 table 11
ip rule add fwmark 2 table 12
The fwmark policy rules are necessary for routing traffic that can't have it's fate decided by the routing policy based on source ip address, sometime you can do without them E.G. you are routing traffic (not NAT, routing) from a subnet to multiple upstreams - personally i'd just use a multi-path route on such a case but sometimes crazy things must be done ;). It's really out of scope here anyway.

Iptables

iptables/netfilter include a few modules probabiltyuseful for load balancing setups. The first is statistic, the module can operate in two modes: random and nth, matching at random according to a probability factor or matching every nth packet. statistic can be used for statistical load balancing, which is good if you don't know the actual bandwidth of the connections or for a subset of the traffic.

Second useful module is rateest, a module that implements a traffic rate monitor and allows decision based on comparisons with the counter.

Other useful module are limit, hashlimit, state, mark and connmark.

FW marks

Theres really no point in LB packets, only connections. The last thing i'd want are packets from the same connection dispersed over two different uplinks. This might actually work if you are using true routing, but with NATed uplinks not only will your connections fail, you will also probably be blacklisted as attacker. Even with true routing, this is probably a bad idea. Differences in traversal time will cause packets to arrive out of order and wait longer for recombination.

So really, we need iptables connection tracking and mark packets consistently. The connmark module is just the thing for the job, it marks connection with a special mark - ctmark. ctmark isn't supported outside netfilter, so the connection mark will copied to nfmark, the standard packet mark.

Example LB setup

iptables -t mangle -N LB_FATE
iptables -t mangle -A LB_FATE -m rateest --rateest1 wan1 --rateest1-bps $WAN1_RATE --rateest2 wan2 --rateest2-bps $WAN2_RATE --rateest-delta --rateest-gt -j CONNMARK --set-mark 1
iptables -t mange -A LB_FATE -m connmark ! --mark 1 -j CONNMARK --set-mark 2

iptables -t mangle -A PREROUTING -m state --state NEW -i lan0 -s $LAN_NET -d ! $LAN_NET -j LB_FATE
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark

iptables -t mangle -A POSTROUTING -m rateest -o wan1 -j RATEEST --rateest-name wan1 --rateest-interval 250ms --rateest-ewmalog 0.5s
iptables -t mangle -A POSTROUTING -m rateest -o wan2 -j RATEEST --rateest-name wan2 --rateest-interval 250ms --rateest-ewmalog 0.5s

iptables -t nat -A POSTROUTING -o wan1 -j SNAT --to-source $WAN1_IP
iptables -t nat -A POSTROUTING -o wan2 -j SNAT --to-source $WAN2_IP
The wan1 routing table:
WAN1_NET dev wan1  proto kernel  scope link  src WAN1_IP 
LAN_NET dev lan  proto kernel  scope link  src LAN_IP 
default dev wan1 via WAN1_GW proto static
The wan2 table is roughly the same with connection specific data of course. The magic is the different default route on both tables.

Rate Estimation and Async lines

DSL and many cable provider are async, so using rate estimation based on outgoing traffic will provide poor results. Instead, measure the rate of incoming traffic and use the rate to determine the route of outgoing traffic. The rate estimation rule will thus be:
iptables -t mangle -A POSTROUTING -m rateest -i wan1 -j RATEEST --rateest-name wan1 --rateest-interval 250ms --rateest-ewmalog 0.5s
iptables -t mangle -A POSTROUTING -m rateest -i wan2 -j RATEEST --rateest-name wan2 --rateest-interval 250ms --rateest-ewmalog 0.5s

-- AvishaiIshShalom - 26 Jul 2010
Topic revision: r3 - 27 Jul 2010 - 15:17:24 - AvishaiIshShalom
 

This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback