Examples
Let's look at some examples of using masquerading, snat, and dnat. Let's first assume the following:
-
Your IP is dynamically assigned by your ISP.
-
You want to allow your entire Class C network of 192.168.50.0/24 access to the Web.
To implement these, we'll need to specify the NAT table. In the previous article, we specifically called the filter table with the -t filter. But if you've been following, you know that's not necessary. Here it is:
iptables -t nat -A POSTROUTING -o ppp+ -s 192.168.50.0/24 -j MASQUERADE
Because you're changing the source address, you want to do that at the very last possible minute. If we do it after the packet has left the system (impossible, of course, but an easy way to think about it), the system will remember the packet that passed through the routing table and the iptables connection tracking software, but it will return to the firewall for rerouting back to the real originating system. So, we're going to specify POSTROUTING (an outside-the-box thing) for where the source IP is changed.
Because the source IP is changed at the outgoing interface, the only interface that you can specify with POSTROUTING is the interface that the packet will leave on. Here, we'll take that to be any one of the ppp interfaces. We can specify ppp0, but if we simply say ppp+, the "+" means any ppp interface (just in case it happens to be ppp1 sometime). Your outgoing interface may also be ippp+, eth0, tr1, and so on. Any legal device can be used. Just remember that POSTROUTING also demands the -o option when you specify an interface (you can't use -i).
The next delimiter that we put on this iptables line is the IP network that we want to masquerade. You'll note in our case (and this will be true in most cases) that we designated one of the private networks, 192.168.50.0/24. You can masquerade your public network, too, but the private network is more common these days. This will also make sure that no one can use you to masquerade behind from anywhere other than 192.168.50.0/24.
Finally, we tell iptables to MASQUERADE. Please note that the capitalized words are important and must be all caps, just as shown.
Now let's assume that we have a public, static IP assigned. In this case, we'll use snat:
-
IP is static and equal to 209.127.112.6.
-
The Class C network to hide is 192.168.50.0/24.
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 209.127.112.6
This is the simplest form of performing snat. For example, you can make the target more specific by specifying a protocol in the rule and then adding a port number to the source address.
But perhaps the most useful feature available to snat over masquerading is its capability to be applied over a range of IPs. Let's say that you were assigned the address range 209.127.112.1 to 209.127.112.6. You're using 209.127.112.1 as your external router (CSU/DSU) that connects via Frame Relay back to your ISP, and you want to use all the other IPs on the firewall. You can do this easily this way:
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 209.127.112.2-209.127.112.
Now iptables will map the outgoing connections to any of 209.127.112..2 to 209.127.112.6 based on the least used IP first, providing primitive load balancing.
If you can use snat, you can also use dnat. Unlike the snat target, the dnat target is a PREROUTING chain target. This demands the use of the -i option for the input interface. Let's assume that we have the following setup: static IPs 209.127.112.2 to 209.127.112.6 on eth0, with no services running on this host.
You want to accomplish the following:
-
Map all incoming connections to port 80 (http) on any of 209.127.112.2 to 209.127.112.3 to any of 192.168.50.20 to 192.168.50.25.
-
Map all incoming DNS connections (UDP or TCP) on 209.127.112.2 to 192.168.50.12, and from 209.127.112.3 to 192.168.50.13.
-
Map all https (secure http) on any of 209.127.112.2209.127.112.3 to 192.168.50.30.
-
Map all sendmail connections to 209.127.112.5 to 192.168.50.50.
Let's start with the last rule first, since it's easiest:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25 -d 209.127.112.5 -j DNAT --to 192.168.50.50:25
Previously, you mapped any incoming packets on eth0, protocol TCP, destination port 25, destination address 209.127.112.5 to the host 192.168.50.50 on port 25. Note that you could use smtp in place of the port number 25, but that requires a lookup. It is easier and safer to use IPs and port numbers than hostnames and port names.
Rule 3 is also simpleit's most easily done as two rules, one for each destination address:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -d 209.127.112.2 -j DNAT --to 192.168.50.30:443 iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -d 209.127.112.3 -j DNAT --to 192.168.50.30:443
Why use two rules? One can easily be dropped just by changing the -A to a -D (delete).
Rule 2 is a little more complex and requires some thought. It can easily be specified by using four rules, one for each of the 1:1 IP mappings for UDP and one for TCP. But we can drop this to just two rules by being a little creative. The four options for protocols are: TCP, UDP, ICMP, and ALL. Because ICMP doesn't use port numbers, we don't want ALL. But if we simply say not ICMP (! ICMP), we can cover both TCP and UDP in one rule:
iptables -t nat -A POSTROUTING -i eth0 -p ! ICMP --dport 53 -d 209.127.112.2 -j DNAT --to 192.168.50.12:53 iptables -t nat -A POSTROUTING -i eth0 -p ! ICMP --dport 53 -d 209.127.112.3 -j DNAT --to 192.168.50.13:53
That handles DNS.
Rule 1 is the most complex. We'll do this similar to what we did previously, but we'll spread the connections over six identical Web servers:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -d 209.127.112.2 -j DNAT --to 192.168.50.20-192.168.50.25:80 iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -d 209.127.112.3 -j DNAT --to 192.168.50.20-192.168.50.25:80
That about does it. There's a lot more you can do with the NAT table, but this will give you a good idea of how to start. Also remember that to list these rules, we need to specify the NAT table:
iptables -t nat -L -n
Until next time .