Resolving a CNAME - who looks up subsequent A record - resolver or server?
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?
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.
The SERVFAIL
should go away if you try that query again with +norecurse
. dig assumes recursion is desired by default, and SERVFAIL
is the correct response to return if recursion was requested and it was not possible to resolve the target of an alias.
Recursive servers which query your authoritive server should not be making the request with the recursion desired (RD=1
) flag set. In short, you should only see this problem in the following two scenarios:
- You are running this transaction by hand and forgetting to disable recursion.
- Someone has written a (poor) implementation of a recursive nameserver and the author has neglected to unset the recursion desired flag when performing authoritative lookups. A recursive nameserver should not be asking authoritative servers to perform recursion on its behalf.