Part XIX - NAT

19. NAT Internals

NAT behavior, NAPT state, Linux conntrack, hairpinning, CGNAT, NAT64, and NPTv6 from packet rewrite to operations.

1. 19.1 - The Four NAT Types

NAT devices differ in two separate behaviors: how they create external mappings and which outside sources they allow back through an existing mapping. The old STUN vocabulary names four common combinations: full cone, address-restricted cone, port-restricted cone, and symmetric NAT.

TypeMapping behaviorFiltering behaviorP2P impact
Full coneSame external port for all destinationsAny source may send backEasy to traverse
Address-restrictedSame external portSource IP must match a contacted peerUsually workable
Port-restrictedSame external portSource IP and source port must matchNeeds simultaneous punching
SymmetricNew external port per destination tupleSource IP and port must matchOften needs TURN

Minimal C Demo - NAT Type Behavior

NAT Type Behavior — C Demo
stdin (optional)

2. 19.2 - NAPT and Port Translation

NAPT, also called PAT or IP masquerading, lets many private sockets share one public address by rewriting the source port. A normal entry is keyed by protocol plus inside tuple, outside tuple, and translated tuple. ICMP has no transport port, so NAT uses the echo identifier as the demultiplexing key.

  • One public IPv4 address has about 64K TCP ports and 64K UDP ports, before policy and reserved ranges.
  • Real capacity is usually limited first by conntrack memory, hash collisions, timeout policy, and CPU.
  • Deterministic NAT assigns subscribers stable port ranges, reducing per-session logging burden.

Minimal C Demo - NAPT Table Lookup

NAPT Table Lookup — C Demo
stdin (optional)

3. 19.3 - Linux Conntrack

Linux NAT is built on nf_conntrack. Conntrack records both directions of a flow tuple, classifies packets as NEW, ESTABLISHED, RELATED, or INVALID, and gives netfilter enough state to reverse NAT return packets.

DNAT happens in PREROUTING before the route lookup so the kernel routes toward the translated destination. SNAT and MASQUERADE happen in POSTROUTING after routing chooses the outgoing interface.

Sizing is operationally important. A conntrack entry is roughly hundreds of bytes; a million entries can consume hundreds of megabytes, and the bucket count should be sized so lookup does not become the high-PPS bottleneck.

4. 19.4 - NAT Hairpinning

Hairpinning solves the case where an inside client reaches an inside server through the server's public address. The NAT performs destination translation to the inside server and source translation to its inside address, forcing the reply path back through the same NAT state.

5. 19.5 - CGNAT

Carrier-grade NAT places another translation layer in the ISP network. A subscriber may translate from RFC 1918 space to 100.64.0.0/10 at the home router, then the ISP translates that shared address to a public IPv4 address.

CGNAT makes inbound port forwarding difficult, breaks many P2P assumptions, and creates attribution problems because many subscribers share one public IP. Port block allocation and deterministic CGN reduce logging volume by mapping subscribers to stable ranges.

6. 19.6 - NAT64 and DNS64

NAT64 lets IPv6-only clients reach IPv4 servers. DNS64 synthesizes a AAAA answer from an A record, commonly under the well-known prefix 64:ff9b::/96, and the NAT64 gateway translates packets between IPv6 and IPv4 while keeping state for return traffic.

7. 19.7 - NPTv6

NPTv6 is IPv6 prefix translation, not port translation. It swaps one IPv6 prefix for another while preserving a one-to-one address relationship. That makes it stateless and less disruptive than NAPT, but it is still controversial because provider-independent addressing and BGP usually preserve the IPv6 end-to-end model better.

8. Interview Prep

QuestionAnswer checkpoint
Why does symmetric NAT make UDP hole punching hard?The external port changes per destination, so the port learned through signaling is not the port used for the peer.
Where do SNAT and DNAT happen in Linux netfilter?DNAT in PREROUTING before routing; SNAT/MASQUERADE in POSTROUTING after route selection.
How can ICMP be translated by NAPT without ports?Echo request/reply traffic uses the ICMP identifier field as a port-like demux key.
Why does hairpin NAT need source translation too?Without SNAT, the inside server may reply directly to the inside client, bypassing the NAT state and breaking the tuple.
What problem does CGNAT port block allocation solve?It maps subscribers to logged or deterministic public port ranges so attribution does not require logging every session.