NAT and PAT Explained
NAT (Network Address Translation) is the workaround that kept IPv4 alive long after we ran out of addresses. Every home router does it. Every cloud VPC does it. It is also the source of half of all networking confusion. Let’s clear it up.
What NAT does
NAT rewrites IP addresses (and usually ports) in packets as they pass through a router.
From your laptop's view:
192.168.1.42:54321 → cloudflare.com:443
What cloudflare.com sees:
198.51.100.5:60000 → cloudflare.com:443
Cloudflare's reply:
cloudflare.com:443 → 198.51.100.5:60000
What your router translates back to:
cloudflare.com:443 → 192.168.1.42:54321
Your router maintains a NAT table mapping (private IP, port) ↔ (public IP, port).
The two main NAT types
Source NAT (SNAT) — the default for outbound
Rewrites the SOURCE address as packets leave your network. This is what your home router does to let you reach the internet.
Destination NAT (DNAT) — for inbound
Rewrites the DESTINATION address. Used for “port forwarding” — e.g. forwarding public_ip:8080 to a server at 192.168.1.50:80 inside your network.
PAT (Port Address Translation) — the trick that scales NAT
PAT (also called NAPT or “NAT overload”) lets MANY private IPs share ONE public IP by using different source ports.
NAT table on your home router:
192.168.1.42:54321 ↔ 198.51.100.5:60000 (your laptop)
192.168.1.43:54321 ↔ 198.51.100.5:60001 (your phone)
192.168.1.44:54321 ↔ 198.51.100.5:60002 (your tablet)
All three reach cloudflare.com from the SAME public IP,
distinguished by port.
Theoretical limit: 65,000 simultaneous connections per public IP per destination. In practice, much less due to port reuse and timeouts.
The downside of NAT
- Inbound connections are blocked by default. Your laptop can connect out, but the internet can’t connect IN unless you set up port forwarding.
- Breaks end-to-end principle — peer-to-peer apps (VoIP, gaming, BitTorrent) need workarounds (STUN, TURN, hole punching).
- Some protocols don’t NAT well — FTP, SIP, anything embedding IP addresses in the payload requires special “NAT helpers” (ALGs).
Carrier-Grade NAT (CGNAT)
Some ISPs are out of public IPs, so they put YOU behind their own NAT. You think you have a “public” IP but it’s actually in 100.64.0.0/10 (CGNAT range), shared with hundreds of other customers.
How to tell: curl ifconfig.me shows a 100.64.x.x address, OR your “public” IP changes randomly, OR you can’t host any inbound services even with port forwarding.
Configuring NAT on Linux
Modern (nftables):
# Enable IP forwarding
sudo sysctl -w net.ipv4.ip_forward=1
# SNAT: outbound traffic from 192.168.1.0/24 gets rewritten
sudo nft add table ip nat
sudo nft add chain ip nat postrouting '{ type nat hook postrouting priority 100 ; }'
sudo nft add rule ip nat postrouting ip saddr 192.168.1.0/24 oifname "eth0" masquerade
Legacy (iptables):
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
Port forwarding (DNAT — make port 8080 on public IP route to internal 192.168.1.50:80):
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to 192.168.1.50:80
The IPv6 way: no NAT
IPv6 has so many addresses (2^128) that every device gets a real, routable global IP. NAT is unnecessary. The end-to-end principle is restored. Many engineers consider this a feature, others find the security implications scary.
What to learn next
TCP — the reliable connection protocol that powers HTTP, SSH, email, and most internet traffic. Up next on the roadmap.