Classroom Glossary Public page

NET-201 Week 8 -- NAT and IPv6 Transition: Dual-Stack, 6to4, and NAT64

1,486 words

"IPv4 addresses ran out. Literally ran out. IANA allocated the last /8 block to APNIC on 3 February 2011. We have been living in a managed scarcity ever since, and IPv6 deployment is the only long-term exit." -- Geoff Huston, APNIC Chief Scientist, BGP in 2022 (blog, 2023)


Lecture (50 min)

8.1 Why NAT Exists: IPv4 Exhaustion

The IPv4 address space is 32 bits: 2^32 = 4,294,967,296 addresses. The Internet has far more than 4 billion connected devices. The gap is filled by NAT (Network Address Translation), which allows many devices behind a single public IP address to communicate with the Internet.

NAT was originally described as a temporary measure. It has been the dominant Internet access architecture for over 20 years.

How NAT works (NAPT / PAT):

The router maintains a NAT translation table mapping (private_IP, private_port) -> (public_IP, public_port). When an internal host (192.168.1.10:52000) opens a connection to an external server (93.184.216.34:80):

  1. Router rewrites the source (192.168.1.10:52000) to (203.0.113.1:60001) [public IP, assigned port]
  2. External server responds to (203.0.113.1:60001)
  3. Router reverse-translates back to (192.168.1.10:52000) and delivers to the internal host

The external server never sees the internal private IP; it sees only the router's public IP.

Private address ranges (RFC 1918):

  • 10.0.0.0/8 (Class A private; single organization)
  • 172.16.0.0/12 (172.16.0.0 - 172.31.255.255; corporate use)
  • 192.168.0.0/16 (home networks; the most visible range)

NAT problems:

  • Breaks end-to-end connectivity: external hosts cannot initiate connections to internal hosts (no inbound mapping exists by default)
  • Complicates protocols that embed IP addresses in payloads (FTP, SIP, some VPN protocols require NAT traversal / ALG)
  • Adds state on the router; overloaded NAT tables cause packet drops
  • Creates troubleshooting complexity; NAT is invisible to traceroute

8.2 IPv6 Overview

IPv6 (RFC 2460 / RFC 8200) was standardized in 1998 to provide a virtually unlimited address space: 128-bit addresses = 2^128 = ~3.4 × 10^38 addresses.

IPv6 address notation: eight groups of four hexadecimal digits, colon-separated. Leading zeros in a group may be omitted; the longest run of consecutive all-zero groups may be replaced by :: (once per address).

Full:        2001:0db8:0000:0000:0000:0000:0000:0001
Compressed:  2001:db8::1

Common IPv6 address types:

  • Global unicast: 2000::/3 (routable on the Internet; equivalent to public IPv4)
  • Link-local: FE80::/10 (non-routable; auto-configured on every interface; used for neighbor discovery)
  • Loopback: ::1/128 (equivalent to 127.0.0.1)
  • Multicast: FF00::/8 (replaces IPv4 broadcast for most purposes)
  • ULA: FC00::/7 (unique local addresses; private, not routable on Internet; equivalent to RFC 1918)

NDP (Neighbor Discovery Protocol, RFC 4861): replaces ARP in IPv6. Uses ICMPv6 multicast messages (Neighbor Solicitation and Neighbor Advertisement) to resolve IPv6 addresses to MAC addresses. NDP also handles router discovery and prefix advertisement (SLAAC).

SLAAC (Stateless Address Autoconfiguration): a host receives an RA (Router Advertisement) from the default gateway containing the /64 prefix. It constructs its own address by appending its interface identifier (derived from the MAC address via EUI-64, or a random value). No DHCPv6 required.

8.3 IPv6 Transition Mechanisms

The Internet does not flip from IPv4 to IPv6 overnight. Transition requires mechanisms that allow IPv4 and IPv6 to coexist.

Dual-stack: the simplest approach. Every host and router runs both IPv4 and IPv6 simultaneously. Connections to IPv6-capable destinations use IPv6; others fall back to IPv4. Requires both addresses allocated on every interface. Most modern OSes and major Internet destinations are dual-stack.

# Verify dual-stack on Linux
ip -4 addr show     # IPv4 addresses
ip -6 addr show     # IPv6 addresses

# Test dual-stack preference (IPv6 preferred when available)
curl -v --ipv6 https://google.com   # force IPv6
curl -v --ipv4 https://google.com   # force IPv4

6to4 (RFC 3056): encapsulates IPv6 packets inside IPv4 packets for traversal across IPv4-only networks. A 6to4 address is automatically constructed from the host's public IPv4 address: 2002:IPv4_hex::/48. The anycast relay 192.88.99.1 (6to4 relay) decapsulates packets at the IPv6 internet boundary.

6to4 is largely deprecated: the anycast relay model caused reliability problems, latency is unpredictable, and the mechanism is obsolete now that most providers offer native dual-stack.

Teredo (RFC 4380): encapsulates IPv6 in UDP, allowing IPv6 connectivity even through NAT devices. Used primarily for Windows hosts behind NAT without native IPv6. Also largely deprecated in modern deployments.

6rd (IPv6 Rapid Deployment, RFC 5569): operator-managed evolution of 6to4; uses the ISP's own IPv6 prefix and dedicated relay servers. More predictable than 6to4; deployed by some ISPs as an interim mechanism before native IPv6.

8.4 NAT64 and DNS64

NAT64 (RFC 6146) allows IPv6-only clients to reach IPv4-only servers. It is the most important transition mechanism for the post-IPv4 world: a mobile network or enterprise that has deployed IPv6-only internally can still reach legacy IPv4 services.

NAT64 flow:

  1. IPv6-only client wants to reach an IPv4-only server (93.184.216.34)
  2. DNS64 resolver synthesizes an AAAA record: 64:ff9b::93.184.216.34 (embedding the IPv4 address in a well-known /96 prefix)
  3. Client sends an IPv6 packet to 64:ff9b::93.184.216.34
  4. NAT64 gateway intercepts the packet, translates to IPv4 93.184.216.34, forwards to Internet
  5. Response arrives at NAT64 gateway; translated back to IPv6; delivered to client

The client never knows it is talking to an IPv4 server.

DNS64 configuration (BIND 9):

# In named.conf options or zone configuration
options {
    dns64 64:ff9b::/96 {
        clients { any; };
        exclude { 64:ff9b::/96; };
    };
};

DNS64 intercepts A-record-only responses and synthesizes AAAA records in the 64:ff9b::/96 prefix. Only applied to clients that have no IPv4 connectivity.

Important limitation: NAT64/DNS64 does not work with DNSSEC validation of synthesized AAAA records (the synthetic AAAA has no RRSIG; it is generated on the fly). DNSSEC validation must be selectively disabled for synthesized records or handled with DO-bit awareness.

8.5 Happy Eyeballs (RFC 8305)

Happy Eyeballs is the client-side algorithm that makes dual-stack connections feel fast. Without it, a client that prefers IPv6 but encounters a broken IPv6 path would wait for an IPv6 connection timeout (~75 seconds) before falling back to IPv4 -- a terrible user experience.

Happy Eyeballs: when connecting to a hostname with both A and AAAA records, race IPv6 and IPv4 connections with a ~250ms head start for IPv6. Whichever connects first wins. The second connection is abandoned. If IPv6 loses consistently, the client reduces its IPv6 preference delay adaptively.

Modern browsers (Chrome, Firefox), curl, and most HTTP clients implement Happy Eyeballs by default.


Lab Preview

Lab 6 builds a dual-stack + NAT64 topology in Containerlab:

  • Configure a Containerlab topology with an IPv4-only "Internet" segment and an IPv6-only "client" segment
  • Install tayga (a NAT64 daemon) and BIND 9 with DNS64 on the gateway node
  • From an IPv6-only container, ping and curl an IPv4-only server via the NAT64 gateway
  • Capture the NAT64 translation in Wireshark (observe the IPv6 destination being 64:ff9b::x.x.x.x and the translated IPv4 packet on the other side)
  • Configure dual-stack on a third container; verify Happy Eyeballs behavior with curl -v

Homework

Reading (45 min): Kurose-Ross 9e Ch 4.3.4 (NAT: Network Address Translation) and Ch 4.4 (IPv6). Focus on the NAPT translation table mechanics, the IPv6 address format, and the dual-stack/tunneling transition motivation.

Hands-on (60 min): On your lab machine (or a virtual machine with no IPv6 configured), configure a basic NAT64 simulation:

# Install tayga (stateless NAT64 daemon)
sudo apt install -y tayga iproute2

# Configure /etc/tayga.conf:
# prefix 64:ff9b::/96
# tun-device nat64
# ipv4-addr 192.168.255.1
# dynamic-pool 192.168.255.0/24

# Enable IPv6 forwarding
sudo sysctl -w net.ipv6.conf.all.forwarding=1

# Start tayga
sudo tayga --mktun
sudo ip link set nat64 up
sudo tayga

Test by pinging an IPv4 address via its 64:ff9b:: representation. Document the address translation observed in a Wireshark capture.


Toolchain Diary Entry

Deepen this week: IPv6 tools; NAT diagnostics

ip -6 addr show: display all IPv6 addresses on all interfaces.

ip -6 route show: IPv6 routing table.

ping6 ::1: verify IPv6 loopback; ping6 fe80::1%eth0 for link-local (interface scope required).

traceroute6 2606:4700::6810:84e5: IPv6 traceroute to a host (e.g., Cloudflare).

rdisc6 eth0: receive and display Router Advertisements on eth0; shows prefix being advertised for SLAAC.

ndptool monitor -t NA -t NS: monitor NDP (Neighbor Advertisement/Solicitation) on the local link.

conntrack -L: display the NAT (conntrack) table on a Linux NAT gateway; shows active translations.

tayga --mktun: create the NAT64 tunnel interface managed by tayga.

ip6tables -t nat -L -n -v: display IPv6 NAT rules (NAT64 gateway firewall rules).


Key Terms

  • NAT / NAPT: Network Address Translation / Network Address and Port Translation; maps private (RFC 1918) IP+port pairs to a public IP+port; hides internal topology from the Internet
  • RFC 1918: IP address ranges reserved for private use: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16; not globally routable; used behind NAT
  • SLAAC: Stateless Address Autoconfiguration; IPv6 hosts generate their own global address from the /64 prefix advertised by the router; no DHCPv6 required
  • NDP: Neighbor Discovery Protocol (RFC 4861); IPv6 replacement for ARP; uses ICMPv6 Neighbor Solicitation/Advertisement to resolve addresses; also handles router discovery and prefix delegation
  • Dual-stack: simultaneous IPv4 and IPv6 on every interface and routing path; the preferred transition approach; requires both address families allocated at every node
  • 6to4: IPv6-in-IPv4 tunneling (RFC 3056); uses anycast relay; deprecated in favor of native dual-stack
  • NAT64 (RFC 6146): translates IPv6 packets to IPv4 at a gateway; allows IPv6-only clients to reach IPv4-only services; requires DNS64 for address synthesis
  • DNS64: synthesizes AAAA records from A records using the 64:ff9b::/96 prefix; works with NAT64 to make IPv4 services reachable from IPv6-only clients
  • Happy Eyeballs (RFC 8305): client-side dual-stack connection racing algorithm; starts both IPv6 and IPv4 connections with a 250ms IPv6 head start; uses whichever connects first; eliminates IPv6 fallback latency