Subject: [DNSOP] RFC2308/6604 violation in NSD and BIND?

From: Peter van Dijk <[email-masked]>
Date: Fri, 26 Oct 2012 14:54:36 +0200

Hello,

first of all, let me say that I could be wrong. Both NSD and BIND violating an
RFC in the same way does not sound like the most likely scenario to me.
However, I want to be sure.

For a CNAME pointing to a non-existing name in the same zone, BIND and NSD
return NOERROR, and do not include a SOA record in the AUTHORITY section.
According to my reading of RFC2308 section 1 (definition of QNAME) and section
2.1, they should return NXDOMAIN and include the SOA.

RFC6604 (which updates 2308) section 3 restates, according to my reading, the
same.

Given a zone example.com with the usual records (SOA, couple of NSes) at the
apex, plus these records:

ns1			IN	A	192.168.1.1
ns2			IN	A	192.168.1.2
nxd			IN	CNAME	nxdomain.example.com.

BIND returns:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 49021
;; flags: qr aa ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 3

;; QUESTION SECTION:
;nxd.example.com.		IN	ANY

;; ANSWER SECTION:
nxd.example.com.	120	IN	CNAME	nxdomain.example.com.

;; AUTHORITY SECTION:
example.com.		120	IN	NS	ns2.example.com.
example.com.		120	IN	NS	ns1.example.com.

;; ADDITIONAL SECTION:
ns1.example.com.	120	IN	A	192.168.1.1
ns2.example.com.	120	IN	A	192.168.1.2

NSD returns the same minus the ra flag.

PowerDNS, however, returns:

;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 34897
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 2800
;; QUESTION SECTION:
;nxd.example.com.		IN	A

;; ANSWER SECTION:
nxd.example.com.	120	IN	CNAME	nxdomain.example.com.

;; AUTHORITY SECTION:
example.com.		86400	IN	SOA	ns1.example.com. ahu.example.com. 2000081501 28800 7200 604800 86400

;; Query time: 1 msec
;; SERVER: 127.0.0.1#5300(127.0.0.1)
;; WHEN: Fri Oct 26 13:06:46 2012
;; MSG SIZE  rcvd: 111

The relevant difference here is NXDOMAIN instead of NOERROR, and the addition
of the SOA. PowerDNS not including the NS records plus their IPs is
inconsequential to the issue, as far as I can tell.

On a sidenote, NSD does include an NSEC3 denying existence of
nxdomain.example.com when DNSSEC+NSEC3 are enabled. I did not verify this for
BIND. PowerDNS currently does not generate this NSEC3 but this will be fixed
shortly.

Opinions welcome!

Kind regards,
-- 
Peter van Dijk
Netherlabs Computer Consulting BV - http://www.netherlabs.nl/

---

From: Mark Andrews <[email-masked]>
Date: Sat, 27 Oct 2012 00:12:56 +1100

> ns2.example.com.	120	IN	A	192.168.1.2

You asked a ANY query.  ANY and CNAME have different processing rules.
The query is NOT restarted with the target of the CNAME.  See RFC 1034.
 
> PowerDNS, however, returns:

You asked a different question (A != ANY).  If you want to compare
answers you need to ask IDENTICAL questions.

> _______________________________________________
> DNSOP mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/dnsop
-- 
Mark Andrews, ISC
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742                 INTERNET: [email-masked]

---

From: Paul Wouters <[email-masked]>
Date: Fri, 26 Oct 2012 09:17:43 -0400 (EDT)

> PowerDNS currently does not generate this NSEC3 but this will be fixed shortly.

You would return an NSEC3 record for a record that actually
exists? That would be a very inconsistent nsec/nsec3 chain.

How would offline signers deal with this? Pregenerate nsec records
for data that _is_ in the zone?

It would also create a really odd behaviour difference between CNAMEs
pointing to non-existing in-zone, versus non-existint out-of-zone 
destinations.

So my feeling, without having read the RFCs you quote, would be to say
that bind and nsd are correct in their behaviour, and that this might
be (or shoudl be) an errata to the RFCs.

Paul

---

From: Peter van Dijk <[email-masked]>
Date: Fri, 26 Oct 2012 15:25:29 +0200

Hello Mark,

Thank you for your swift and accurate response.

> answers you need to ask IDENTICAL questions.

My mistake.

NSD:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34556
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; QUESTION SECTION:
;nxd.example.com.		IN	A

;; ANSWER SECTION:

BIND, PowerDNS (same except for ra flag)

;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 4382
;; flags: qr aa ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; QUESTION SECTION:
;nxd.example.com.		IN	A

;; ANSWER SECTION:

;; AUTHORITY SECTION:

To be complete: 

- for the A query, BIND and PowerDNS return NXDOMAIN+SOA, NSD returns NOERROR.
- for the ANY query, NSD and BIND return NOERROR, PowerDNS returns
  NXDOMAIN+SOA.

Then, as far as I can tell, BIND and PowerDNS do the right thing for the A
query. NSD and BIND do the right thing for the ANY query, going from Mark's
interpretation of the RFCs.

However, 2308 and 6604 totally ignore the ANY exception to following CNAME
chains, and one might argue that thus, 2308 and 6604 still mean that QNAME is
the end of the CNAME chain in the response, and the RCODE thus should be
NXDOMAIN. I think this argument could go either way.

Unless conflicting opinions come in, I will fix PowerDNS to do the right thing
for ANY, and will report the A query issue to the NSD developers.

Kind regards,

---

From: Peter van Dijk <[email-masked]>
Date: Fri, 26 Oct 2012 15:27:41 +0200

Hello Paul,

> exists? That would be a very inconsistent nsec/nsec3 chain.

nxdomain.example.com does not exist.

> for data that _is_ in the zone?

Offline signers would already have generated the NSEC(3) that denies existence
of nxdomain.example.com, simply by virtue of the name not existing in the
zone.

Kind regards,

---

From: Olafur Gudmundsson <[email-masked]>
Date: Fri, 26 Oct 2012 09:53:49 -0400

<dnsext-chair-hat=on>
Strictly speaking this is dnsext fodder not dnsop as the RFC's quoted 
are under DNSEXT change control.
Please move the discussion there.

<dnsext-chair-hat=off>

> nxd.example.com.	120	IN	CNAME	nxdomain.example.com.

This is perfectly OK as NSD in this case is not performing the
optional server side CNAME processing.
The cname exists thus this is a valid answer and valid RCODE.
A recursive resolver now has to ask for nxdomain.example.com and will 
get the no name error.

> example.com.		86400	IN	SOA	ns1.example.com. ahu.example.com. 2000081501 28800 7200 604800 86400

This is fine as well but harder to understand :-) as the RCODE refers to 
the target of the CNAME not the qname.

> s

In the case of ANY IMHO no CNAME processing should take place.
And I encourage you to file errata against the RFC's that we can discuss 
on the dnsext mailing list, before it is approved.

> Kind regards,

Good observations.
	thanks
	Olafur

---

From: Paul Wouters <[email-masked]>
Date: Fri, 26 Oct 2012 10:01:24 -0400 (EDT)

> of nxdomain.example.com, simply by virtue of the name not existing in the

But wouldn't the chain be built based on LHS? Let's check opendnssec:

[root@nohats signed]# ldns-nsec3-hash cname.nohats.ca. -t 5
javgjvs1ictdbmts0fcjome4s37kndg0.
[root@nohats signed]# grep javg nohats.ca 
javgjvs1ictdbmts0fcjome4s37kndg0.nohats.ca.	3600	IN	NSEC3 1 0 5 -  jn89c3qpvavcumn3cv172r7gbu8h6ffs CNAME RRSIG 
javgjvs1ictdbmts0fcjome4s37kndg0.nohats.ca.	3600	IN	RRSIG NSEC3 8 3 3600 20121109223118 20121026121347 52368 nohats.ca.  zjkB06zMPYIAdtGnWoA3wRqe2Fg5y4Y7R21qaQovhqXtijwMQJfukhKA4OWO4oj5DVL/v0WTZRJII64XuAUzVs9RZMAcCuDceR0BdAT5CgjbkvEwgq08/PI06hXvScTjPzFSRPPfRJ3ViAinFDPd2JZHgMkTO9Wen0KkVPH/vhc=
ioukpqjt07l1b83ppfd1grdcc57864ja.nohats.ca.	3600	IN	NSEC3 1 0 5 -  javgjvs1ictdbmts0fcjome4s37kndg0 A RRSIG

So cname.nohats.ca is part of the nsec3 chain.

So in some sense, the record "exists". I guess validators would have to
be very careful handling the NXDOMAIN, they might decide it is spoofed
because they have an existing NSEC/NSEC3 entry for it.

Odd corner case.

Paul