2

i want to every source ip (i have many) will be always the same SNAT (i have two. which for me can assigned randomaly the first time).

for example:

10.0.0.1 > 8.0.0.1
10.0.0.2 > 8.0.0.2
10.0.0.3 > 8.0.0.1
10.0.0.4 > 8.0.0.2
10.0.0.1 > 8.0.0.1
10.0.0.2 > 8.0.0.2

ect.

It is possible?

2

Apparently -j SNAT --persistent works only for a src/dst pair so when connecting to different destinations there's no guarantee that the same source will be used.
Instead, from man iptables-extensions:

u32
U32 tests whether quantities of up to 4 bytes extracted from a packet have specified values. The specification of what to extract is general enough to find data at given offsets from tcp headers or payloads.

As long as you want exactly 2^n IPs after transformation (here you want 2, so that's OK) it's then easy to use only 2^n (here 2) rules by checking the end of the original IP modulo 2^n and doing a selective SNAT from the result. The solution is then:

iptables -t nat -I POSTROUTING -s 10.0.0.0/16 ! -d 10.0.0.0/16 -m u32 --u32 '12 & 0x1 = 0x1' -j SNAT --to-source 8.0.0.1
iptables -t nat -I POSTROUTING -s 10.0.0.0/16 ! -d 10.0.0.0/16 -m u32 --u32 '12 & 0x1 = 0x0' -j SNAT --to-source 8.0.0.2

12 is the position of the source IP address in the packet

Please replace -I with a -A and all the /16 (you said many!) with any other size if needed.

If you don't know in advance the target IPs (8.0.0.1 and 8.0.0.2) then of course you'll have to use some variables in a script to replace the values (8.0.0.1 and 8.0.0.2)

If you had 4 available public IPs instead, you'd change the mask & 0x1 to & 0x3 and would use a total of 4 SNAT, one for each of the 4 possible results 1 2 3 0 . And so on...

Because there's no equivalent target extension rule it seems impossible with iptables to do a "generic" transformation on the target IP to use directly the result of the test in an unique rule.

1

i make bpf match to make mod operation for divide any amount external ip

like this ip % 3 == 2

this bash code

#!/bin/bash

mod=7

src_ip_mod (){ 
    eq=$1
    echo "15,48 0 0 0,84 0 0 240,21 0 11 64,32 0 0 12,2 0 0 1,52 0 0 ${mod},7 0 0 5,0 0 0 ${mod},44 0 0 0,7 0 0 5,96 0 0 1,28 0 0 0,21 0 1 ${eq},6 0 0 65535,6 0 0 0"
}

mod=3

iptables -t nat -A POSTROUTING -m bpf --bytecode "`src_ip_mod 0`" -j SNAT --to-source 8.0.0.1
iptables -t nat -A POSTROUTING -m bpf --bytecode "`src_ip_mod 1`" -j SNAT --to-source 8.0.0.2
iptables -t nat -A POSTROUTING -m bpf --bytecode "`src_ip_mod 2`" -j SNAT --to-source 8.0.0.3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.