
How to Work With IPv6 in AWS and Don't Die in the Process
Discover how to transition from IPv4 to IPv6 in AWS. This guide covers topics like IPv6 subnetting, public and private subnets, and DNS64 and NAT64.
2001:0db8:85a3:0000:0000:8a2e:0370:7334
- Leading zeros in each field could be omitted.
- The longest sequence of zeros could be compressed as double colons
::
.
2001:db8:85a3::8a2e:370:7334
which is way shorter.<ipv6-address>/N
where N is the number of bits representing the network part. For example, the address 2001:0db8:85a3::/64
uses the first 64 bits to set the network part, and the remaining 64 bits represent the host part ( 2^64 = 18446744073709551616264 hosts, which are a lot)./56
by default for VPC IPv6 CIDR ranges, but it could be in the range /44
to /60
in increments of /4
. Subnets have a fixed sized of /64
. This simplifies things a lot when designing networks with IPv6 in AWS.::/0
pointing to an Internet gateway. On the contrary, the subnet is considered private. But what happens with egress traffic in an IPv6 subnet? It depends, of course, on the type of subnet.- Dual-stack IPv4 and IPv6 subnets.
- IPv6 only subnets.
0.0.0.0/0
, and IPv6 egress traffic will be routed through an Egress Only Internet Gateway with a default route ::/0
.
Egress Only Internet Gateways work in a similar fashion as an Internet Gateway but with the difference that in only allows outbound traffic and not inbound traffic.

- DNS64
- NAT64
A
for IPv4 records or type AAAA
for IPV6 records. So, when you ask for a DNS record from an IPv6 only subnet, if the service you intend to access doesn’t support IPv6 you’ll receive an IPv4 address and won’t be able to connect. To solve this issue, AWS offers DNS64.AAAA
record, if there is at least one, or an IPv6 address synthesized by prepending the well-known /96
prefix, defined in RFC6052 (64:ff9b::/96)
, to the IPv4 address in the A
record.- From the
64:ff9b::/96
prefix, the NAT Gateway recognizes that the original destination is IPv4 and translates the IPv6 packets to IPv4 by replacing:- Source IPv6 with its own private IP which is translated to Elastic IP address by the Internet Gateway.
- Destination IPv6 to IPv4 by truncating the
64:ff9b::/96
prefix.
- The NAT Gateway sends the translated IPv4 packets to the destination through the Internet Gateway, Virtual Private Gateway, or Transit Gateway and initiates a connection.
- The IPv4-only host sends back IPv4 response packets. After a connection is established, NAT Gateway accepts the response IPv4 packets from the external hosts.
- The response IPv4 packets are destined for NAT gateway, which receives the packets and de-NATs them by replacing its IP (destination IP) with the host’s IPv6 address and prepending back
64:ff9b::/96
to the source IPv4 address. The packet then flows to the host following the local route.

gitlab.com
:gitlab.com
resolves to 2606:4700:90:0:f22e:fbec:5bed:a9b9
so the traffic is routed trough Egress Only Internet Gateway to reach the destination.github.com
github.com
resolves to 64:ff9b::4d0:1ac5
. As we saw earlier, this address is prefixed by 64:ff9b::/96
and the latest 32 bits, 4d0:1ac5
, correspond with the IPv4 address 4.208.26.197
.54.154.55.245
and then reaches the NGINX even though it is located in an instance in an IPv6 only subnet.2a05:d018:edc:de00:fcd3:24a:53bd:eff1
and 54.154.55.245
but chooses the IPv6 one rendering the same content without any issues.