NAT (NAT)
Your home network might have 20 devices, but your ISP gives you only one public IP address. NAT is what lets all those devices share that single address. When your laptop sends a request to a website, your router swaps the laptop’s private address for the public one, remembers which device made the request, and routes the response back to the right device. It is the reason 192.168.x.x addresses work on your home network but are invisible to the outside world.
Network Address Translation (NAT), defined in RFC 3022, modifies IP address information in packet headers as they pass through a routing device, enabling multiple hosts on a private network (RFC 1918 addresses) to access external networks using fewer public IP addresses.
NAT types:
- SNAT (Source NAT) / PAT (Port Address Translation): the most common form. Many private IPs are translated to a single public IP by also translating source port numbers. The NAT table maps each internal IP:port to a unique external port on the public IP. Also called “NAT overload” or “masquerade” in Linux.
- DNAT (Destination NAT) / Port Forwarding: external traffic arriving on a specific port is redirected to an internal host. Used to expose servers (web, game, SSH) behind NAT.
- Static NAT: one-to-one mapping of a private IP to a public IP. Used for servers that need a consistent external address.
- Carrier-grade NAT (CGNAT): ISPs apply a second layer of NAT (RFC 6598, 100.64.0.0/10) to conserve IPv4 addresses. Creates a “double NAT” scenario.
NAT traversal challenges:
- Breaks end-to-end connectivity (external hosts cannot initiate connections to NATted devices without port forwarding)
- Complicates protocols that embed IP addresses in payloads (SIP, FTP active mode)
- Workarounds: STUN, TURN, ICE (used by WebRTC), UPnP, NAT-PMP
IPv6 was designed to eliminate the need for NAT by providing a vast address space (128-bit addresses), but NAT remains ubiquitous in IPv4 networks.
NAT configuration (Linux iptables)
# Enable IP forwarding
$ echo 1 > /proc/sys/net/ipv4/ip_forward
# Source NAT (masquerade): all outbound traffic from 192.168.1.0/24
# uses the public IP of eth0
$ sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 \
-o eth0 -j MASQUERADE
# Port forwarding (DNAT): forward external port 8080 to internal web server
$ sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 \
-j DNAT --to-destination 192.168.1.50:80
# View active NAT table (conntrack)
$ sudo conntrack -L -n | head -5
tcp 6 300 ESTABLISHED src=192.168.1.10 dst=93.184.216.34 \
sport=54312 dport=443 src=93.184.216.34 dst=203.0.113.1 \
sport=443 dport=54312 [ASSURED] NAT is running on every home router and most enterprise edge devices. When you check “What is my IP?” from different devices on the same network and see the same address, that is NAT. In cloud environments, NAT gateways (AWS NAT Gateway, Azure NAT Gateway) allow instances in private subnets to reach the internet for updates and API calls without being directly accessible. Docker uses NAT to map container ports to host ports (-p 8080:80). NAT is also a basic security layer: since external hosts cannot initiate connections to private addresses without explicit port forwarding, it acts as an implicit firewall. The main pain point is double NAT (ISP CGNAT + your router NAT), which breaks port forwarding, VPN connections, and peer-to-peer applications.