Starphix
Network Engineering / Sources
The Lab / Sources / Network Engineering / Network-Services/NAT-And-PAT.md

NAT and PAT

Network Address Translation rewrote the internet's addressing model as a workaround for IPv4 exhaustion. It is everywhere, it is invisible when it works, and it breaks a specific set of protocols that expect end-to-end addressing.

The three flavours

Type What changes Typical use
Static NAT (1:1) One private IP ↔ one public IP Publishing an internal server
Dynamic NAT (pool) Private IP ↔ any free public IP from a pool Legacy outbound with a block of addresses
PAT / NAT overload (many:1) Private IP:port ↔ public IP:unique port Every home router and most corporate egress

PAT is what almost everyone means by "NAT": thousands of internal hosts share one public address, distinguished by source port.

Client 192.168.1.20:51234  →  203.0.113.5:41200  →  Server 198.51.100.10:443

The router keeps a translation table mapping the tuple back for the return packet. That table is state, so NAT is a stateful middlebox and inherits every stateful-middlebox problem.

Why it exists, and what it costs

IPv4 has ~4.3 billion addresses. NAT let the world postpone renumbering for thirty years. The bill:

  • No inbound connections without a forwarding rule or a tunnel.
  • No end-to-end addressing, which breaks protocols that embed IPs or ports inside payloads.
  • State exhaustion — every translation holds a table entry and a port.
  • Ambiguity in logs — the server sees the NAT address, not the client, unless something forwards the original.

Protocols that break, and why

Protocol Problem Workaround
FTP (active) Server connects back to a port the client did not open Passive mode, or an ALG
SIP / H.264 Addresses embedded in the payload ALG, STUN, TURN, ICE
IPsec ESP No ports to translate NAT-T (UDP 4500 encapsulation)
ICMP No ports; identifier is translated instead Handled by most NATs, not all
DNS A records pointing at private IPs leak out Split-horizon DNS, not NAT
Peer-to-peer / WebRTC Direct connection impossible STUN/TURN relay

ALGs (application layer gateways) try to fix this by rewriting payloads. They are the reason "NAT works except for that one application", and they are frequently the bug rather than the fix.

The table, and what exhaustion looks like

conntrack -L | wc -l
conntrack -S                       # insert_failed, drop counters
sysctl net.netfilter.nf_conntrack_max
cat /proc/sys/net/netfilter/nf_conntrack_count

Symptoms of a full table: new connections fail while established ones work, insert_failed climbs, and the failure looks random by client. Common in offices where everyone opens a video call at 9am.

Fixes in order: raise the limit (buys time), reduce connection churn (pooling, keep-alive), add more public IPs (more tuples), or move to IPv6.

Hairpinning and the internal-then-external problem

A client inside the network resolves api.example.com to the public IP and tries to connect. The packet goes to the router, which must translate it back inside — NAT hairpin / loopback. Many routers do not support it by default, so internal clients cannot reach an internal service via its public name while external clients can. The usual fixes:

  1. Split-horizon DNS returning the private address internally.
  2. Explicit hairpin/NAT-loopback configuration.
  3. Route internal clients to the internal load balancer directly.

This is one of the most common "it works from home but not from the office" causes, and it is a DNS problem wearing a NAT costume.

IPv6 and the end of NAT (mostly)

IPv6 restores end-to-end addressing, so NAT is not required. What remains is a stateful firewall with the same job as NAT's side effect, and NAT66 exists for multihoming but is discouraged. The practical translation of skills: what you learned as "port forwarding" becomes "firewall policy", and what you learned as "no inbound" becomes "default deny inbound, which you configured deliberately".

Where it goes wrong

  • Port forward to the wrong internal IP after a DHCP lease changed. The fix is a static reservation, not a new rule.
  • Overlapping private ranges across a VPN: both sides use 192.168.1.0/24, so half the destinations are ambiguous. Renumber one side; there is no clean NAT fix.
  • Assuming the server logs the client IP. Behind NAT it does not; you need X-Forwarded-For set by a proxy you trust, or PROXY protocol.
  • Hairpin missing, as above.
  • ALG disabled to fix one application and enabled to fix another, on the same gateway.
  • Conntrack full during a traffic spike, misdiagnosed as an application bug.
  • NAT on the firewall and NAT on the router, each translating, producing a double-NAT that is invisible in the config of either device alone.

From the Network Engineering research vault · CC BY 4.0 · all notes · raw markdown