DNAME: synthesized CNAME might be perfect answer to CNAME query
SivaKesava1 opened this issue · 11 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.