Basic guide to the issues around CNAME at the zone apex

What is a CNAME?

In DNS, CNAME stands for “canonical name”.

“Canonical” is one of those words you hear every now and then in technology discussions, but not many people are exactly sure what it means. In effect, it means “official”, which can be further extrapolated to “universally accepted”.

So in a DNS zone file, a CNAME looks like this:

www.nightbluefruit.com. 3600 IN CNAME www.nightbluefruit.hostingcompany.com

In this case, the canonical name for the server which hosts www.nightbluefruit.com is:

www.nightbluefruit.hostingcompany.com

An alias (“also know as”) of that canonical name is:

www.nightbluefruit.com

So if you request this name, which is an alias, the response you will get will be data for the canonical record, for any type of record. For example, if you request the MX data for www.nightbluefruit.com, you will/should receive the MX data for  www.nightbluefruit.hostingcompany.com.

At this point, it is important to understand that www.nightbluefruit.com is an alias of www.nightbluefruit.hostingcompany.com, and not the other way around.

What is the zone apex?

The zone apex is that part of the a DNS zone for which data exists for the entire domain, rather that a specific host in the domain.

So if you want to define an MX records for the entire domain, nightbluefruit.com, you would create that record at the apex:

nightbluefruit.com. 3600 IN MX mail.nightbluefruit.com.

Its worth noting that there is a difference between the default record type for a domain and the zone apex:

*.nightbluefruit.com. 3600 IN A 192.168.100.1

The default value for a particular record type defines the data that should be returned if a request is received for a record type which does not have a specific match is the zone file.

What’s a CNAME at the zone apex?

A CNAME at the zone apex looks like this:

nightbluefruit.com. 3600 IN CNAME www.nightbluefruit.hostingcompany.com.

This is a common requirement for website owners who want to advertise their website without the “www” prefix and who also use the services of a 3rd party web hosting company who cannot provide them with a dedicated ip address and instead provide them with a canonical name for the website running on their infrastructure.

Why is it not allowed?

Given that so many web owners have the requirement outlined above, it seems incredulous that this isn’t allowed, which is why this is such a hot topic.

Firstly, let’s clarify that there is no explicit RFC rule that says “you can’t have a CNAME at the zone apex”.

What the RFCs do say is that if you define a CNAME with a name (the left side of the record declaration) of “nightbluefruit.com”, you can’t create any other record of any other type using the same name. For example, the following would be non-compliant:

nightbluefruit.com. 3600 IN CNAME www.nightbluefruit.hostingcompany.com.
nightbluefruit.com  3600 IN MX mail.nightbluefruit.com.

The reason for this goes back to understanding that the “alias” is the left side and the “official” name is the ride side. If something is “official”, there can only be one version of it. The first record in the above sequence tells DNS that www.nightbluefruit.hostingcompany.com is “official” for nightbluefruit.com, so DNS doesn’t want to know about any other records for nightbluefruit.com.

But, you’ll ask, why can’t DNS simply segregate “officialness” based on the record type? The answer to this is that the DNS standard came into being long before HTTP or any contemplation of shared web hosting, and it is no longer practical to reverse engineer all of the DNS software that has grown out of the standard to fit this specific use case.

Is this strict?

This is where is starts to get interesting.

Given that so many people want CNAMEs at their zone apex ($$$$), many software developers and their product managers have taken a sideways look at the RFC and determined that it permits a degree of flexibility in its implementation:

If a CNAME RR is present at a node, no other data should be present; this ensures that the data for a canonical name and its aliases cannot be different.

The key phrase is “should be”. The argument runs that the absence of the phrase “must be” is in fact a license to interpret the standard more liberally, and there are DNS server implementations on the market that will allow CNAME records to co-exist with other records with the same name.

If you’re using a web hosting or DNS provider who says you can have a CNAME at the zone apex, they will be using such an implementation. This isn’t something that exists only in the dark, backstreets of web hosting. Global internet services providers like Cloudflare have permitted CNAMEs at the zone apex.

In truth, this interpretation exists on very shaky foundations. There is a more detailed discussion of this issue here.

How does this problem manifest itself?

RFCs exist to allow different people design software that will interoperate. If person A is writing code to implement a DNS server, and person B is writing software to implement a DNS client. If they both follow the standard, the 2 pieces of software should work together. The RFC doesn’t tell them how to write code, but it does tell them how their code should behave.

When people beginning interpreting the intent of an RFC, nothing good comes of it. It may not be immediately apparent, but the longer software exists, the more edge cases it has to deal with, and that’s where it becomes important that one piece of software can anticipate the response of another.

In terms of a practical example, this is really good:
https://social.technet.microsoft.com/Forums/exchange/en-US/b3beefee-e353-44ec-b456-f2c70bcd1913/cname-issue?forum=exchange2010

In this case, MS Exchange Server 2010 stopped delivering mail to addresses whose DNS zone had a CNAME at the zone apex. The Exchange mail server was relying on a local DNS cache. Previously, someone had queried an A record for company.com, and received a CNAME response. That data was cached. Later, when the MX record for company.com was queried, the cache ignored the fact that the cached record was an A record (this was compliant behaviour) and returned a CNAME. The Exchange server correctly rejected this as CNAMEs are not valid data for MX queries.

Are there workarounds?

The first workaround is to not implement the RFC standard. Some providers will tell that this is their workaround, but it isn’t. It’s just chicanery, and you should avoid it.

The big cloud hosting companies are the best place to go for workarounds. Amazon AWS have a black box solution in Route53 which allows CNAMEs at the zone apex if the canonical name is an AWS resource identifier (like an ARN for an Elastic Load Balancer).

The most en vogue workaround at the moment is what is called CNAME flattening.

What is CNAME flattening?

DNS server software that implements CNAME flattening permits the user to create multiple CNAMEs of the same name with different official values, which allows the user to create a CNAME at the zone apex. When you configure the zone file in this way, the server will accept it and start as normal.

When a query is then received for one of these records, rather than return the CNAME value, the server will go off and query the CNAME value, and any subsequent values, until it gets to an IP address, and then return that IP address as the response to the original query.

Is CNAME flattening standards compliant?

Yes and no.

On the one hand it permits the existence of something that the RFC says is not permitted, but equally, it behaves in a way that is RFC compliant.

Whether a user wants to rely on CNAME flattening is something they will have to make a call on them according to their individual circumstances.