It has been quite some time since the transition from IPv4 to IPv6 started. Despite being a standard internet protocol for a few years now, there are still many web services that don't support IPv6. Lately, several governments around the world have started to push their suppliers to support IPv6 in an attempt to speed up the process.
In this article, I will try to explain how (many) clients resolve domain names to IP addresses when a web service is available on both IPv4 and IPv6. I will also explain what can go wrong if you don't do it right when serving websites.
IPv4 vs IPv6
An executive summary
IPv4 is the internet protocol that has been used everywhere since the dawn of the internet. Typically a network card has one IPv4 address that is used when sending packets of data between computers in your local network, or over the internet. When sending a packet to an IPv4 address the computer will first check if the receiver is on its own network, if it's not on the same network, it will send the packet to the network router. The router then forwards it in a generally correct direction of the receiver's IP address.
Technically, the IP packet is put inside an Ethernet frame when being sent between devices on the same network, but this is outside the scope of this article.
The problem with IPv4 is that it was never built to handle the growth of global internet users, and the fact that an incredible amount of electronic gizmos are now internet-connected. An IPv4 address is only a 32-bit address, meaning that there are only 4 294 967 295 theoretically available addresses. That might seem like a lot, but first of all, not all those addresses can be used because of how IPv4 addresses are distributed and used. Secondly, we unfortunately used up all those addresses. For a few years, we have relied on tricks like NAT (Network Address Translation) and PAT (Port Address Translation) to make several computers on a network share a single IP address on the internet.
The solution to the address shortage problem is IPv6. This internet protocol uses 128-bit addresses. Remember that a 33-bit number is twice as large a number as a 32-bit number. Because of this 128-bits can be used to represent a number that is incredibly larger than a 32-bit number. A famous analogy is that with IPv6, every grain of sand on earth can have its own IP address, and we could still have a lot of addresses left.
IPv6 also has a lot of different features that make it a lot better than IPv4. But that's also out of the scope of this article. 😅
Another executive summary
DNS (Domain Name System) is the phonebook system for the web. When you try to navigate to https://www.haxor.no in your web browser, the browser will check what IP address that domain name is located at. This process is called resolving domain names and is performed by sending a request to a DNS server and querying it for a resulting IP address.
- When querying for an IPv4 address, the web browser will query an "A-record".
- When querying for an IPv6 address, the browser will query an "AAAA-record".
It's important to remember that www.haxor.no and haxor.no are technically two completely separate domain names, and will be treated as such by both the web browser and a DNS server. With webpages, it's not common to not use another A-record for the www.haxor.no domain, but instead, use a CNAME-record that points to a domain name of the server it's hosted on. An example of a server name can be c2.haxor.no. There are several reasons for this, and they are all out of the scope of this article.
Yet another executive summary
A web server is a service that is running on a computer somewhere on the internet. A web server can host multiple websites. Since many webpages can be hosted on the same web server, and they are in turn served on a computer that has a single IP address, each web request has to include the name of the "host" they want data from.
The web server will forward the request to the correct website that is hosted on that hostname. If the webserver does not have a host with the requested hostname it will respond with an error message, or in most cases it will respond with either a default host or the alphabetically first host on the webserver. Both will result in upset end-users and clients.
In addition to being separated by hostnames, the hosts are separated by port numbers. One host can be served on multiple ports and can have multiple host names. A great example is haxor.no and www.haxor.no that is served on both port 80 for HTTP, and port 443 for HTTPS. Every combination of those hostnames and ports is going to the same host on my web server, but technically each combination of hostname and port number is a unique host.
In practice, a host on a web server has to be configured to listen to both IPv4 requests and IPv6 addresses.
IPv6 and DNS
When thigs become tricky
Many web browsers will try to query the DNS server for an AAAA-record (IPv6) of a domain name first. If it does not find an AAAA record, it will proceed to query the DNS server for the A-record of a domain name.
The problem arises when you have a situation where not all hosts on the web server are configured to allow for IPv6 requests, and a subdomain is configured to use a CNAME that points to a domain name that is configured with both A-record and AAAA-record.
A subdomain is a domain that belongs to a domain. www.haxor.no is the subdomain of haxor.no
For example, the DNS server that stores records for the haxor.no domain has the following records:
- haxor.no (note the lack of www) has an A-record that stores the IPv4 address and an AAAA-record that stores the IPv6 address where this website is hosted.
- www.haxor.no (note the www subdomain) is a CNAME that points to c2.haxor.no.
- c2.haxor.no has an A-record that stores the IPv4 address of the server, and a AAAA-record that stores the IPv6 address of the server.
Since I like to serve my web pages on www.haxor.no, I have created a redirect from haxor.no to www.haxor.no.
Imagine if the server's domain name (c2.haxor.no) is configured with both an A-record, and an AAAA-record, but the web server host that is serving haxor.no and www.haxor.no is not configured to respond to IPv6 requests. Because of how (most?) web browsers prefer IPv6 addresses a requester from a web browser will look like this if:
- The web browser will query the IP addresses of haxor.no from a DNS server.
- The DNS server will respond with just the A-record of the haxor.no.
- The web browser will then send a request to the IPv4 address of haxor.no, asking for the content of the host haxor.no.
- The web server will then respond with a redirect to www.haxor.no
- The web browser will then make a DNS query for the IP address of www.haxor.no.
- The DNS server will respond with the CNAME of c2.haxor.no
- The web browser will then send a DNS query for the IPv6 address of c2.haxor.no
- The DNS server will respond with the A-record and AAAA-record for c2.haxore.no
- The web browser will then make a request to the IPv6 address of c2.haxor.no asking for the content of the host www.haxor.no
- Because the web server does not have a matching host for IPv6, it will respond with the default host for IPv6.
- The web browser will then NOT receive the anticipated webpage.
Remember that both the hostname, IP address, and port number make up the definition of how you access a host.
If you have not configured every host on the webserver to respond to IPv6 requests the web server will either respond with a default host or the alphabetically first hostname on the web server.