Subject: [dnsext] NSEC for preemptive assertion of nonexistence

From: Stuart Cheshire <[email-masked]>
Date: Tue, 21 Apr 2009 15:44:32 -0700

In our discussions last September, Wouter Wijngaards made this good  
suggestion:

> Why don't you use the existing NSEC record type, that can be used to
> list all the types present (and absent) for a record?
>
> It would look like this:
> stuartsprinter.local.           120 IN A	169.254.123.45
> stuartsprinter.local.		120 IN NSEC	. A NSEC

We're finally at the point of implementing this, and we're debating  
what name should go in the "Next Domain Name" field.

The two obvious candidates are root and self, but both have drawbacks:

1. Use root, e.g. "stuartsprinter.local. 120 IN NSEC . A NSEC"

+ Nice and compact
- Introduces a special interpretation for "Next Domain Name" ==  
"root", namely that this is not asserting the non-existence of any  
other names.

Unfortunately, "Next Domain Name" == "root" already has a valid  
interpretation, namely that this is the last name in the root zone.  
When the root zone is signed, (if I understand it correctly) the last  
name in the zone will have an NSEC record something like this: "zw.  
2D IN NSEC . NS NSEC". This is asserting that "zw." is the last name  
in the root zone.

2. Use own rrname, e.g. "stuartsprinter.local. 120 IN NSEC  
stuartsprinter.local. A NSEC"

- Less compact (unless name compression is used, which would violate  
RFC 3845)
+ Seems semantically cleaner (but maybe not)

This would seem semantically cleaner, except it may still not be  
quite right. In a signed zone that contains nothing but a single name  
at its apex, you'd have a self-referential NSEC record, something  
like this: "minimal-zone.example. 2D IN NSEC minimal-zone.example. A  
NS SOA NSEC". This is asserting that there are no (delegated or non- 
delegated) subdomains of "minimal-zone.example." In our mDNS case,  
this is more than we want to assert, since claiming ownership of  
"foo.local." does not necessarily assert ownership of  
"bar.foo.local." or any other names falling under "foo.local."

However, I may not be understanding this quite right. In the parent  
zone ("example.") there will also be an NSEC record, potentially  
something like this: "minimal-zone.example. 2D IN NSEC next- 
name.example. NS NSEC". That NSEC record is *not* asserting that the  
name a.minimal-zone.example. does not exist, just that it does not  
exist in the "example." zone.

I'm trying to work out solution that fits this set of constraints.  
Given that no perfect solution seems to exist, I'm leaning towards a  
new option 3:

3. A "special" variant of NSEC, e.g. "stuartsprinter.local. 120 IN  
NSEC . A"

This uses the root domain name as the Next Domain Name field, which  
is compact on the wire, and simple to program. However, since in this  
usage case this is a synthesized record, not an actual record in a  
signed zone, the NSEC bit is *not* set in the bitmap. This means that  
this special synthesized variant of NSEC is easily distinguishable  
from the NSEC record that asserts "this is the last record of the  
root zone" because that record has the NSEC bit set, and the  
synthesized NSEC that's only talking about one specific name, not a  
range of names, does not have the NSEC bit set.

That's the best I can think of right now. If feels a bit rough, but  
maybe it's not so bad. It's programmatically simple, and should there  
ever be any confusion in the future between real NSEC records and  
these synthetic ones, the absence of the NSEC bit in the synthetic  
ones means they can be programmatically distinguished.

Any better ideas would be welcomed.

Stuart Cheshire <[email-masked]>
* Wizard Without Portfolio, Apple Inc.
* Internet Architecture Board
* www.stuartcheshire.org

--
to unsubscribe send a message to [email-masked] with
the word 'unsubscribe' in a single line as the message text body.
archive: <http://ops.ietf.org/lists/namedroppers/>

---

From: John Dickinson <[email-masked]>
Date: Wed, 22 Apr 2009 09:47:13 +0100

On 21 Apr 2009, at 23:44, Stuart Cheshire wrote:

> When the root zone is signed, (if I understand it correctly) the  
> last name in the zone will have an NSEC record something like this:  
> "zw. 2D IN NSEC . NS NSEC". This is asserting that "zw." is the last  
> name in the root zone.
>
> quite right. In a signed zone that contains nothing but a single  
> name at its apex, you'd have a self-referential NSEC record,  
> something like this: "minimal-zone.example. 2D IN NSEC minimal- 
> zone.example. A NS SOA NSEC". This is asserting that there are no  
> (delegated or non-delegated) subdomains of "minimal-zone.example."  
> In our mDNS case, this is more than we want to assert, since  
> claiming ownership of "foo.local." does not necessarily assert  
> ownership of "bar.foo.local." or any other names falling under  
> "foo.local."
>
> is compact on the wire, and simple to program. However, since in  
> this usage case this is a synthesized record, not an actual record  
> in a signed zone, the NSEC bit is *not* set in the bitmap. This  
> means that this special synthesized variant of NSEC is easily  
> distinguishable from the NSEC record that asserts "this is the last  
> record of the root zone" because that record has the NSEC bit set,  
> and the synthesized NSEC that's only talking about one specific  
> name, not a range of names, does not have the NSEC bit set.
>
> maybe it's not so bad. It's programmatically simple, and should  
> there ever be any confusion in the future between real NSEC records  
> and these synthetic ones, the absence of the NSEC bit in the  
> synthetic ones means they can be programmatically distinguished.
>

Could another option be to use the successor part of RFC4471?

John
---
John Dickinson
http://www.jadickinson.co.uk

I am riding from Lands end to John O'Groats to raise money for  
Parkinson's Disease Research. Please sponsor me here http://justgiving.com/pedalforparkinsons2009

---

From: Stuart Cheshire <[email-masked]>
Date: Wed, 22 Apr 2009 10:36:49 -0700

> Could another option be to use the successor part of RFC4471?

Yes, I did think of that, but:

(a) Implementation: It seems like a lot of work just to compute a  
value we intend to be ignored anyway.

(b) Semantics: Computing "<nil>.name.example." as the successor to  
"name.example." to put in the NSEC record seems to be asserting that  
the name <nil>.name.example." does exist, when in fact it (probably)  
does not.

---

From: John Dickinson <[email-masked]>
Date: Wed, 22 Apr 2009 19:09:30 +0100

> value we intend to be ignored anyway.

Yes, I agree that may well be true and a very good reason not to do  
this. However, I don't think that in your case you would need to  
calculate the successor on the fly in response to every query would you?

> the name <nil>.name.example." does exist, when in fact it (probably)  

I don't agree, NSEC (especially as modified in 4470 and 4471) tells us  
that the space between two names is empty, it doesn't say anything  
about the existence of those two names. After all, isn't that the  
whole point of 4470 and 4471 - to prevent zone enumeration.

John
---
John Dickinson

---

From: Olafur Gudmundsson <[email-masked]>
Date: Wed, 22 Apr 2009 14:08:38 -0400

>exist in the "example." zone.

<no-hat>

There are violations and there are Violations.
In your case "stuartsprinter.local." is authorative for it self, but it
is not advertising NS set nor a SOA ==> violation of contents of a 
DNS delegation.

But in your system there are no delegations, there are only
claims to names, thus your can strictly say NS and SOA are not need ==>
you can draw any conclusions from:
         bar.local. NSEC bar.local.  AAAA
if foo.bar.local. exists or not.

My recommendation is to use the same target name as the owner name.

         Olafur