Rack of Ethernet switches.

How NAT Works

NAT is Network Address Translation

You can very effectively protect your network from active attack with Network Address Translation or NAT. You assign your internal addresses from one or more of the reserved blocks defined in RFC 1918 — 10/8, 172.16/12, and 192.168/16. Those represent 16,277,216, 1,048,576, and 65,536 possible IPv4 addresses, respectively.

You then configure one or more border routers to do what's called IP masquerading, each hiding all the internal addresses behind one or more external IP addresses used by the exterior port of the router.

You can make all the connections you want from inside to out, but there is no way for a host on the outside to establish a connection to one of your inside hosts as those address blocks aren't routable out on the Internet. (Unless, of course, you go out of your way to set up static port forwarding, where some combination of IP address and TCP or UDP port on the exterior side of the NAT router is always mapped to some IP address and TCP or UDP port on the interior server.)

How can you get away with telling lies?

  1. Make certain that your lie is somewhat plausible.
  2. Above all, make certain that you are consistent in your lying.

Network Address Translation (or IP masquerading) is a form of lying. It's something that firewalls, or routers in general, can do with the IP addresses in headers of packets they forward. The result is that details of the interior network are hidden, because the device doing NAT is effectively lying, masquerading as though it simultaneously was all of the hosts inside the networks it is hiding. To distant servers, your entire organization looks like one extremely busy host.

Using a NAT Firewall

Using a NAT firewall: your PC, modem, your ISP, and the Internet.

Let's say that you have a cable modem or a DSL interface, and you just connect your computer to the Internet. This is dangerous if you're using Windows, but a lot of people do this. Your connection to the world might look something like this picture, where modem is your cable modem or DSL interface:

Well, that's how you see it from your house. Using my connection as an example, the reality is a bit more detailed. For an explanation of IP addresses, the slash notation, CIDR blocks and more, see my TCP/IP page.

Using a NAT firewall: your PC, modem, your ISP, and the Internet.

Now, if you find your PC's IP addressing, using the commands described on my page of TCP/IP commands, we can update the diagram:

Using a NAT firewall: your PC, modem, your ISP, and the Internet.

It is just one hop from my host to my default gateway, which means, in network-speak, that we're adjacent. Verify this with the following command, changing the IP address to that of your default gateway:
Or, if you're stuck using Windows:
The important thing is that the modem isn't there in terms of IP addresses. While it does crucial things with signals, it isn't really part of the networking topology as far as networks and routing are concerned.

D-Link TM-G5240 WLAN 802.11g wireless router, Cisco EZXS88W Ethernet switch, MFJ-1278 multi-mode data controller.

D-Link TM-G5240 802.11g wireless router, Cisco EZXS88W 8-port Ethernet switch, and MFJ-1278 multi-mode data controller. Small Internet access routers like this D-Link unit implement NAT.

Now you go to the store and buy one of those "SOHO" (Small Office / Home Office) router/firewall boxes. They only cost about US$ 20-40. What's in it? Quite a bit, actually. A typical router box really contains all this:

Using a NAT firewall: the interior of the cable/DSL router/firewall.

On its exterior port, the firewall is a DHCP client, and acts just like your PC did to get an IP connection to the world.

Internally, the firewall does NAT and applies stateful packet filtering rules.

On its interior side, the firewall is a DHCP server for a private IP address space used inside your organization. RFC 1918 specifies a set of private blocks of IP addresses.

Class CIDR Block IP Address Range
A -
B -
C -

So you plug your NAT firewall into where your PC used to go, and your PC into one of the firewall's Ethernet jacks. And other computers, and/or other Ethernet switches, into the other ports. So now you have something like the below:

Using a NAT firewall: internal Ethernet switches, the interior of the cable/DSL router/firewall, ISP, and Internet backbone.


You could have up to 16,777,214 hosts on your internal network, if you used the IP network. But you only need one external IP address.
224 = 16,777,216
Minus two unusable addresses, hostid all 0's or all 1's:
224 - 2 = 16,777,214

No one outside can tell anything about your internal topology. You could have lots of routers and networks inside. From the outside it appears that you have only one very busy host, the exterior port of the NAT firewall.

Your internal addresses are not routable. The reserved RFC 1918 addresses are not routable. If an attacker managed to figure out your internal IP address, his packets would not go toward you but toward the core of the Internet. They would eventually hit a core router, one of the routers on the backbone. The core routers have no default routes, they have to know where everything is. And they don't have routes for 10/8, 172.16/12, or 192.168/16 — those networks effectively do not exist according to the routing tables of the public Internet.

So what about that "telling lies" analogy?

The NAT device is lying about the internal network. It pretends that the internet network doesn't exist, and that the firewall is really everything you have inside. And remember:

How can I do this for free with a Linux machine?

Run a shell script like the following at boot time to enable NAT. Make sure you get this right, it really matters where you use regular quote characters (ASCII 0x27, typically just to the left of the <Enter> key, at least on US keyboards) and where you use back-quote characters (ASCII 0x60, typically somewhere in the upper left region of the keyboard, at least on US keyboards). Also parenthesis (ASCII 0x28/0x29) versus curly braces (ASCII 0x7b/0x7d).

# Turn on IP forwarding (routing)
echo '1' > /proc/sys/net/ipv4/ip_forward
# Figure out what the external IP address is.
# This assumes that eth0 is the external port.
EXT_IPADDR=$( ifconfig eth0 | grep 'inet addr' | cut -d : -f 2 | awk '{print $1}' )
# Turn on NAT
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source ${EXT_IPADDR}

The kernel maintains the "NAT table", the list of currently masqueraded connections. Put another way, it keeps track of the lies it's telling and keeps them consistent. You can view the NAT table by displaying a kernel data structure, or just see how many connections are currently being masqueraded by counting its lines:

wc -l /proc/net/ip_conntrack
more /proc/net/ip_conntrack

At the SIGGRAPH Conference in Los Angeles in 2005, we used one Linux host with a 3 GHz CPU to do address translation for the entire conference site.

The Linux machine was handling over 9500 simultaneous network connections and its CPU was still something over 99% idle.

We did this because a $15,000 Cisco router did not have the needed performance. Cisco routers are extremely good at routing, which can be done in hardware. NAT takes processing, and routers traditionally have not had very powerful CPUs. The last I heard, the Los Angeles Conference Center was looking into Linux. And, Cisco has moved away from slower Motorola CPUs to IA64 systems, basically PC motherboards.

Linux firewall running NAT at the Los Angeles Conference Center.

Linux machine running NAT at the Los Angeles Conference Center. Overworked Cisco routers in the background could not handle the load.