Linux — IPTABLES NAT, Dynamic NAT, NAT Overloading/Masquerade

If you have had experience with NATs via Cisco Routers or read about them in your CCNA studies, there are 3 Network Address Translation(NAT) types. Technically, two, see here, plus a third special case.

  • Static NAT, one-to-one mapping
  • Dynamic NAT, pool-to-pool mapping
  • Dynamic NAT with PAT Overload, many-to-one mapping

So as you can see the two types are static NAT and Dynamic NAT, with the special case of Dynamic NAT with PAT overload.


NAT, also know as “static NAT”,  is a one-to-one mapping of an inside IP address to outside IP address. For each real outside IP you address have, you also have to have an inside IP mapped to it. This can be useful to hide a inside entities true identify, and also put it behind a firewall rather than directly exposed to the outside networks. Keeping in mind the example below exposes all ports and protocols to this inside address. You can use further filters on each statement, such as specifiying ACCEPT’d ports, etc.

iptables example:
eth0 = outside network
eth1 = inside network

iptables -t nat -A PREROUTING -d {outside_address} -j DNAT --to-destination {inside_address} 
iptables -t nat -A POSTROUTING -d {inside_address} -j SNAT --to-destination {outside_address}

Dynamic NAT

Dynamic NAT, or NAT pool, is a pool-to-pool network translation. You have a pool of inside IP addresses and a pool of outside IP addresses to dynamical translate to. Each dynamic NAT is selects an outside IP address to use when connecting to outside networks, this 1:1 mapping persists as long as the connection takes place. This is common for DMZ networks where there is a set amount of outside IP addresses that need to be mapped to  inside IP addresses.

iptables example:
eth0 = outside network
eth1 = inside network

iptables -t nat -A POSTROUTING -o eth0 -s -j SNAT --to-source

Or more finite.

iptables -t nat -A POSTROUTING -o eth0 -s -j SNAT --to-source

NOTICE: outside IP address range has to be within the same network. Also you can split up the ranges by using the –to parameter.

Dynamic NAT with PAT Overload

Dynamic NAT with PAT Overload, also known as IP Masquerading, is a Dynamic Network Address Translation with Port Address Translation Overload. This is a many-to-one NAT type and works by using a single outside IP address for many inside IP addresses. Many inside IP addresses share this outside IP address, by borrowing source ports from the outside IP. This effectively is how the NAT keeps track of the outside-to-inside and inside-to-outside translations. Dynamic NAT with PAT Overload is limited to the amount of source ports not in use, as the PAT piece utilizes unused source ports on the single outside address to create the inside mapping. Exceeding the number of ports available is referred to as port exhaustion. Therefore, if you foresee exceeding 65000+ connections, you will need to be aware of this limitation and assign more outside IP address to accommodate.

iptables example:
eth0 = outside network
eth1 = inside network

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Or if you have an outside IP address that does not change use SNAT for the entire outbound interface. I’ve read some articles stating that MASQUERADE is CPU intensive, so use SNAT when you possible.
NOTICE: Masquerade specifies an interface, SNAT specifies an IP.

iptables example:
eth0 = outside network
eth1 = inside network

iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source {outside_address}

You could also specfiy which inside networks are allowed to SNAT using the outside IP address.

iptables -t nat -A POSTROUTING -o eth0 -s -j SNAT --to-source {outside_address_1}

Split them up based on inside IP address information. For example, let’s say you have a for Users and a for Servers. Let’s also assume you have at least two outside IP addresses. You can do the following to not have IP’s overlap from different networks

iptables -t nat -A POSTROUTING -o eth0 -s -j SNAT --to-source {outside_address_2}

Keeping Track of Those Connections

Now you may be thinking how can I see these mappings that the iptable NAT’ing is creating. The Netfilter community has a nice little application to display the current NAT table conntrack can be used to display real time NATing, simlar to Cisco’s show ip nat translations command in the IOS,and it’s available in Ubuntu’s package repository.

Install it:

sudo apt-get install conntrack

List Connection Table:

sudo conntrack -L

Show Connections:

sudo conntrack -E

You will see [NEW],[UPDATE],[ASSURED],[DESTROY].
[NEW] = New NAT traffic flow
[UPDATE] = Active NAT traffic flows
[ASSURED] = Firewall sees NAT traffic in both directions for pair
[DESTROY] = Destroys NAT mapping

You can also filter out connections, see here for parameters.


  1. Netfliter NAT Documentation
  2. Linux Home Networking
  3. Conntrack
  4. iptables wikipedia