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 192.168.0.1/24 and the three clients are 192.168.0.2, 192.168.0.3 and 192.168.0.4.
The external interface of the router is ppp0 and its address is 203.0.113.1.
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 203.0.113.1
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:
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.
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
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 127.0.0.0/8 -j ACCEPT iptables -t nat -A POSTROUTING -d 192.168.0.0/24 -j ACCEPT iptables -t nat -A POSTROUTING -j SNAT --to 203.0.113.1