Aparentemente, o -j SNAT --persistent
funciona apenas para um par src / dst, portanto, ao se conectar a destinos diferentes, não há garantia de que a mesma fonte será usada.
Em vez disso, de 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.
Contanto que você queira exatamente 2 ^ n IPs após a transformação (aqui você quer 2, então tudo bem) então é fácil usar apenas 2 ^ n (aqui 2) regras verificando o final do módulo IP original 2 ^ n e fazendo um SNAT seletivo do resultado. A solução é então:
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 é a posição do endereço IP de origem no pacote
Por favor, substitua -I por um -A e todos os / 16 (você disse muitos!) com qualquer outro tamanho, se necessário.
Se você não souber antecipadamente os IPs de destino (8.0.0.1 e 8.0.0.2), é claro que você terá que usar algumas variáveis em um script para substituir os valores (8.0.0.1 e 8.0.0.2)
Se você tivesse 4 IPs públicos disponíveis, mudaria a máscara & 0x1
para & 0x3
e usaria um total de 4 SNAT, um para cada um dos 4 resultados possíveis 1 2 3 0. E assim por diante ...
Como não há regra de extensão de destino equivalente, parece impossível que o iptables faça uma transformação "genérica" no IP de destino para usar diretamente o resultado do teste em uma regra exclusiva.