NAT64 is a gateway that allows IPv6-only clients to reach IPv4-only servers by translating IPv6 addresses to IPv4 addresses on the fly.

Let’s see it in action. Imagine an IPv6-only client, 2001:db8:1::100, trying to access a classic IPv4 web server at 192.0.2.1.

Here’s a simplified packet flow:

  1. Client sends to NAT64 gateway: The client constructs an IPv6 packet. The destination address is a special IPv6 prefix that the NAT64 gateway understands, often in the format 64:ff9b::/96 followed by the IPv4 address. So, 2001:db8:1::100 sends a packet to 64:ff9b::192.0.2.1. The source address is the client’s IPv6 address, 2001:db8:1::100.

  2. NAT64 gateway receives: The NAT64 gateway, let’s say with IPv6 address 64:ff9b::1 and an internal IPv4 address 192.168.1.1, receives the packet.

  3. Address translation: The gateway looks at the destination IPv6 address 64:ff9b::192.0.2.1. It strips off the 64:ff9b:: prefix, leaving the IPv4 address 192.0.2.1. It then rewrites the packet:

    • Source IP: Changes from 2001:db8:1::100 to its own internal IPv4 address, 192.168.1.1.
    • Destination IP: Remains 192.0.2.1.
    • Port: The gateway typically uses Network Address Translation (NAT) to map the client’s source IPv6 address and port to an internal IPv4 address and a unique port. For example, if the client used UDP port 54321, the gateway might map this to its IPv4 address 192.168.1.1 on UDP port 34567.
  4. Forward to IPv4 server: The translated IPv4 packet is sent to the destination IPv4 server 192.0.2.1.

  5. Server replies: The IPv4 server 192.0.2.1 receives the packet from 192.168.1.1 (the NAT64 gateway’s IPv4 address). It sends a reply back to 192.168.1.1.

  6. NAT64 gateway receives reply: The gateway receives the IPv4 reply.

  7. Reverse translation: The gateway consults its NAT translation table. It finds the mapping for 192.168.1.1 and port 34567, which corresponds to the original client 2001:db8:1::100 and port 54321. It rewrites the packet:

    • Source IP: Changes from 192.168.1.1 to the IPv6 equivalent of the original destination, 64:ff9b::192.0.2.1.
    • Destination IP: Changes from 192.168.1.1 to the client’s IPv6 address, 2001:db8:1::100.
    • Port: The original client port 54321 is restored.
  8. Forward to IPv6 client: The translated IPv6 packet is sent back to the client 2001:db8:1::100.

This seamless translation is powered by the Stateless IP/ICMP Translation (SIIT) algorithm, which defines the mapping between IPv6 and IPv4 addresses. There are two primary forms:

  • Stateful NAT64: The gateway maintains a table of active translations, just like traditional NAT. This is common for TCP and UDP.
  • Stateless NAT64: The translation is purely algorithmic. The IPv6 address is constructed by prepending a fixed prefix (like 64:ff9b::/96) to the IPv4 address. No state is stored on the gateway for this part, making it highly scalable. However, it relies on the client and server using the same ports for the reverse translation to work without a state table. When combined with DNS64, it can handle both stateful and stateless scenarios.

The DNS64 server is a crucial partner in the NAT64 ecosystem. When an IPv6-only client tries to resolve an IPv4-only domain name (e.g., example.com), the DNS64 server intercepts the request. If the DNS server would normally return an A record (IPv4 address), the DNS64 server synthesizes an AAAA record (IPv6 address). This synthesized IPv6 address is formed by taking the IPv4 address and prepending the NAT64 prefix (e.g., 64:ff9b::/96). So, an A record for 192.0.2.1 would result in a DNS64 returning a synthetic AAAA record for 64:ff9b::192.0.2.1. The IPv6-only client then uses this synthetic IPv6 address, which is routed to the NAT64 gateway.

The most surprising true thing about NAT64 is that it doesn’t require the NAT64 gateway to maintain session state for stateless translation to work, provided the DNS64 synthesizes addresses correctly and the client/server use predictable ports. The translation is entirely derived from the address itself.

Consider a scenario where you have an IPv6-only client network with the prefix 2001:db8:1::/64. Your NAT64 gateway has an IPv6 address 64:ff9b::1 and an internal IPv4 address 192.168.1.1. The NAT64 prefix configured on your gateway is 64:ff9b::/96.

If an IPv6 client 2001:db8:1::100 tries to reach 198.51.100.50 (an IPv4 server), the DNS64 server would return the synthetic IPv6 address 64:ff9b::198.51.100.50. The client sends a packet to this destination. The NAT64 gateway receives it. It strips 64:ff9b:: to get 198.51.100.50. It then maps the client’s source 2001:db8:1::100:xxxx (where xxxx is a port) to its own IPv4 address 192.168.1.1 and a new port, say yyyy. The packet is sent as src=192.168.1.1:yyyy, dst=198.51.100.50. The IPv4 server replies to 192.168.1.1:yyyy. The NAT64 gateway sees the reply, looks up 192.168.1.1:yyyy in its table (or reconstructs it if stateless), finds it maps to 2001:db8:1::100:xxxx, and sends the packet back.

The critical component that most people overlook is the DNS64 server. Without it, IPv6-only clients wouldn’t even know how to form the synthetic IPv6 addresses that NAT64 translates. It acts as the bridge on the DNS layer, making IPv4 resources appear as IPv6 resources to the IPv6-only clients.

The next logical step after understanding NAT64 is exploring DNS64 configuration and its interaction with BIND or CoreDNS.

Want structured learning?

Take the full Computer Networking course →