Subject: [DNSOP] Question on interpretation of DO and CD

From: Eric Rescorla <[email-masked]>
Date: Wed, 6 Oct 2021 16:47:32 -0700

Hi folks,

We've been trying to take some measurements of the success of endpoint
DNSSEC validation and run into some confusion about the implications
of the DO and CD bits. Sorry if these are dumb questions.

In the section on stub resolvers RFC 4035 says:

   A validating security-aware stub resolver MUST set the DO bit,
   because otherwise it will not receive the DNSSEC RRs it needs to
   perform signature validation. (S 4.9.1)

and:
   A validating security-aware stub resolver SHOULD set the CD bit,
   because otherwise the security-aware recursive name server will
   answer the query using the name server's local policy, which may
   prevent the stub resolver from receiving data that would be
   acceptable to the stub resolver's local policy. (S 4.9.2)

And then in S 5, says:
   When a resolver indicates support for DNSSEC (by setting the DO bit),
   a security-aware name server should attempt to provide the necessary
   DNSKEY, RRSIG, NSEC, and DS RRsets in a response (see Section 3).

Looking at things from the stub resolver's perspective, if the zone is
signed, then the stub resolver must receive the necessary RRsets or
fail the resolution. So, there needs to be an unambiguous way for the
stub to tell the recursive to deliver them. Am I right so far?

Reading the above text, I infer that this signal is the DO bit. This
should cause the recursive to deliver the right RRsets (if available)
(I note that this text just says "name server" from which I'm
inferring that it applies to both authoritative and recursive).  Is
this correct? If so, is the fact that this is "should" and not
"SHOULD" telling me something"?

Finally, as I understand it, the function of the CD bit is to tell the
recursive resolver to return records even it if cannot validate them
itself. However, it does *not* tell the recursive resolver to send the
RRsets in the first place, as that's the function of CD.

Summarizing all this, I have the following table of what the stub
should expect to receive if the recursive is a validating resolver and
it asks for an A record (just as an example)

Bits set         Records valid        Records invalid
-----------------------------------------------------
None             A + ???                        Error
DO               A + DNSSEC                     Error
CD               A + ???                      A + ???
DO + CD          A + DNSSEC                A + DNSSEC

Where "A + DNSSEC" means "A + plus the DNSSEC records" and "A + ???"
means "A + maybe some DSNSSEC records depending on what the recursive
wants".

Thanks in advance,
-Ekr

---

From: Michael StJohns <[email-masked]>
Date: Wed, 6 Oct 2021 21:12:45 -0400

Hi EKR  -

Your table looks correct and hope.

You may want to take a look at section 5.9 of RFC 6840, as well as 
appendix B as there's some implementation guidance with respect to the 
setting of the CD bit.

Mike

On 10/6/2021 7:47 PM, Eric Rescorla wrote:
> _______________________________________________
> DNSOP mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/dnsop

---

From: Mark Andrews <[email-masked]>
Date: Thu, 7 Oct 2021 13:41:25 +1100

You should also note that a validating stub resolver (or anything talking
through a validating resolver) should be prepared to send *both* DO and
DO+CD queries. There are different error conditions / threats that are
mitigated by each of these settings and only by trying the other on error
can you ensure that you have mitigated both.

If the validating resolver is being sent spoofed/erroneous traffic DO
will filter that traffic out of the response stream.  DO+CD works around
bad time/trust-anchors in the validating resolver.

Mark

> On 7 Oct 2021, at 10:47, Eric Rescorla <[email-masked]> wrote:
> 
> Hi folks,
> 

-- 
Mark Andrews, ISC
1 Seymour St., Dundas Valley, NSW 2117, Australia
PHONE: +61 2 9871 4742              INTERNET: [email-masked]

---

From: Andrew Sullivan <[email-masked]>
Date: Thu, 7 Oct 2021 00:10:25 -0400

Hi,

Disclaimer: I work for the Internet Society but am speaking for myself.

On Wed, Oct 06, 2021 at 04:47:32PM -0700, Eric Rescorla wrote:
>Sorry if these are dumb questions.

They are not dumb questions, unfortunately.

>stub to tell the recursive to deliver them. Am I right so far?

You are right.  The problem is that the protocol is exactly ambiguous enough, in my reading, that there isn't a way to ensure that happens.

RFC 6840 attempted to clarify a number of things, but there are IMO two gaps in it.

First of all, it is apparent that if a resolver maintains a unified cache in which it has DNSSEC-aware and DNSSEC-oblivious data, things will definitely break.  The general wisdom appears to be that you need to maintain two caches, and only answer DO-set queries with DO-set cache (or go fetch); but if there's ever been explicit protocol requirement of this, I have forgotten it.  The upshot is that it is entirely possible for a cache to have some but not all the DNSSEC data to answer a query, and to respond with what it has, and I know I have seen this in the wild.

Much worse is the continued confusion around CD, which 6840 tried pretty hard to sort out but that seems to remain a dark corner of the protocol.  The reality is that the SHOULD about setting CD in 6840 probably has to be a MUST or else stuff will almost certainly break.  For some reason I now don't recall, some people wanted to be able to select a policy in which they didn't set CD even though it was the only way the validating stub would actually get everything it needed.  This is laid out in some detail in Appendix B, but the result is still not that satisfying to someone who wants predictable behaviour our of the validated resolution system.

Hope that's helpful,

A

-- 
Andrew Sullivan
[email-masked]

---

From: George Michaelson <[email-masked]>
Date: Thu, 7 Oct 2021 14:49:53 +1000

> First of all, it is apparent that if a resolver maintains a unified cache in which it has DNSSEC-aware and DNSSEC-oblivious data, things will definitely break.  The general wisdom appears to be that you need to maintain two caches, and only answer DO-set queries with DO-set cache (or go fetch); but if there's ever been explicit protocol requirement of this, I have forgotten it.

Sorry, but I think this is just an over-reach. There is no necessary
reason for a single information model to break. It is about how you do
it. The problem of course is transitive links in the tree from one
state (signed) to the other (unsigned) and back again, and associated
meta data. Arguably, its one information model, one cache,  but the DO
bit flagging limits what answers you can tell people and you have to
reply with SERVFAIL for information you hold, even though you know the
next query might well be for the same info without DO force.

It may well be logistically simpler to run two caches, but this
statement seems to me to be over-stating things.

G

---

From: Mark Andrews <[email-masked]>
Date: Thu, 7 Oct 2021 17:52:49 +1100

> On 7 Oct 2021, at 15:49, George Michaelson <[email-masked]> wrote:
> 

Very much so.

Eric,
      DNSSEC validation does not work *reliably* if the upstream resolvers
are not *validating*.  Anyone that does a rigorous analysis of the protocol
will tell you this.

DNSSEC will work reasonably well if the upstream are just DNSSEC aware (keep the
RRSIGs with the data they cover, pass through negative proofs required for
the answers) if there is not spoofed traffic, a mix of DNSSEC aware and DNSSEC
oblivious server for the zone, etc.  A validating upstream will block this
badness and only pass through good responses. A non-validating upstream will
cache this garbage.

It will fail abysmally if the upstreams are not DNSSEC aware.  Don’t even
attempt it.

I know many on this list don’t like hearing this, that they would like it
if DNSSEC aware was enough so that intermediate resolvers don’t need to
validate.  They are fooling themselves.  This is where the "just send CD=1"
came from.  The fear that the upstream will have a bad trust anchor or bad
time are just that, fears. If a upstream has a bad clock or bad trust anchors
then everything will be failing and it will get fixed.  Just send DO=1,CD=0
and on the few cases where you get SERVFAIL return with DO=1,CD=1.

Now there are some improvements that could be made to make the protocol
even more robust when there are intermediate resolvers.  Passing the
trust anchors (DS record form) the downstream is using to the upstream
to improve the robustness of the process.  One could also pass the clients
concept of time.

Mark

---

From: Brian Dickson <[email-masked]>
Date: Thu, 7 Oct 2021 00:48:47 -0700

Quick question in a top-reply, sorry:
Mark:
Is there any combination of flag bits or EDNS options that a stub can use
to reliably determine if a resolver is validating?

Obviously there are clever tricks possible, such as sending queries to a
small set of domains that identify whether resolvers validate (at all
and/or correctly), that have been used in some previous tests by George and
Geoff.

But, are there ways that give immediate confirmation (and can be used on
every query) of the DNSSEC-validating status of a resolver?

Brian

On Wed, Oct 6, 2021 at 11:53 PM Mark Andrews <[email-masked]> wrote:

> >> First of all, it is apparent that if a resolver maintains a unified
> cache in which it has DNSSEC-aware and DNSSEC-oblivious data, things will
> definitely break.  The general wisdom appears to be that you need to
> maintain two caches, and only answer DO-set queries with DO-set cache (or
> go fetch); but if there's ever been explicit protocol requirement of this,
> I have forgotten it.
> >

---

From: Joe Abley <[email-masked]>
Date: Thu, 7 Oct 2021 09:55:34 +0200

On Oct 7, 2021, at 09:49, Brian Dickson <[email-masked]> wrote:

> Is there any combination of flag bits or EDNS options that a stub can use to reliably determine if a resolver is validating?

Do you mean reliably determine if a resolver is claiming to validate, or reliably determine whether a resolver is actually validating?

Joe

---

From: Brian Dickson <[email-masked]>
Date: Thu, 7 Oct 2021 01:43:00 -0700

Sent from my iPhone

> On Oct 7, 2021, at 12:55 AM, Joe Abley <[email-masked]> wrote:
> 

Claiming… if the answer is that it is not claiming that, it might simplify some parts of the logic on use of CD.

If there isn’t any way to reliably determine that it is claiming to validate, that is unfortunate, and then begs the question on whether it is worth doing anything about it.

Brian

---

From: Joe Abley <[email-masked]>
Date: Thu, 7 Oct 2021 11:44:13 +0200

> If there isn’t any way to reliably determine that it is claiming to validate, that is unfortunate, and then begs the question on whether it is worth doing anything about it.

I'm not sure what value such a claim would have anyway. 

If you need to be sure that something is correct to the extent that you require cryptographic proof, then you need cryptographic proof. This surely means you need to establish a path of trust from an anchor to the leaf you care about. 

Some unsigned promise from an external system to behave in any particular way surely doesn't meet the bar; if it does, then perhaps you don't in fact require cryptographic proof. 

So I think your question needs work. 

Joe

---

From: Peter van Dijk <[email-masked]>
Date: Thu, 07 Oct 2021 12:25:59 +0200

> of the DO and CD bits. Sorry if these are dumb questions.

Not dumb questions!

> Bits set         Records valid        Records invalid

Looks right to me. I'd expect no DNSSEC records in your "???" cases.

During the implementation of DNSSEC validation in the PowerDNS Recursor we also found that it's impossible to make sense of it all without laying out all permutations. Here's a table Pieter Lexis built around that time (it has different dimensions than yours, but given your initial understandable confusion, maybe you want to read it and see if anything surprises you): https://doc.powerdns.com/recursor/dnssec.html#what-when
 
Kind regards,
-- 
Peter van Dijk
PowerDNS.COM BV - https://www.powerdns.com/

---

From: Andrew Sullivan <[email-masked]>
Date: Thu, 7 Oct 2021 11:44:39 -0400

Still speaking only for myself :)

On Thu, Oct 07, 2021 at 02:49:53PM +1000, George Michaelson wrote:
>> if there's ever been explicit protocol requirement of this, I have forgotten it.
>
>reason for a single information model to break.

And this, of course, is why there isn't such an explicit protocol requirement (and also why we weren't able to get to consensus on MUST set CD on queries): these things represented protocol changes, however trivial, and people didn't accept they were absolutely necessary so the answer was no.  From the point of view of an implementer coming along later, however, it sure seems like a gap in the protocol (particularly if you want to maximize interoperability).  After all, while we might say, "It's one information model and you need to understand the interactions of the model components," the chances are good that an implementer will _not_ understand those interactions or even componets, and will mess up the implementation accordingly.

Best regards,

A

-- 
Andrew Sullivan
[email-masked]

---

From: Mark Andrews <[email-masked]>
Date: Fri, 8 Oct 2021 08:22:37 +1100

> On 8 Oct 2021, at 02:44, Andrew Sullivan <[email-masked]> wrote:
> 

The model used to develop DNSSEC was a single cache with only validated
answers in it.  If you got asked with CD *and* it is not cached you ask
upstream with CD, pass the answer through without validating it, then
possibly validate and cache it.  If you have a cached answer you just
return it (validated as secure or validated as insecure).

That is the model that was used to develop DNSSEC.

---

From: Eric Rescorla <[email-masked]>
Date: Fri, 8 Oct 2021 12:11:57 -0700

Hi Mark,

Thanks for your response.

> bad time/trust-anchors in the validating resolver.

Can you elaborate on this a bit? I.e., if I sent DO + CD, then won't I just
get an unfiltered view and be able to sort it out locally? What am I
missing?

-Ekr

Mark

---

From: Benno Overeinder <[email-masked]>
Date: Mon, 11 Oct 2021 16:54:42 +0200

> It will fail abysmally if the upstreams are not DNSSEC aware.  Don’t even

With the getdns API library and stub resolver design, quite a bit of 
effort has gone into "road block avoidance" i.e. checking if the 
upstream resolver is DNSSEC aware and falling back to full recursion if 
it isn't (to obtain the DNSSEC data for end-point validation).

For pictures, see the slide desk 
https://getdnsapi.net/slides/an-earnest-stub.pdf, slide 17 and onwards.

-- Benno

-- 
Benno J. Overeinder
NLnet Labs
https://www.nlnetlabs.nl/