What you get when you do a DNS A record lookup for a CNAME'd name

March 1, 2019

One of the things that we do with our monitoring system is to check that a variety of DNS servers can resolve things from our university subdomain, including our own authoritative server, the external secondary NS, our internal resolving servers, and so on, and recently we started checking through Google's and Cloudflare's public servers. The specific hostname I picked to check the address of is actually a CNAME, so recently I wound up asking the obvious question: if you look up the A record for something that is a CNAME, when should you get back both the CNAME and the A record of the CNAME's target in the reply?

As Wikipedia summarizes, when a DNS server encounters a CNAME record in the process of doing a non-CNAME lookup, it's supposed to restart the query using the CNAME's target (the canonical name). If this restarted lookup is successful, the reply to you will include both the CNAME record and the result of looking up the canonical name, but what results you get from the canonical name lookup depend on what sort of DNS server you're querying.

If you're querying a recursive, resolving DNS server, then you should get back the full result, ie both the CNAME and the A record, and this should happen regardless of whether the target of the CNAME is in the same zone or not (and it doesn't depend on whether the resolving server has the A record cached already; if it doesn't, it will do a full lookup for it). If you're querying a non-recursive DNS server, such as one of the NS records for the domain, then the result depends on whether or not the DNS server also has zone data for the zone of the target name. If it does have zone data, then you'll get back the full answer; otherwise, you appear to get just the CNAME. The simple case of this is when the CNAME's target is in the same zone as the CNAME itself (eg, you have 'a.example.com' being a CNAME to 'b.example.com'). Then an authoritative server is guaranteed to have data for the target, and you'll always get both the CNAME and the A record back, just as if you were asking a recursive DNS server.

So in short, if the CNAME's target is in the same zone, resolving DNS servers and your authoritative DNS servers will both give you a full answer with both CNAME and A records. If they don't, something has gone wrong.

Since the hostname I want to check is CNAME'd to another hostname in our zone, it's safe for me to write a check that requires the DNS reply to contain both the right CNAME record and the right A record. This check should (and does) pass on anything that we want to query, including public DNS servers.

(I don't have enough test cases to say what DNS servers will return if the target of the CNAME doesn't exist. If it's an in-zone name, which I have an example of, I get NXDOMAIN from both our authoritative DNS servers and various recursive resolvers.)

Written on 01 March 2019.
« Taking advantage of the Linux kernel NFS server's group membership cache
Really understanding diffs requires knowing their context too »

Page tools: View Source, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri Mar 1 22:00:01 2019
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.