Resolving a CNAME – who looks up subsequent A record – resolver or server

cname-recorddomain-name-system

When a resolver looks up a CNAME, the resolver apparently first sends an A record request to the DNS server. Is the DNS server supposed to figure out that the request is actually for a CNAME, or is the resolver supposed to retry the request, but for a CNAME type? I ask because – and here is the twist – we have an "internal" top level domain we use on our internal LAN, let's call it "domain1", and the DNS server I am querying is the authoritative server for "domain1" (and is recursive for everything else.) What my host (Centos 6.8) actually sends out is a request for an A record:

16:15:45.837525 IP (tos 0x0, ttl 64, id 36911, offset 0, flags [none], proto UDP (17), length 62)
myhost.domain1.40684 > dnsserver.domain1.domain: 15355+ A? cfengine.domain1. (34)
Reply - a servfail:
16:15:45.837762 IP (tos 0x0, ttl 64, id 49982, offset 0, flags [DF], proto UDP (17), length 62)
dnsserver.domain1.domain > myhost.domain1.40684: 15355 ServFail 0/0/0 (34)

If I do a dig for a CNAME type, I get the correct CNAME record (although the A rec is not returned as ADDITIONAL data):

cfengine.domain1.   3600    IN  CNAME   helm02.domain2.

Yes, I know it's poor practice to combine authoritative and recursive functions into a single DNS server, but I don't have control over this DNS setup.

First of all, if authoritative and recursive functions are combined into a single server, and you send a recursion desired query to the server for a CNAME the server is authoritative for – is it even supposed to work?

Assuming it's supposed to work, who is responsible for figuring out my request is actually for a CNAME record and not an A record? The DNS server, or my resolver?

Best Answer

If a server is authoritative for a certain name, has a CNAME record for that name it must respond with that record to queries for all record types.

If a server is doing a recursion, asks for a record type that is not CNAME, but gets a CNAME response, then it should restart the query with the name from the CNAME record, merge the response from the restarted query with the CNAME response and return the combined response to whoever it was doing the recursion for.

Differently put, the authoritative server is responsible for knowing that a name has a CNAME and to respond with that to all queries, and the recursor is responsible for noticing that it got a CNAME back when asking for something else and for acting accordingly. If you specifically ask for a CNAME record, you bypass this extra magic and the recursor will just give you the CNAME response as is without trying to follow the name.