NLnetLabs / nsd

The NLnet Labs Name Server Daemon (NSD) is an authoritative, RFC compliant DNS nameserver.

Home Page:https://nlnetlabs.nl/nsd

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

DNAME: synthesized CNAME might be perfect answer to CNAME query

SivaKesava1 opened this issue · comments

Short description

When there is a DNAME record in the zone file (partial rewrite to the same zone), and that record handles the query, then the RCODE of the server should probably be different depending on whether the query is for CNAME or not. After the DNAME rewrite, the new query name belongs to the same zone but doesn't exist. The server currently returns NXDOMAIN for all the types, but it might be reasonable to return NOERROR for the CNAME type.

Environment

  • Operating system: Ubuntu 18
  • Software version: NSD version 4.1.17
  • Software source: Ubuntu repository

Steps to reproduce

Consider the following sample zone file:

campus.edu. 500 SOA ns1.campus.edu. root.campus.edu. 3 86400 7200 604800 300
campus.edu. 500 NS ns1.outside.edu.
c.d.campus.edu. 500 DNAME f.d.campus.edu.

For the query <a.c.d.campus.edu., CNAME> the answer from the NSD server is:

          "opcode QUERY",
          "rcode NXDOMAIN",
          "flags QR AA",
          ";QUESTION",
          "a.c.d.campus.edu. IN CNAME",
          ";ANSWER",
          "a.c.d.campus.edu. 500 IN CNAME a.f.d.campus.edu.",
          "c.d.campus.edu. 500 IN DNAME f.d.campus.edu.",
          ";AUTHORITY",
          ";ADDITIONAL"

Expected/Actual behavior

The answer section would be the same for the above query, but the RCODE should likely be NOERROR. PowerDNS was doing it that way, but BIND, NSD, and Knot were returning NXDOMAIN for all types so I thought it might be an issue with PowerDNS. I have filed a GitHub issue with PowerDNS, and they said it's intentional and they are doing it correctly. A patch was sent to Knot server also to return NOERROR for the CNAME type.

Thanks, makes sense to me, the CNAME is there so it is not a NXDOMAIN.
Do you have a real-world situation in which this is an issue?

I was checking out different implementations with small test zone files and came across this input where they differed. I followed up and found out that it's a minor bug in some of them, so I filed issues. I don't currently have a scenario where this is used as DNAME is not so common. I brought it up here as other implementations have fixed it/going to fix it, but I understand this is a minor case, so it's not an urgent issue.

This is not correct, it is that the server is answering the question if there is a CNAME type at the destination of the CNAME, a.f.d, and this does not exist, so the answer is NXDOMAIN. When you ask for a type, you ask for the type at the final part of the cname chain, and this is also true for type CNAME, so it comes back NXDOMAIN. It does not answer about the first leg of the chain but for the last. This is also true for type A and AAAA and so on, it would answer about if that type exists at the end of the chain.

In RFC2308, section 2.1.0, page 5, it says so, that the NXDOMAIN refers to the destination of the CNAME, in The NXDOMAIN refers to "TRIPPLE.XX", which is then known not to exist. The query of type CNAME does not make special processing, eg, just like type A, and the answered RCODE is for the final part of the cname chain. And that could be NXDOMAIN if the cname chain ends in a non existing node, or NOERROR if it ends on a node that contains different data.

That's not perfectly correct. It's different for CNAME when compared to other types.
Consider the following zone file:

campus.edu. 500 SOA ns1.campus.edu. root.campus.edu. 3 86400 7200 604800 300
campus.edu. 500 NS ns1.outside.edu.
foo.campus.edu. 500 CNAME bar.campus.edu.

For the query <foo.campus.edu., A> or any other type, the return code is NXDOMAIN as bar does not exist, but for the query <foo.campus.edu., CNAME> the return code is NOERROR. (NSD currently returns in the above manner).
The server algorithm in RFC 6672 mentions in Step 3A that if the query name matches exactly a node and the node has a CNAME record, then check if the query type is CNAME or not. If the query type is also CNAME, then the algorithm terminates; otherwise, it proceeds with the CNAME target.

NSD 3.2.15 changes that with the commit - Fix RCODE when CNAME loop final answer does not exist, should return NXDOMAIN as stated by RFC 6604.

The responses in the previous message are given by the NSD 4.1.17.

Not for me, if I try with latest codebase, I get, for an example to an nonexistant name, and NXDOMAIN, and a SOA record after a fix today, for the last leg of the cnames.

In the case there the CNAME target refers to a referral, then the referral is included and the rcode is set to noerror, that could potentially happen to you?

I haven't tried with the latest code, but when the query is for any other type, the response, as you said, has an SOA record, the CNAME record in the answer section with RCODE NXDOMAIN. For the CNAME type in the query, the response has the NS record in the authority section and the CNAME record in the answer section with the NOERROR code. To be clear, the zone file has just the above three records, and there are no other referral NS records.

RFC 6604 mentions that The RCODE in the ultimate DNS response MUST BE set based on the final query cycle leading to that response. If the xNAME chain was terminated by an error, it will be that error code.

When the query is for any type other than CNAME, then the last query cycle is for bar.campus.edu. but if the query type is CNAME, then the last query cycle is for foo.campus.edu. and so there is no error. (I took it that way, but I might be wrong here, as I have not yet checked with the latest NSD code.) All the other implementations like BIND, Knot, PowerDNS returns NOERROR for CNAME but NXDOMAIN for other types for the above three record zone file.

If you are right that the other implementations do this, then we can do that too; that makes less unexpected surprises in packet responses.