How to Loadbalance Outgoing Traffic with Iptables?

I have a centos 7 server with 5 IPS like 192.168.0.2/29 to 192.168.0.5/29.I want to change Outgoing traffic in roundrobin method because i need to use all ips to my project. so am trying to configure iptables with the command

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.1/29 -m statistic --mode nth --every 4 --packet 0 -p tcp --dport 25 -j SNAT --to-source 192.168.0.3
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.1/29 -m statistic --mode nth --every 3 --packet 0 -p tcp --dport 25 -j SNAT --to-source 192.168.0.2

like that its working properly. its taking traffic ascending order(192.168.0.3,192.168.0.2) in same thing i try to configure centos 6 its running decending order example

(192.168.0.2,192.168.0.3). now < i want to know meaning of --every 3 or 4 >


Solution 1:

There are two methods. It's really statistics. The first method (as by OP) leads to:

  • 1/4 (--every 4) gets first choice
  • 1/3 (--every 3) of remaining gets 2nd choice

There are only two rules in OP's question but one can assume two more (or one more plus default) would follow:

  • 1/2 of remaining gets 3rd choice
  • remaining gets 4th choice

As iptables' nat table is handling only the initial packet of a flow, the whole flow will then follow the rule of the initial packet (other packets in the same flow are handled directly by conntrack and not seen by the nat table).

Each choice got 1/4:

  • 1/4 = 1/4
  • 1/3 * (1 - 1/4) = 1/4

And for the remaining half (if more rules are used):

  • 1/2 * (1 - 2 * 1/4) = 1/4
  • 1 * (1 - 3 * 1/4) = 1/4

The other method would have been to use only --every 4 in each rule but change the modulus with --packet with rules similar to:

iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.1/29 -m statistic --mode nth --every 4 --packet 0 -p tcp --dport 25 -j SNAT --to-source 192.168.0.3
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.0.1/29 -m statistic --mode nth --every 4 --packet 1 -p tcp --dport 25 -j SNAT --to-source 192.168.0.2
[...]
  • 1st rule gets packets where packet count % 4 = 0 (with % meaning "remainder of division by"): 1/4 of them
  • 2nd rule gets packets where packet count % 4 = 1 : 1/4 of them

etc.

The second method might be easier to understand, but the 1st method is easier to scale: just prepend a rule with a value for --every increased by one if one has to use an additional round-robin.