The NAT problem sometimes becomes very acute.

The task looks something like this:

  • Linking an internal address to an external one
  • Balancing external traffic
  • Possibility to take the client to another white address
  • Ability to transfer all clients to another white address
  • Rotation of white addresses among clients (and so as not to get used to one address)

Creating ipset tables

ipset create no_nat nethash
ipset create nat_01 iphash timeout 86400
ipset create nat_02 iphash timeout 86400
ipset create nat_03 iphash timeout 86400
...
ipset create nat_16 iphash timeout 86400

Implementation in NAT

iptables -t nat -A POSTROUTING -s 100.64.0.0/10 -o bond0 -m set ! --match-set no_nat dst -j NAT
iptables -t nat -A NAT -m set --match-set nat_01 src -j SNAT --to-source 192.0.2.1
iptables -t nat -A NAT -m set --match-set nat_02 src -j SNAT --to-source 192.0.2.2
iptables -t nat -A NAT -m set --match-set nat_03 src -j SNAT --to-source 192.0.2.3
...
iptables -t nat -A NAT -m set --match-set nat_16 src -j SNAT --to-source 192.0.2.16
iptables -t nat -A NAT -m limit --limit 10/s --limit-burst 10 -j JNAT

The JNAT module is not included in the standard Linux package - it is a homemade module.

What’s going on here?

The client connects - it is not in any table - it ends up in JNAT.

The JNAT module scatters the tables evenly - i.e. throws into the table with minimal contents.

The next packet is matched by source and goes to the desired address.

After 24 hours, the address is removed from the table and goes back to JNAT.

This scheme has only one drawback - the first packets are not transferred. You can, of course, loop tables - but this can shoot yourself in the foot.

Or apply this rule:

iptables -t nat -A NAT -j SNAT --to-source 192.0.2.1-192.0.2.16 --persistent

Here another question arises - “what if you need to have NAT in several ranges?”….