Rate this page

Flattr this

Share an IP address between clients using iptables

Tested on

Debian (Etch, Lenny, Squeeze)
Ubuntu (Hardy, Intrepid, Jaunty, Karmic, Lucid, Maverick, Natty)


To share a public IP address between two or more clients using iptables


Suppose that you have three machines that need access to the public Internet, but only one public IP address. You have given the public address to a fourth machine which will act as a router. All four machines are connected via a local area network on which the router is and the three clients are, and The external interface of the router is ppp0 and its address is


These instructions assume that:


For outbound traffic to the public Internet there are two things which iptables must do:

The SNAT target performs both of these tasks. It should be used in the POSTROUTING chain of the nat table, however it should not be allowed to act on all traffic passing through that chain: only traffic destined for the public Internet. The simplest way to ensure this is to make the rule specific to the external interface of the router (ppp0):

iptables -t nat -A POSTROUTING -o ppp0 -j SNAT --to

Only the first packet of a connection traverses the POSTROUTING table: subsequent packets are automatically redirected. For this reason it is not necessary to provide a rule for the return path.

You should not use the SNAT target if you have a dynamic IP address. Instead use the MASQUERADE target, as described below. Also below are details of how to select the traffic by IP address as opposed to interface name, which may be preferable in some circumstances.


Testing must be done from a machine on the internal side of the router, which in this case is the local area network. A ping to a third-party public webserver will suffice for most purposes. You should try to avoid dependencies on services other than the one you are testing:


Use tcpdump or a similar tool to answer the following questions, stopping at the first one for which the answer is no:

  1. Does the outbound connection request reach the router?
  2. Does the router forward the request on to the external network?
  3. When the request leaves the router does it have an unchanged destination address, and a source address equal to the external address of the router?
  4. Does the response reach the router?
  5. Does the router forward the response on to the internal network?
  6. When the response leaves the router does it have an unchanged source address, and a destination address equal to that of the test machine?
  7. Does the response reach the test machine?

A failure at step 1, 4 or 7 indicates an issue that is unconnected with iptables or NAT, and which will need to be addressed before you can test further.

A failure at step 2 could indicate that:

A failure at step 3 could indicate that:

A failure at step 5 could indicate that:

Finally, a failure at step 6 could indicate that:

Further information about how to investigate these issues can be found in the troubleshooting guides for iptables and routing.


SNAT with a dynamic IP address

iptables provides an alternative to the SNAT target called MASQUERADE that is specifically intended for use with dynamic IP addresses. It has two benefits over SNAT in that situation:

If in the scenario above the public IP address had been assigned dynamically then an appropriate rule would be:

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

Traffic selection using IP addresses

The recommendation above was to make the SNAT rule specific to the external interface of the router. This is a safe option that gives precisely the right behaviour, however there may be circumstances where selection by IP address is preferred. For example:

There will usually be at least two address ranges that need to be excluded, therefore this cannot be done with a single rule. A solution that scales to any number of ranges is to remove them from the chain using the ACCEPT target:

iptables -t nat -A POSTROUTING -d -j ACCEPT
iptables -t nat -A POSTROUTING -d -j ACCEPT
iptables -t nat -A POSTROUTING -j SNAT --to

Tags: iptables | nat