Load balancing IPTABLES POSTROUTING rules

6,867

Solution 1

iptables has a statistic module, which could be used. It can operate in two modes which are either randomized or deterministic. Here is how your rules could be written with that module.

Deterministic version:

-A POSTROUTING -s 10.8.0.0/24 -m statistic --mode nth --every 5 --packet 0 -j SNAT --to-source 192.0.2.1
-A POSTROUTING -s 10.8.0.0/24 -m statistic --mode nth --every 4 --packet 0 -j SNAT --to-source 192.0.2.2
-A POSTROUTING -s 10.8.0.0/24 -m statistic --mode nth --every 3 --packet 0 -j SNAT --to-source 192.0.2.3
-A POSTROUTING -s 10.8.0.0/24 -m statistic --mode nth --every 2 --packet 0 -j SNAT --to-source 192.0.2.4
-A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source 192.0.2.5

Randomized version:

-A POSTROUTING -s 10.8.0.0/24 -m statistic --mode random --probability 0.2 -j SNAT --to-source 192.0.2.1
-A POSTROUTING -s 10.8.0.0/24 -m statistic --mode random --probability 0.25 -j SNAT --to-source 192.0.2.2
-A POSTROUTING -s 10.8.0.0/24 -m statistic --mode random --probability 0.3333333333 -j SNAT --to-source 192.0.2.3
-A POSTROUTING -s 10.8.0.0/24 -m statistic --mode random --probability 0.5 -j SNAT --to-source 192.0.2.4
-A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source 192.0.2.5

Solution 2

To be clear, this is not load-balancing. Load balancing would balance the load over multiple hosts. You're only spreading the source address across multiple IP's on the same host. It's not going to give you any performance benefits, but make your set up more complicated.

But, assuming you want to go ahead.

According to iptables-extensions man page.

SAME (IPv4-specific)

Similar to SNAT/DNAT depending on chain: it takes a range of addresses (`--to 1.2.3.4-1.2.3.7') and gives a client the same source-/destination-address for each connection.
N.B.: The DNAT target's --persistent option replaced the SAME target.

--to ipaddr[-ipaddr]
Addresses to map source to. May be specified more than once for multiple ranges.
--nodst
Don't use the destination-ip in the calculations when selecting the new source-ip
--random
Port mapping will be forcibly randomized to avoid attacks based on port prediction (kernel >= 2.6.21).

But obviously the range has to be linear. e.g. 1.2.3.4-1.2.3.7 = 1.2.3.4, 1.2.3.5, 1.2.3.6, 1.2.3.7 I'm not sure if that matches your setup.

But if it does you can do:

-A POSTROUTING -s 10.8.0.0/24 -j SAME --to x1.x1.x1.x1-x5.x5.x5.x5 --nodst

The --nodst option should make it a little more random as to which source-ip is chosen, I don't know whether it uses a round-robin approach or a simple randomiser.

Share:
6,867

Related videos on Youtube

Amit Bareket
Author by

Amit Bareket

Updated on September 18, 2022

Comments

  • Amit Bareket
    Amit Bareket over 1 year

    I have an interface with 5 IP addresses assigned to it (as virtual adapters) let's call them x1,x2,x3,x4 and x5.

    Currently I have SNAT POSTROUTING forwarding rules from local source range to specific public ip address. Below is an example for the current rule:

    -A POSTROUTING -s 10.8.0.0/24 -j SNAT --to-source x1.x1.x1.x1
    

    What I would like to achieve is that new established local connections will be post-routed and assigned to one of the IPs above (x1/x2/x3/x4/x5) randomly / round robin. I tired to look for a solution online but I didn't find any information for how to do so. I am almost certain that it practical.

  • Amit Bareket
    Amit Bareket over 9 years
    hi there, I have just realized that the IP assignment does not stay persistent from the point connection has started till it ended (per source IP address). There is any way to keep it persistent once an IP address was allocated for source IP address?
  • kasperd
    kasperd over 9 years
    @AmitBareket Sounds like the connection tracking entry might have expired. That is a risk inherent to any stateful middlebox, which includes most NAT solutions. You can use conntrack -L to see all current connection tracking entries and how many seconds will pass before they are expired.