NAT (Network Address Translation)

intermediate nat ipv4 private-ip port-forwarding networking

NAT (Network Address Translation) lets many devices on a private network share a single public IP address. Our home router does this for every device behind it — laptop, phone, smart fridge, all sharing one public IP.

In simple language: NAT rewrites the source IP and port on outgoing packets and remembers the mapping so it can rewrite replies on the way back.

Why NAT Exists

IPv4 has only ~4.3 billion addresses, and we long since blew past that. Without NAT, every connected device would need its own public IP. NAT lets ISPs hand out one public IP per home and serve everyone behind it.

  • IPv4 address conservation (the main reason).
  • A side effect: hosts inside aren’t directly reachable from outside without explicit forwarding — accidental firewalling.

How It Rewrites

Say my laptop (192.168.1.42:51234) connects to 93.184.216.34:443.

Outgoing from laptop:
  src=192.168.1.42:51234   dst=93.184.216.34:443

Router rewrites and stores in NAT table:
  src=203.0.113.5:60001    dst=93.184.216.34:443
  (203.0.113.5 = router's public IP, 60001 = router's chosen port)

Reply from server:
  src=93.184.216.34:443    dst=203.0.113.5:60001

Router looks up port 60001 in NAT table -> rewrites:
  src=93.184.216.34:443    dst=192.168.1.42:51234

Hands packet to laptop. Laptop has no idea translation happened.

The NAT table entry is keyed by (public_port → private_ip:private_port + remote). It expires after a timeout if there’s no traffic.

Types of NAT

  • Static NAT — one private IP maps to one fixed public IP. Like a permanent reservation.
  • Dynamic NAT — pool of public IPs, mapping changes per session.
  • PAT / NAPT (Port Address Translation) — many private IPs share one public IP using different ports to disambiguate. This is what your home router does. Also called NAT overload.

When people say “NAT” today, they almost always mean PAT.

NAT Behavior Types (for P2P)

For peer-to-peer apps (WebRTC, gaming), the type of NAT matters:

  • Full-cone (one-to-one) — once an internal host has a public mapping, anyone can reach it via that mapping. Most permissive.
  • Restricted-cone — same mapping, but only the external host the internal one already contacted can use it.
  • Port-restricted-cone — even stricter: must match both IP and port.
  • Symmetric — a new external destination gets a new public port. Hardest to traverse — STUN often fails, requiring TURN relays.

Symmetric NAT is the bane of P2P apps.

Port Forwarding

A device behind NAT can’t normally accept incoming connections — the router has no mapping yet. Port forwarding is a manual rule: “incoming packets to my public IP on port 22000 → forward to 192.168.1.50:22 (my home server’s SSH).”

Public:  203.0.113.5:22000
            ↓ (port forward rule)
Private: 192.168.1.50:22

Common for self-hosted services, game servers, etc.

Hairpinning (NAT Loopback)

Imagine our home server is at private IP 192.168.1.50 and a port-forward rule exposes it as 203.0.113.5:8080. From inside the LAN, can we reach 203.0.113.5:8080?

If the router supports hairpinning — yes, it’ll loop the request back to the internal host. If not, we have to use the private IP from inside. Older routers often fail at this.

What Breaks With NAT

  • End-to-end principle — outside hosts can’t initiate to inside hosts.
  • Some protocols — FTP active mode, SIP/VoIP, IPsec passthrough can struggle because they embed IP addresses in payloads.
  • Logging / forensics — many users behind one IP makes attribution hard.
  • P2P — needs hole-punching tricks (STUN, ICE, TURN).

Carrier-Grade NAT (CGNAT)

ISPs can run NAT on their side too, sharing one public IP across thousands of customers. We end up double-NATted: home router NAT → ISP NAT → internet. Often shows as a public IP in the 100.64.0.0/10 range (RFC 6598).

This makes self-hosting from home impossible without VPN tunnels or solutions like Cloudflare Tunnel / Tailscale Funnel.

Inspecting NAT

# Linux: see the conntrack table (tracks NAT mappings)
sudo conntrack -L
# tcp 6 ESTABLISHED src=192.168.1.42 dst=93.184.216.34 sport=51234 dport=443 \
#                  src=93.184.216.34 dst=203.0.113.5 sport=443 dport=60001

# Check public IP from inside
curl ifconfig.me

Common Gotcha

NAT is not a firewall, but it acts firewall-ish by accident. Inbound connections to unmapped ports just have nowhere to go. Don’t rely on NAT for security — use a proper firewall.

Interview Tip

Two reasons NAT was invented: (1) IPv4 exhaustion (the real one), (2) simple isolation for private LANs. The trade-off: it breaks end-to-end connectivity, which is why IPv6 enthusiasts want NAT to die.