Mailing List Archive

howto make SNAT preserve translation ip for all connections from the same internal ip
Hi, all.
Say, I use iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source for NAT. Accordingly to man:
The source IP for each stream that we open would then be allocated randomly from these (, and a single stream would always use the same IP address for all packets within that stream.

What if I want that internal ip from block is always translated into the same external ip?
PF from OpenBSD does it:

For nat and rdr rules, (as well as for the route-to, reply-to and dup-to
rule options) for which there is a single redirection address which has a
subnet mask smaller than 32 for IPv4 or 128 for IPv6 (more than one IP
address), a variety of different methods for assigning this address can
be used:

The bitmask option applies the network portion of the redirection
address to the address to be modified (source with nat, destination
with rdr).

The random option selects an address at random within the defined
block of addresses.

The source-hash option uses a hash of the source address to deter-
mine the redirection address, ensuring that the redirection address
is always the same for a given source. An optional key can be
specified after this keyword either in hex or as a string; by de-
fault pfctl(8) randomly generates a key for source-hash every time
the ruleset is reloaded.

The round-robin option loops through the redirection address(es).

When more than one redirection address is specified, round-robin is
the only permitted pool type.

With nat rules, the static-port option prevents pf(4) from modify-
ing the source port on TCP and UDP packets.

Additionally, the sticky-address option can be specified to help ensure
that multiple connections from the same source are mapped to the same
redirection address. This option can be used with the random and round-
robin pool options. Note that by default these associations are de-
stroyed as soon as there are no longer states which refer to them; in or-
der to make the mappings last beyond the lifetime of the states, increase
the global options with set timeout src.track. See STATEFUL TRACKING
OPTIONS for more ways to control the source tracking.