NAT64 and 464XLAT: Running an IPv6-Only Network - 夜莺博客

NAT64 and 464XLAT: Running an IPv6-Only Network

Going IPv6-only is the only way to stop running two protocol stacks, two ACL sets and two sets of monitoring rules. The obstacle has never been the IPv6 side - it is the IPv4-only destinations and applications that refuse to die. NAT64 and 464XLAT are the standard answer, and they are more nuanced than "translate everything", because the details decide whether DNSSEC breaks, whether applications using literal IPv4 addresses fail, and whether you can produce useful logs.

The Building Blocks

Component Function Reference
Stateful NAT64 Translates IPv6 packets from IPv6-only hosts to IPv4 servers, sharing IPv4 addresses RFC 6146
Stateless IP/ICMP translation The header translation algorithm itself RFC 7915
Address format Embeds IPv4 addresses in the IPv6 prefix RFC 6052
DNS64 Synthesises AAAA records from A records so clients use IPv6 transport RFC 6147
464XLAT CLAT on the client plus PLAT (= NAT64) in the network, so IPv4 literals also work RFC 6877

The prefix conventions: 64:ff9b::/96 is the well-known prefix, usable on the public internet but restricted to that specific length. A network-specific prefix (NSP) - typically a /96 from your own allocation - gives you routing control and better log correlation, and is what most operators should use.

Why DNS64 Alone Is Not Enough

DNS64 works by rewriting DNS answers. That is exactly the kind of modification DNSSEC was designed to detect. If a validating resolver sees a synthesised AAAA record without a matching signature, the answer is treated as bogus and the lookup fails - which is why the deployment guidance explicitly assumes you must support hosts that validate DNSSEC.

The second gap is IPv4 literals. An application that connects to 192.0.2.10 directly never asks DNS, so DNS64 never helps it. This is the single biggest real-world failure in IPv6-only rollouts, and it is the specific problem 464XLAT solves.

464XLAT: CLAT Plus PLAT

IPv4 app  -->  CLAT (in the device/CE)  -->  IPv6-only access  -->  PLAT (NAT64)  -->  IPv4 internet
             stateless NAT46                                        stateful NAT64

The CLAT is a stateless 1:1 translator that embeds the device's IPv4 address into the IPv6 prefix. Any IPv4 packet, including one addressed by literal, gets encapsulated into IPv6 and handed to the PLAT. With DNS64 present, DNS-capable applications take a single translation instead of two; without it, everything still works but with an extra hop and without AAAA synthesis.

The trade-off is explicit in the guidance: using 464XLAT without DNS64 guarantees DNSSEC is never broken, at the cost of a possible delay from dual A/AAAA lookups unless Happy Eyeballs is present, and without heuristic NAT64 prefix discovery.

Prefix Discovery

Clients need to know the Pref64. Three mechanisms:

# 1. heuristic discovery (RFC 7050) - client queries ipv4only.arpa
dig AAAA ipv4only.arpa @2001:db8::53
# expected: 64:ff9b::192.0.0.170 and 64:ff9b::192.0.0.171 with your NSP

# if you do not run DNS64, you can still answer discovery from your resolver:
# ipv4only.arpa.  AAAA  64:ff9b::192.0.0.170

# 2. DHCPv6 option 108 (PREF64) - RFC 8781, the clean modern way
# 3. Port Control Protocol, RFC 7225

Option 108 is worth preferring where clients support it: it removes the need for a special-purpose DNS name entirely and tells the client the exact prefix and lifetime. Assisting this discovery from your own infrastructure is a small configuration change with a large operational benefit.

Lab Configuration on Linux

Jool is the practical stateful NAT64 implementation.

sudo modprobe jool
sudo jool instance add "nat64" --netfilter --pool6 64:ff9b::/96
sudo jool -i nat64 global update pool6 2001:db8:64::/96

# allow the traffic through netfilter
sudo ip6tables -t mangle -A PREROUTING -j JOOL --instance nat64
sudo sysctl -w net.ipv4.ip_forward=1
sudo sysctl -w net.ipv6.conf.all.forwarding=1

# verify
sudo jool -i nat64 stats display
sudo jool -i nat64 session display

DNS64 on Unbound:

server:
  interface: ::0
  do-ip6: yes
  do-ip4: yes
  module-config: "dns64 validator iterator"
  dns64-prefix: 2001:db8:64::/96
  dns64-synthall: no

Validate before you deploy: query for a name that exists only in IPv4 and confirm the answer embeds the right prefix.

dig A example.com @2001:db8::53
dig AAAA example.com @2001:db8::53
# the AAAA answer must contain 2001:db8:64::<embedded ipv4>

A client-side CLAT for testing:

# clatd (Linux)
sudo apt-get install clatd
sudo tee /etc/clatd.conf <<'EOF'
clat-dev=clat
plat-prefix=2001:db8:64::/96
clat-v4-addr=192.0.0.1
EOF
sudo clatd &
ip addr show clat
ip route show            # default via the clat interface
ping 8.8.8.8            # an IPv4 literal now traverses the CLAT/PLAT path

The Operational Problems Nobody Warns You About

  1. Logging and attribution. One IPv4 address serves many subscribers, and the port range is the only identifier. You must log the IPv4 address, the port range and the timestamp together, and for many jurisdictions retain them. Design the logging before you design the translation.
  2. DNSSEC. Document which resolvers synthesise and which validate, and test that a validating client can still reach signed zones. Some designs deliberately do not synthesise for signed domains, at the cost of those destinations being unreachable.
  3. Protocols that embed addresses. FTP, SIP, some VPN protocols and older games carry IP addresses in the payload. These need application-layer gateways or they need to be declared out of scope. Discovering this after cutover is unpleasant.
  4. MTU. Translation changes header sizes. Path MTU discovery has to work end to end, and ICMPv6 "packet too big" messages must not be filtered. The mechanics are the same as for any tunnelling change and are covered in this IPv6 path MTU discovery guide.
  5. Capacity and state. The NAT64 is a stateful bottleneck with a finite session table. Size it from measured session counts, not from a rule of thumb, and monitor session table utilisation as a first-class metric.

Addressing and Assignment

An IPv6-only access network still needs a coherent addressing plan for hosts and a DHCPv6 or SLAAC strategy. The trade-offs between stateless and stateful assignment for a network with no IPv4 fallback are the same as anywhere else and are set out in this SLAAC vs DHCPv6 guide. Where the ISP hands you a changing prefix, the mechanics of requesting and renumbering are covered in this DHCPv6 prefix delegation guide - and renumbering is materially harder when there is no IPv4 address to fall back on, so shorten the prefix lifetime deliberately rather than taking the default.

Migration Sequence

  1. Dual-stack everything, and turn on DNS64 + NAT64 for testing while IPv4 is still available.
  2. Move one user segment to IPv6-only with 464XLAT, keeping a rollback path.
  3. Measure the failure list - it will be shorter than expected and dominated by literals and DNSSEC.
  4. Retire IPv4 from the access layer segment by segment, keeping IPv4 only where translation is genuinely needed.

原文链接:https://datatracker.ietf.org/doc/rfc8683