Concepts / Address translation

Address translation

NAT

Also called network address translation, masquerade, source NAT, SNAT

A router rewriting addresses as packets pass, usually to hide many private devices behind one address.

Outbound, the router replaces the private source with its own address and remembers the mapping; replies are translated back. Nothing outside can start a connection in, unless a port forward says where it should go. Servers behind NAT see the router's address, not the device's.

How NAT works, step by step

A home network uses a private range (RFC 1918: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). Those addresses mean nothing on the internet, and no router out there will carry a reply back to them. The home router has one public address, and NAT (RFC 3022) lets every device share it. Follow one web request from a laptop at 10.0.1.11 to a server at 10.0.2.10, through a router whose outside address is 10.0.2.2:

  1. The laptop sends 10.0.1.11:48210 → 10.0.2.10:80, a TCP SYN. It knows nothing about NAT.
  2. The router routes it, then, as it leaves by the outside card, rewrites the source to its own address: 10.0.2.2:48210 → 10.0.2.10:80. It fixes the IP and TCP checksums to match.
  3. It records the mapping in its connection table: this inside address and port, that outside address and port, this server. If another device inside already uses port 48210 to the same server, the router picks a different outside port. That is why home NAT is also called PAT or NAT overload: ports, not addresses, tell the devices apart.
  4. The server replies to 10.0.2.2:48210. It never sees the laptop's address.
  5. The router looks the reply up, finds the mapping, rewrites the destination back to 10.0.1.11:48210 and delivers it inside.

A packet that arrives from outside and matches no mapping has nowhere to go, so the router drops it. That is why nothing outside can start a connection in, unless a port forward (destination NAT) says in advance where a port should go.

What it looks like on a Linux machine

On a Linux router NAT is two iptables rules in the nat table. Source NAT happens in POSTROUTING, after the routing decision; destination NAT, for a port forward, in PREROUTING, before it:

iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 2222 -j DNAT --to-destination 10.0.1.10:22

MASQUERADE uses whatever address the outside card has, which suits a line whose address changes; SNAT --to-source names a fixed one. The mappings live in the kernel's connection tracking, and conntrack -L lists them. Each entry shows the packet as the laptop sent it, then the reply as the router expects it:

$ conntrack -L -p tcp -s 10.0.1.11
tcp      6 117 TIME_WAIT src=10.0.1.11 dst=10.0.2.10 sport=48210 dport=80 src=10.0.2.10 dst=10.0.2.2 sport=80 dport=48210 [ASSURED] mark=0 use=1

The second half is where the translation shows: the server answers 10.0.2.2, not 10.0.1.11. In the port forwarding and NAT lab an outsider reaches a NAS's SSH through the router's port 2222, and its log records the outsider's real address: a forward rewrites the destination, never the source. The static NAT, pool and overload lab shows one-to-one NAT and address pools.

What goes wrong, and how you see it

A forward that does nothing. The DNAT rule rewrites the destination, but the firewall's FORWARD chain still decides. With no rule allowing it, the packet is rewritten and then dropped, and the client just times out. The lab leaves one forward blocked on purpose to show the two are separate.

A server that answers by another way. If the inside server's default route does not point back at the NAT router, replies leave untranslated and the client ignores them.

Protocols that carry addresses inside. Active FTP sends the client's private address in the payload, and SIP does the same for media. The server connects back to an address that does not exist. Helpers or passive mode fix it; the FTP lab shows both.

Two devices behind two NATs that want to talk. Neither can reach in. Peer-to-peer apps punch holes with STUN, as in the NAT traversal lab.

Idle connections that die. A mapping lives only as long as its timer: Linux keeps an unanswered UDP flow for 30 seconds. Long-idle connections need keepalives.

Questions people ask

Is NAT a firewall? No, though it blocks unsolicited inbound traffic as a side effect. The protection comes from the state table, and a real firewall gives the same protection with rules you can read.

What is the difference between SNAT, DNAT and PAT? SNAT rewrites the source on the way out; DNAT rewrites the destination on the way in (a port forward); PAT is SNAT that also rewrites ports, so many devices share one address.

Does IPv6 need NAT? Not for lack of addresses: every device can have a global one. A stateful firewall still blocks inbound connections, which is the part of NAT people actually relied on.

See it on real machines

Learn it on real machines.

Every lab is a small network of real Linux machines in your browser. Start with a free account: Google or email, no card.

Start this lab, free