RFC 5155

DNS Security (DNSSEC) Hashed Authenticated Denial of Existence

๐Ÿ“… published March 2008, from ietf

RFC 5155: DNSSEC Hashed Authenticated Denial of Existence ๐ŸŒธ

Okay bestie, this one is RFC 5155, published in March 2008 as a Standards Track document from the Network Working Group. It was written by B. Laurie, G. Sisson, and R. Arends of Nominet, plus D. Blacka of VeriSign, Inc. โœจ The header doesn't list anything it obsoletes or updates, so it stands on its own. ๐ŸŽ€

Status of This Memo

This document is a standards track protocol for the Internet community ๐Ÿ’– It's asking for discussion and suggestions for improvements, so it's basically inviting everyone into the group chat ๐Ÿซถ For the current standardization state and status of this protocol, check the latest edition of "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited ๐Ÿฆ‹

Abstract

Okay so the DNS Security Extensions (DNSSEC) gave us the NSEC resource record (RR) for authenticated denial of existence ๐Ÿ” This doc introduces a new one called NSEC3, which does the same job of proving a name doesn't exist, but with extra perks ๐Ÿ’… It adds measures against zone enumeration (aka nobody can just list everything in your zone ๐Ÿ™ˆ) and it lets delegation-centric zones expand gradually ๐ŸŒˆ iconic behaviour, honestly.

Table of Contents

Table of Contents โœจ

1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  4
  1.1.  Rationale  . . . . . . . . . . . . . . . . . . . . . . . .  4
  1.2.  Requirements . . . . . . . . . . . . . . . . . . . . . . .  4
  1.3.  Terminology  . . . . . . . . . . . . . . . . . . . . . . .  5
2.  Backwards Compatibility  . . . . . . . . . . . . . . . . . . .  6
3.  The NSEC3 Resource Record  . . . . . . . . . . . . . . . . . .  7
  3.1.  RDATA Fields . . . . . . . . . . . . . . . . . . . . . . .  8
    3.1.1.  Hash Algorithm . . . . . . . . . . . . . . . . . . . .  8
    3.1.2.  Flags  . . . . . . . . . . . . . . . . . . . . . . . .  8
    3.1.3.  Iterations . . . . . . . . . . . . . . . . . . . . . .  8
    3.1.4.  Salt Length  . . . . . . . . . . . . . . . . . . . . .  8
    3.1.5.  Salt . . . . . . . . . . . . . . . . . . . . . . . . .  8
    3.1.6.  Hash Length  . . . . . . . . . . . . . . . . . . . . .  9
    3.1.7.  Next Hashed Owner Name . . . . . . . . . . . . . . . .  9
    3.1.8.  Type Bit Maps  . . . . . . . . . . . . . . . . . . . .  9
  3.2.  NSEC3 RDATA Wire Format  . . . . . . . . . . . . . . . . .  9
    3.2.1.  Type Bit Maps Encoding . . . . . . . . . . . . . . . . 10
  3.3.  Presentation Format  . . . . . . . . . . . . . . . . . . . 11

4.  The NSEC3PARAM Resource Record . . . . . . . . . . . . . . . . 12
  4.1.  RDATA Fields . . . . . . . . . . . . . . . . . . . . . . . 12
    4.1.1.  Hash Algorithm . . . . . . . . . . . . . . . . . . . . 12
    4.1.2.  Flag Fields  . . . . . . . . . . . . . . . . . . . . . 12
    4.1.3.  Iterations . . . . . . . . . . . . . . . . . . . . . . 13
    4.1.4.  Salt Length  . . . . . . . . . . . . . . . . . . . . . 13
    4.1.5.  Salt . . . . . . . . . . . . . . . . . . . . . . . . . 13
  4.2.  NSEC3PARAM RDATA Wire Format . . . . . . . . . . . . . . . 13
  4.3.  Presentation Format  . . . . . . . . . . . . . . . . . . . 14
5.  Calculation of the Hash  . . . . . . . . . . . . . . . . . . . 14
6.  Opt-Out  . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
7.  Authoritative Server Considerations  . . . . . . . . . . . . . 16
  7.1.  Zone Signing . . . . . . . . . . . . . . . . . . . . . . . 16
  7.2.  Zone Serving . . . . . . . . . . . . . . . . . . . . . . . 17
    7.2.1.  Closest Encloser Proof . . . . . . . . . . . . . . . . 18
    7.2.2.  Name Error Responses . . . . . . . . . . . . . . . . . 19
    7.2.3.  No Data Responses, QTYPE is not DS . . . . . . . . . . 19
    7.2.4.  No Data Responses, QTYPE is DS . . . . . . . . . . . . 19
    7.2.5.  Wildcard No Data Responses . . . . . . . . . . . . . . 19
    7.2.6.  Wildcard Answer Responses  . . . . . . . . . . . . . . 20
    7.2.7.  Referrals to Unsigned Subzones . . . . . . . . . . . . 20
    7.2.8.  Responding to Queries for NSEC3 Owner Names  . . . . . 20
    7.2.9.  Server Response to a Run-Time Collision  . . . . . . . 21
  7.3.  Secondary Servers  . . . . . . . . . . . . . . . . . . . . 21
  7.4.  Zones Using Unknown Hash Algorithms  . . . . . . . . . . . 21
  7.5.  Dynamic Update . . . . . . . . . . . . . . . . . . . . . . 21
8.  Validator Considerations . . . . . . . . . . . . . . . . . . . 23
  8.1.  Responses with Unknown Hash Types  . . . . . . . . . . . . 23
  8.2.  Verifying NSEC3 RRs  . . . . . . . . . . . . . . . . . . . 23
  8.3.  Closest Encloser Proof . . . . . . . . . . . . . . . . . . 23
  8.4.  Validating Name Error Responses  . . . . . . . . . . . . . 24
  8.5.  Validating No Data Responses, QTYPE is not DS  . . . . . . 24
  8.6.  Validating No Data Responses, QTYPE is DS  . . . . . . . . 24
  8.7.  Validating Wildcard No Data Responses  . . . . . . . . . . 25
  8.8.  Validating Wildcard Answer Responses . . . . . . . . . . . 25
  8.9.  Validating Referrals to Unsigned Subzones  . . . . . . . . 25
9.  Resolver Considerations  . . . . . . . . . . . . . . . . . . . 26
  9.1.  NSEC3 Resource Record Caching  . . . . . . . . . . . . . . 26
  9.2.  Use of the AD Bit  . . . . . . . . . . . . . . . . . . . . 26
10. Special Considerations . . . . . . . . . . . . . . . . . . . . 26
  10.1. Domain Name Length Restrictions  . . . . . . . . . . . . . 26
  10.2. DNAME at the Zone Apex . . . . . . . . . . . . . . . . . . 27
  10.3. Iterations . . . . . . . . . . . . . . . . . . . . . . . . 27
  10.4. Transitioning a Signed Zone from NSEC to NSEC3 . . . . . . 28
  10.5. Transitioning a Signed Zone from NSEC3 to NSEC . . . . . . 28
11. IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 29
12. Security Considerations  . . . . . . . . . . . . . . . . . . . 30
  12.1. Hashing Considerations . . . . . . . . . . . . . . . . . . 30

    12.1.1. Dictionary Attacks . . . . . . . . . . . . . . . . . . 30
    12.1.2. Collisions . . . . . . . . . . . . . . . . . . . . . . 31
    12.1.3. Transitioning to a New Hash Algorithm  . . . . . . . . 31
    12.1.4. Using High Iteration Values  . . . . . . . . . . . . . 31
  12.2. Opt-Out Considerations . . . . . . . . . . . . . . . . . . 32
  12.3. Other Considerations . . . . . . . . . . . . . . . . . . . 33
13. References . . . . . . . . . . . . . . . . . . . . . . . . . . 33
  13.1. Normative References . . . . . . . . . . . . . . . . . . . 33
  13.2. Informative References . . . . . . . . . . . . . . . . . . 34
Appendix A.  Example Zone  . . . . . . . . . . . . . . . . . . . . 35
Appendix B.  Example Responses . . . . . . . . . . . . . . . . . . 40
  B.1.  Name Error . . . . . . . . . . . . . . . . . . . . . . . . 40
  B.2.  No Data Error  . . . . . . . . . . . . . . . . . . . . . . 42
    B.2.1.  No Data Error, Empty Non-Terminal  . . . . . . . . . . 43
  B.3.  Referral to an Opt-Out Unsigned Zone . . . . . . . . . . . 44
  B.4.  Wildcard Expansion . . . . . . . . . . . . . . . . . . . . 45
  B.5.  Wildcard No Data Error . . . . . . . . . . . . . . . . . . 46
  B.6.  DS Child Zone No Data Error  . . . . . . . . . . . . . . . 48
Appendix C.  Special Considerations  . . . . . . . . . . . . . . . 48
  C.1.  Salting  . . . . . . . . . . . . . . . . . . . . . . . . . 49
  C.2.  Hash Collision . . . . . . . . . . . . . . . . . . . . . . 49
    C.2.1.  Avoiding Hash Collisions During Generation . . . . . . 50
    C.2.2.  Second Preimage Requirement Analysis . . . . . . . . . 50

1. Introduction โœจ

1.1. Rationale

Okay so the DNS Security Extensions already included the NSEC RR to give us authenticated denial of existence ๐Ÿ’… The NSEC RR does meet the requirements for that, but it comes with a side-effect: the contents of a zone can be enumerated ๐Ÿ˜ฌ That creates some undesired policy issues, and nobody wants drama like that ๐Ÿ’€

Here's how the enumeration happens. The set of NSEC records inside a signed zone is what makes it possible. Each NSEC record lists two names that are ordered canonically, to show that nothing exists between those two names ๐Ÿงฉ Put the whole set of NSEC records together and you get every name in the zone. It's trivial to enumerate a zone just by querying for names that don't exist ๐Ÿ™ƒ

An enumerated zone can be used as a source of probable e-mail addresses for spam, or as a key for multiple WHOIS queries that reveal registrant data. Many registries may have legal obligations to protect that data ๐Ÿ˜ญ So a lot of registries prohibit copying their zone data. The catch is that using NSEC RRs makes those policies unenforceable ๐Ÿ™ˆ

There's a second problem too. The cost of cryptographically securing delegations to unsigned zones is high, relative to the security benefit people actually get. That's true in two cases: large, delegation-centric zones, and zones where insecure delegations get updated rapidly ๐ŸŒธ In those cases, the cost of maintaining the NSEC RR chain may be extremely high, and the "Opt-Out" convention may be more appropriate for those unsecured zones ๐Ÿฆ‹

This document presents the NSEC3 Resource Record, which can be used as an alternative to NSEC to deal with these issues ๐Ÿ’–

Earlier work tackling these issues includes [DNSEXT-NO], [RFC4956], and [DNSEXT-NSEC2v2] ๐Ÿงš

1.2. Requirements

Here's the key words bit, and it matters: the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] ๐ŸŽ€ Those capitalised words are the official strength-of-requirement labels, so read them carefully, bestie ๐Ÿ‘‘

That's the end of part 1 of 10 ๐Ÿ“œ

1.3. Terminology ๐Ÿ“š

okay so you're assumed to already know the basic DNS and DNSSEC stuff from [RFC1034], [RFC1035], [RFC4033], [RFC4034], [RFC4035], plus the later RFCs that update them: [RFC2136], [RFC2181], and [RFC2308]. ๐Ÿค“

here's the vocab we'll be using all over the place ๐Ÿ’…

  • Zone enumeration: finding out a zone's whole contents by making query after query. it was kinda tricky before DNSSEC showed up ๐Ÿ‘€
  • Original owner name: the owner name that goes with a hashed owner name. ๐Ÿ”
  • Hashed owner name: the owner name you get after running the hash function on an owner name. ๐Ÿง‚
  • Hash order: how hashed owner names are lined up by their numerical value, with the leftmost (lowest numbered) octet counting as the most significant octet. ๐Ÿ“ this order is the same as the canonical DNS name order from [RFC4034], as long as the hashed owner names are in base32 and encoded with an Extended Hex Alphabet [RFC4648]. iconic overlap ๐Ÿซถ
  • Empty non-terminal: a domain name that owns no resource records but has one or more subdomains that do. ๐ŸŒฑ
  • Delegation: an NS RRSet with a name that's different from the current zone apex (non-zone-apex), meaning it hands things off to a child zone. ๐ŸŽ€
  • Secure delegation: a name with a delegation (NS RRSet) AND a signed DS RRSet, which means it's handing off to a signed child zone. ๐Ÿ”
  • Insecure delegation: a name with a delegation (NS RRSet) but no DS RRSet, so the child zone is unsigned. ๐Ÿซฅ
  • Opt-Out NSEC3 resource record: an NSEC3 resource record that has the Opt-Out flag set to 1. ๐Ÿšฉ
  • Opt-Out zone: a zone with at least one Opt-Out NSEC3 RR. ๐ŸŒธ
  • Closest encloser: the longest existing ancestor of a name. also see Section 3.3.1 of [RFC4592]. ๐ŸŒณ
  • Closest provable encloser: the longest ancestor of a name that can be proven to exist. this only ends up different from the closest encloser in an Opt-Out zone, so it's a niche one ๐Ÿง
  • Next closer name: the name that's one label longer than the closest provable encloser of a name. ๐Ÿชœ
  • Base32: the "Base 32 Encoding with Extended Hex Alphabet" from [RFC4648]. quick heads up: trailing padding characters (=) are NOT used in the NSEC3 spec. ๐Ÿšซ
  • To cover: an NSEC3 RR "covers" a name if the hash of the name (or of its "next closer" name) falls between the NSEC3's owner name and the next hashed owner name. basically, it proves the name doesn't exist, either directly or by proving an ancestor of it doesn't exist. ๐Ÿซฃ
  • To match: an NSEC3 RR "matches" a name if the NSEC3's owner name is the same as that name's hashed owner name. ๐Ÿ’ฏ

2. Backwards Compatibility ๐ŸŽ€

okay this part's a little drama ๐Ÿ˜ญ this spec makes a protocol change that's NOT generally backwards compatible with [RFC4033], [RFC4034], and [RFC4035]. specifically, security-aware resolvers that don't know about this spec (NSEC3-unaware resolvers) might fail to validate the responses this document introduces. yikes ๐Ÿ’€

so to help with rollout, this spec uses a signaling trick to stop NSEC3-unaware resolvers from trying to validate responses from NSEC3-signed zones. clever, right? ๐Ÿง โœจ

this spec allocates two new DNSKEY algorithm identifiers for that purpose. algorithm 6, DSA-NSEC3-SHA1, is an alias for algorithm 3, DSA. algorithm 7, RSASHA1-NSEC3-SHA1, is an alias for algorithm 5, RSASHA1. and before anyone panics: these are NOT new algorithms, just extra identifiers for the algorithms that already exist ๐Ÿซถ

zones signed under this spec MUST only use these algorithm identifiers for their DNSKEY RRs. ๐Ÿ”’ since these new identifiers are unknown algorithms to existing NSEC3-unaware resolvers, those resolvers will treat responses from the NSEC3 signed zone as insecure, as detailed in Section 5.2 of [RFC4035]. so they just shrug and move on ๐Ÿคทโ€โ™€๏ธ

these algorithm identifiers get used with the NSEC3 hash algorithm SHA1. if you want to use other NSEC3 hash algorithms, you'll need to allocate a new alias (see Section 12.1.3). ๐Ÿงช

security aware resolvers that know about this spec MUST recognize the new algorithm identifiers and treat them as equivalent to the algorithms they alias. no excuses ๐Ÿ’…

if you're moving from a DNSSEC signed zone over to a zone signed with NSEC3, there's a whole methodology for that in Section 10.4. ๐Ÿฆ‹

3. The NSEC3 Resource Record ๐Ÿฆ‹

the NSEC3 Resource Record (RR) gives you authenticated denial of existence for DNS Resource Record Sets. aka it proves that stuff ISN'T there, securely ๐Ÿ™…โ€โ™€๏ธโœจ

the NSEC3 RR lists the RR types present at the original owner name of the NSEC3 RR. it also includes the next hashed owner name in the zone's hash order. put all the NSEC3 RRs in a zone together and they show which RRSets exist for each original owner name, forming a chain of hashed owner names through the zone. that info is what gives you authenticated denial of existence for DNS data ๐Ÿ”—

now for the zone enumeration protection ๐Ÿ•ต๏ธโ€โ™€๏ธ: the owner names used in NSEC3 RRs are cryptographic hashes of the original owner name, prepended as a single label to the zone's name. the NSEC3 RR also says which hash function was used, which salt was used, and how many iterations of the hash function were run over the original owner name. the full hashing technique is described in Section 5. ๐Ÿง‚

unsigned delegations' hashed owner names can be left out of the chain. an NSEC3 RR whose span covers the hash of an owner name or "next closer" name of an unsigned delegation is called an Opt-Out NSEC3 RR, and you can spot it because a flag is set. ๐Ÿšฉ

the owner name for an NSEC3 RR is the base32 encoding of the hashed owner name, prepended as a single label to the zone's name. ๐Ÿท๏ธ

the type value for the NSEC3 RR is 50. ๐Ÿ”ข

the NSEC3 RR RDATA format is class independent, and it's described below. ๐Ÿ“ฆ

the class MUST be the same as the class of the original owner name. no mixing and matching ๐Ÿ™…โ€โ™€๏ธ

the NSEC3 RR SHOULD have the same TTL value as the SOA minimum TTL field. this is in the spirit of negative caching [RFC2308]. ๐Ÿ•ฐ๏ธ

3.1. RDATA Fields ๐Ÿงฉ

3.1.1. Hash Algorithm ๐Ÿ”

the Hash Algorithm field tells you which cryptographic hash algorithm was used to build the hash-value. ๐Ÿงฎ

the values for this field are defined in the NSEC3 hash algorithm registry, which is defined in Section 11. ๐Ÿ“‹

3.1.2. Flags ๐Ÿšฉ

the Flags field holds 8 one-bit flags that can be used to signal different processing. all undefined flags must be zero. the only flag this spec defines is the Opt-Out flag. ๐Ÿซง

3.1.2.1. Opt-Out Flag ๐ŸŒ™

if the Opt-Out flag is set, the NSEC3 record covers zero or more unsigned delegations. ๐Ÿซถ

if the Opt-Out flag is clear, the NSEC3 record covers zero unsigned delegations. ๐Ÿ™…โ€โ™€๏ธ

the Opt-Out Flag tells you whether this NSEC3 RR may cover unsigned delegations. it's the least significant bit in the Flags field. see Section 6 for details on using this flag. ๐ŸŽฏ

3.1.3. Iterations ๐Ÿ”

the Iterations field defines how many additional times the hash function has been performed. more iterations mean the hash value is more resilient against dictionary attacks, BUT it costs more computing power for both the server and the resolver. see Section 5 for how this field is used, and Section 10.3 for the limits on its value. โš–๏ธ

3.1.4. Salt Length ๐Ÿ“

the Salt Length field defines the length of the Salt field in octets. the value ranges from 0 to 255. ๐Ÿ”ข

3.1.5. Salt ๐Ÿง‚

the Salt field gets appended to the original owner name before hashing, which helps defend against pre-calculated dictionary attacks. see Section 5 for how the salt is used. ๐Ÿ›ก๏ธ

3.1.6. Hash Length ๐Ÿ“

the Hash Length field defines the length of the Next Hashed Owner Name field. it ranges in value from 1 to 255 octets. ๐Ÿ“

3.1.7. Next Hashed Owner Name โžก๏ธ

the Next Hashed Owner Name field contains the next hashed owner name in hash order. this value is in binary format. given the ordered set of all hashed owner names, this field holds the hash of the owner name that immediately follows the owner name of the given NSEC3 RR. ๐Ÿ”— the value of this field in the LAST NSEC3 RR in the zone is the same as the hashed owner name of the FIRST NSEC3 RR in the zone in hash order. wrap-around energy ๐ŸŒ€ and note that, unlike the owner name of the NSEC3 RR, this field does NOT contain the appended zone name. ๐Ÿ™…โ€โ™€๏ธ

3.1.8. Type Bit Maps ๐Ÿ—บ๏ธ

the Type Bit Maps field identifies the RRSet types that exist at the original owner name of the NSEC3 RR. ๐Ÿ—‚๏ธ

3.2. NSEC3 RDATA Wire Format ๐Ÿ”Œ

the RDATA of the NSEC3 RR looks like this ๐Ÿ‘‡

                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Hash Alg.   |     Flags     |          Iterations           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Salt Length  |                     Salt                      /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Hash Length  |             Next Hashed Owner Name            /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/                         Type Bit Maps                         /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

the Hash Algorithm is a single octet. ๐Ÿ”ข

the Flags field is a single octet, and the Opt-Out flag is the least significant bit, like so ๐Ÿ‘‡

 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|             |O|
+-+-+-+-+-+-+-+-+

Iterations is represented as a 16-bit unsigned integer, with the most significant bit first. ๐Ÿ’–

Salt Length is represented as an unsigned octet, and it represents the length of the Salt field in octets. if the value is zero, the following Salt field is omitted entirely. ๐Ÿซฅ

Salt, if it's present, is encoded as a sequence of binary octets. the length of this field is determined by the preceding Salt Length field. ๐Ÿง‚

Hash Length is represented as an unsigned octet, and it represents the length of the Next Hashed Owner Name field in octets. ๐Ÿ“

the next hashed owner name is NOT base32 encoded, unlike the owner name of the NSEC3 RR. it's the unmodified binary hash value, and it does not include the name of the containing zone. the length of this field is determined by the preceding Hash Length field. ๐Ÿฆ‹

3.2.1. Type Bit Maps Encoding

okay so the Type Bit Maps encoding is the exact same one the NSEC RR uses, which is described in [RFC4034] ๐Ÿ’… it gets explained again here so it's crystal clear, no cap ๐ŸŽ€

The RR type space gets split into 256 window blocks ๐Ÿงš. Each block stands for the low-order 8 bits of the 16-bit RR type space. Every block that has at least one active RR type is encoded with a single octet window number (from 0 to 255), a single octet bitmap length (from 1 to 32) that tells you how many octets that block's bitmap uses, and up to 32 octets (256 bits) of bitmap ๐Ÿฆ‹

The blocks show up in the NSEC3 RR RDATA in increasing numerical order โœจ

      Type Bit Maps Field = ( Window Block # | Bitmap Length | Bitmap )+

      where "|" denotes concatenation.

Each bitmap encodes the low-order 8 bits of the RR types inside its window block, in network bit order ๐ŸŒธ The first bit is bit 0. For window block 0, bit 1 means RR type 1 (A), bit 2 means RR type 2 (NS), and so on. For window block 1, bit 1 means RR type 257 and bit 2 means RR type 258. If a bit is set to 1, an RRSet of that type exists for the original owner name of the NSEC3 RR. If a bit is set to 0, no RRSet of that type exists for that original owner name ๐Ÿ“

Bit 0 in window block 0 refers to RR type 0, which doesn't exist, so it MUST be set to 0. After verification, the validator MUST ignore the value of bit 0 in window block 0 ๐Ÿ™ˆ

Bits for Meta-TYPEs or QTYPEs (as specified in Section 3.1 of [RFC2929]), or for anything in the range reserved only for QTYPEs and Meta-TYPEs, MUST be set to 0, because they never show up in zone data. If you do run into one, they must be ignored upon reading ๐Ÿ’œ

Blocks with no types present MUST NOT be included. Trailing zero octets in the bitmap MUST be omitted. The length of each block's bitmap is decided by the highest numerical type code in that block, out of the RR types present at the original owner name of the NSEC3 RR. Any trailing octets that aren't specified MUST be interpreted as zero octets ๐ŸŽ€

3.3. Presentation Format

okay so here's how the RDATA portion looks when it's written out for humans ๐Ÿ‘‘

  • The Hash Algorithm field is written as an unsigned decimal integer. The value has a maximum of 255.
  • The Flags field is written as an unsigned decimal integer. The value has a maximum of 255.
  • The Iterations field is written as an unsigned decimal integer. The value is between 0 and 65535, inclusive.
  • The Salt Length field is not written out at all ๐Ÿ™ƒ
  • The Salt field is written as a sequence of case-insensitive hexadecimal digits, with no whitespace allowed inside the sequence. When the Salt Length field is 0, the Salt field is written as "-" (without the quotes) ๐ŸŒˆ
  • The Hash Length field is not written out at all.
  • The Next Hashed Owner Name field is written as an unpadded sequence of case-insensitive base32 digits, with no whitespace โœจ
  • The Type Bit Maps field is written as a sequence of RR type mnemonics. When a mnemonic isn't known, the TYPE representation from Section 5 of [RFC3597] MUST be used ๐Ÿฆ‹

4. The NSEC3PARAM Resource Record

the NSEC3PARAM RR is basically the cheat sheet ๐Ÿงš It holds the NSEC3 parameters (hash algorithm, flags, iterations, and salt) that authoritative servers need so they can work out hashed owner names. When an NSEC3PARAM RR sits at a zone apex, it signals that authoritative servers may use those parameters to pick a suitable set of NSEC3 RRs for negative responses. Validators and resolvers do NOT use the NSEC3PARAM RR, which is the part that's giving "server only" energy ๐Ÿ’…

If an NSEC3PARAM RR is at the apex of a zone and its Flags field is zero, then there MUST be an NSEC3 RR at every hashed owner name in the zone, using the same hash algorithm, iterations, and salt parameters. Basically, the zone MUST contain a complete set of NSEC3 RRs with those same hash algorithm, iterations, and salt parameters ๐Ÿ”ฅ

The owner name of the NSEC3PARAM RR is the name of the zone apex ๐ŸŽ€

The type value for the NSEC3PARAM RR is 51 โœจ

The NSEC3PARAM RR RDATA format doesn't depend on class, and it's described below. The class MUST be the same as the class of the NSEC3 RRs this RR refers to ๐Ÿ’–

4.1. RDATA Fields

the RDATA for this RR basically copies the first four fields from the NSEC3 RR ๐Ÿซถ

4.1.1. Hash Algorithm

The Hash Algorithm field identifies the cryptographic hash algorithm used to build the hash-value ๐ŸŒธ

The acceptable values are the same as the matching field in the NSEC3 RR ๐Ÿฆ‹

4.1.2. Flag Fields

The Opt-Out flag isn't used, so it's set to zero ๐Ÿ™ˆ

All of the other flags are reserved for future use and must be zero ๐Ÿ’…

NSEC3PARAM RRs with a Flags field value other than zero MUST be ignored. Bye bye ๐Ÿ‘‹

4.1.3. Iterations

The Iterations field says how many extra times the hash gets run ๐Ÿ“

Its acceptable values are the same as the matching field in the NSEC3 RR ๐ŸŒˆ

4.1.4. Salt Length

The Salt Length field defines how long the salt is in octets, from 0 to 255 ๐Ÿ’œ

4.1.5. Salt

The Salt field gets appended to the original owner name before hashing ๐Ÿงš

4.2. NSEC3PARAM RDATA Wire Format

the RDATA of the NSEC3PARAM RR looks like this on the wire ๐ŸŽ€

                        1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |   Hash Alg.   |     Flags     |          Iterations           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Salt Length  |                     Salt                      /
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Hash Algorithm is a single octet ๐ŸŒธ

The Flags field is a single octet ๐Ÿฆ‹

Iterations is a 16-bit unsigned integer, with the most significant bit first ๐Ÿ™ˆ

Salt Length is an unsigned octet. It tells you how long the Salt field that follows is, in octets. If the value is zero, the Salt field gets left out entirely ๐Ÿ“

If it's present, the Salt is a sequence of binary octets, and its length is set by the Salt Length field right before it ๐ŸŒˆ

4.3. Presentation Format

the presentation format of the RDATA portion goes like this ๐Ÿ’œ

  • The Hash Algorithm field is written as an unsigned decimal integer. The value has a maximum of 255.
  • The Flags field is written as an unsigned decimal integer. The value has a maximum value of 255.
  • The Iterations field is written as an unsigned decimal integer. The value is between 0 and 65535, inclusive.
  • The Salt Length field is not written out at all ๐Ÿงš
  • The Salt field is written as a sequence of case-insensitive hexadecimal digits, with no whitespace allowed inside the sequence. It's written as "-" (without the quotes) when the Salt Length field is zero ๐ŸŽ€

5. Calculation of the Hash

the hash calculation uses three of the NSEC3 RDATA fields: Hash Algorithm, Salt, and Iterations โœจ

Let H(x) be the hash of x, using the Hash Algorithm picked by the NSEC3 RR. Let k be the number of Iterations, and let || mean concatenation. Then define:

      IH(salt, x, 0) = H(x || salt), and

      IH(salt, x, k) = H(IH(salt, x, k-1) || salt), if k > 0

Then the calculated hash of an owner name is

      IH(salt, owner name, iterations),

where the owner name is in canonical form ๐Ÿ’– The canonical form is the wire format of the owner name, with these rules:

  1. The owner name is fully expanded (no DNS name compression) and fully qualified ๐ŸŒธ
  2. All uppercase US-ASCII letters get swapped for their lowercase US-ASCII versions ๐Ÿฆ‹
  3. If the owner name is a wildcard name, it stays in its original unexpanded form, including the "*" label. No wildcard substitution happens here ๐Ÿ™ˆ

This form is defined in Section 6.2 of [RFC4034] ๐Ÿ“

The method for calculating the Hash is based on [RFC2898] ๐ŸŒˆ


6. Opt-Out

in this spec, just like in [RFC4033], [RFC4034] and [RFC4035], NS RRSets at delegation points are not signed, and they might come with a DS RRSet ๐Ÿ’… With the Opt-Out bit clear, the security status of the child zone depends on whether that DS RRSet is there or not, and that's proven by the signed NSEC3 RR at the hashed owner name of the delegation. Setting the Opt-Out flag changes this a bit: it lets insecure delegations exist inside the signed zone without a matching NSEC3 RR at the hashed owner name of the delegation ๐Ÿ”ฅ

An Opt-Out NSEC3 RR is said to cover a delegation when the hash of the delegation's owner name, or its "next closer" name, falls between the NSEC3 RR's owner name and its next hashed owner name ๐Ÿฆ‹

An Opt-Out NSEC3 RR doesn't assert whether the insecure delegations it covers exist or don't exist. That means delegations can be added or removed without recalculating or re-signing the NSEC3 RR chain ๐Ÿงš However, Opt-Out NSEC3 RRs do assert the (non)existence of other authoritative RRSets ๐ŸŽ€

An Opt-Out NSEC3 RR MAY have the same original owner name as an insecure delegation. In that case, the delegation is proven insecure by the lack of a DS bit in the type map, and the signed NSEC3 RR does assert that the delegation exists ๐ŸŒธ

Zones using Opt-Out MAY contain a mix of Opt-Out NSEC3 RRs and non-Opt-Out NSEC3 RRs ๐Ÿ’– If an NSEC3 RR is not Opt-Out, there MUST NOT be any hashed owner names of insecure delegations (or any other RRs) between it and the name given by the next hashed owner name in the NSEC3 RDATA. If it IS Opt-Out, it MUST only cover hashed owner names or hashed "next closer" names of insecure delegations ๐Ÿซถ

How the Opt-Out flag affects signing, serving, and validating responses is covered in the following sections ๐Ÿ‘‘


7. Authoritative Server Considerations โœจ

7.1. Zone Signing ๐Ÿง

Okay bestie, zones using NSEC3 have to hit these properties, no exceptions ๐Ÿ’…

  • Each owner name within the zone that owns authoritative RRSets MUST have a corresponding NSEC3 RR. Owner names that correspond to unsigned delegations MAY have a corresponding NSEC3 RR. However, if there is not a corresponding NSEC3 RR, there MUST be an Opt-Out NSEC3 RR that covers the "next closer" name to the delegation. Other non-authoritative RRs are not represented by NSEC3 RRs. ๐ŸŒธ
  • Each empty non-terminal MUST have a corresponding NSEC3 RR, unless the empty non-terminal is only derived from an insecure delegation covered by an Opt-Out NSEC3 RR. ๐Ÿฆ‹
  • The TTL value for any NSEC3 RR SHOULD be the same as the minimum TTL value field in the zone SOA RR. โœจ
  • The Type Bit Maps field of every NSEC3 RR in a signed zone MUST indicate the presence of all types present at the original owner name, except for the types solely contributed by an NSEC3 RR itself. Note that this means that the NSEC3 type itself will never be present in the Type Bit Maps. ๐Ÿ™ˆ

The following steps show one way to build NSEC3 RRs properly. It's not the only way, but it's a really good one ๐ŸŽ€

  1. Select the hash algorithm and the values for salt and iterations.
  2. For each unique original owner name in the zone, add an NSEC3 RR.
    • If Opt-Out is being used, owner names of unsigned delegations MAY be excluded.
    • The owner name of the NSEC3 RR is the hash of the original owner name, prepended as a single label to the zone name.
    • The Next Hashed Owner Name field is left blank for the moment.
    • If Opt-Out is being used, set the Opt-Out bit to one.
    • For collision detection purposes, optionally keep track of the original owner name with the NSEC3 RR.
    • Additionally, for collision detection purposes, optionally create an additional NSEC3 RR corresponding to the original owner name with the asterisk label prepended (i.e., as if a wildcard existed as a child of this owner name) and keep track of this original owner name. Mark this NSEC3 RR as temporary. ๐Ÿงš
  3. For each RRSet at the original owner name, set the corresponding bit in the Type Bit Maps field.
  4. If the difference in number of labels between the apex and the original owner name is greater than 1, additional NSEC3 RRs need to be added for every empty non-terminal between the apex and the original owner name. This process may generate NSEC3 RRs with duplicate hashed owner names. Optionally, for collision detection, track the original owner names of these NSEC3 RRs and create temporary NSEC3 RRs for wildcard collisions in a similar fashion to step 1.
  5. Sort the set of NSEC3 RRs into hash order.
  6. Combine NSEC3 RRs with identical hashed owner names by replacing them with a single NSEC3 RR with the Type Bit Maps field consisting of the union of the types represented by the set of NSEC3 RRs. If the original owner name was tracked, then collisions may be detected when combining, as all of the matching NSEC3 RRs should have the same original owner name. Discard any possible temporary NSEC3 RRs. ๐Ÿ’–
  7. In each NSEC3 RR, insert the next hashed owner name by using the value of the next NSEC3 RR in hash order. The next hashed owner name of the last NSEC3 RR in the zone contains the value of the hashed owner name of the first NSEC3 RR in the hash order. ๐Ÿ”„
  8. Finally, add an NSEC3PARAM RR with the same Hash Algorithm, Iterations, and Salt fields to the zone apex. ๐Ÿ‘‘

If a hash collision is detected, then a new salt has to be chosen, and the signing process restarted. ๐Ÿ’€


7.2. Zone Serving ๐ŸŒˆ

This spec changes DNSSEC-enabled DNS responses that authoritative servers generate. Specifically, it swaps out NSEC RRs in those responses for NSEC3 RRs. ๐Ÿ’…

In the following response cases, the NSEC RRs dictated by DNSSEC [RFC4035] are replaced with NSEC3 RRs that prove the same facts. Responses that would not contain NSEC RRs are unchanged by this specification. ๐Ÿซถ

When returning responses containing multiple NSEC3 RRs, all of the NSEC3 RRs MUST use the same hash algorithm, iteration, and salt values. The Flags field value MUST be either zero or one. โœจ

7.2.1. Closest Encloser Proof ๐Ÿ”

For a lot of NSEC3 responses, you need a proof of the closest encloser. This is proof that some ancestor of the QNAME is the closest encloser of QNAME. ๐Ÿ’œ

This proof is made of (up to) two different NSEC3 RRs:

  • An NSEC3 RR that matches the closest (provable) encloser.
  • An NSEC3 RR that covers the "next closer" name to the closest encloser.

The first NSEC3 RR basically suggests a possible closest encloser, and proves that this encloser really does exist. The second NSEC3 RR proves that the possible closest encloser is the closest one, and proves that the QNAME (and any ancestors between QNAME and the closest encloser) does not exist. ๐Ÿฆ‹

These NSEC3 RRs are collectively called the "closest encloser proof" in the rest of the write-up. ๐ŸŽ€

For example, the closest encloser proof for the nonexistent alpha.beta.gamma.example. owner name might prove that gamma.example. is the closest encloser. This response would contain the NSEC3 RR that matches gamma.example., and would also contain the NSEC3 RR that covers beta.gamma.example. (which is the "next closer" name). ๐Ÿ“

When using Opt-Out (Section 6), you might not be able to prove the actual closest encloser, because it is, or is part of, an insecure delegation covered by an Opt-Out span. In that case, instead of proving the actual closest encloser, the closest provable encloser is used. That is, the closest enclosing authoritative name is used instead. In this case, the set of NSEC3 RRs used for this proof is called the "closest provable encloser proof". ๐ŸŒธ

7.2.2. Name Error Responses ๐Ÿ™…โ€โ™€๏ธ

To prove that QNAME doesn't exist, a closest encloser proof and an NSEC3 RR covering the (nonexistent) wildcard RR at the closest encloser MUST be included in the response. This group of (up to) three NSEC3 RRs proves both that QNAME does not exist and that a wildcard that could have matched QNAME also does not exist. ๐Ÿ˜ญ

For example, if gamma.example. is the closest provable encloser to QNAME, then an NSEC3 RR covering *.gamma.example. is included in the authority section of the response. ๐Ÿงš

7.2.3. No Data Responses, QTYPE is not DS ๐Ÿ™ˆ

The server MUST include the NSEC3 RR that matches QNAME. This NSEC3 RR MUST NOT have the bits corresponding to either the QTYPE or CNAME set in its Type Bit Maps field. ๐Ÿ’…

7.2.4. No Data Responses, QTYPE is DS ๐Ÿ”

If there is an NSEC3 RR that matches QNAME, the server MUST return it in the response. The bits corresponding with DS and CNAME MUST NOT be set in the Type Bit Maps field of this NSEC3 RR. ๐Ÿซถ

If no NSEC3 RR matches QNAME, the server MUST return a closest provable encloser proof for QNAME. The NSEC3 RR that covers the "next closer" name MUST have the Opt-Out bit set (note that this is true by definition -- if the Opt-Out bit is not set, something has gone wrong). ๐Ÿ’€

If a server is authoritative for both sides of a zone cut at QNAME, the server MUST return the proof from the parent side of the zone cut. ๐Ÿ‘‘

7.2.5. Wildcard No Data Responses ๐Ÿƒ

If there is a wildcard match for QNAME, but QTYPE is not present at that name, the response MUST include a closest encloser proof for QNAME and MUST include the NSEC3 RR that matches the wildcard. This combo proves both that QNAME itself does not exist and that a wildcard that matches QNAME does exist. Note that the closest encloser to QNAME MUST be the immediate ancestor of the wildcard RR (if this is not the case, then something has gone wrong). ๐ŸŒˆ

7.2.6. Wildcard Answer Responses ๐ŸŽฏ

If there is a wildcard match for QNAME and QTYPE, then, in addition to the expanded wildcard RRSet returned in the answer section of the response, proof that the wildcard match was valid must be returned. โœจ

This proof works by showing that QNAME does not exist and that the closest encloser of the QNAME and the immediate ancestor of the wildcard are the same (i.e., the correct wildcard matched). ๐Ÿ”

To do this, the NSEC3 RR that covers the "next closer" name of the immediate ancestor of the wildcard MUST be returned. It is not necessary to return an NSEC3 RR that matches the closest encloser, because the existence of that closest encloser is already proven by the expanded wildcard in the response. ๐Ÿฆ‹

7.2.7. Referrals to Unsigned Subzones ๐Ÿ“ฌ

If there is an NSEC3 RR that matches the delegation name, then that NSEC3 RR MUST be included in the response. The DS bit in the type bit maps of the NSEC3 RR MUST NOT be set. ๐ŸŽ€

If the zone is Opt-Out, then there may not be an NSEC3 RR corresponding to the delegation. In this case, the closest provable encloser proof MUST be included in the response. The included NSEC3 RR that covers the "next closer" name for the delegation MUST have the Opt-Out flag set to one. (Note that this will be the case unless something has gone wrong). ๐Ÿ“

7.2.8. Responding to Queries for NSEC3 Owner Names ๐Ÿชž

The owner names of NSEC3 RRs are not represented in the NSEC3 RR chain like other owner names. As a result, each NSEC3 owner name is covered by another NSEC3 RR, which effectively negates the existence of the NSEC3 RR. It's a paradox, since the existence of an NSEC3 RR can be proven by its RRSIG RRSet. ๐Ÿคฏ

If the following conditions are all true:

  • the QNAME equals the owner name of an existing NSEC3 RR, and
  • no RR types exist at the QNAME, nor at any descendant of QNAME,

then the response MUST be constructed as a Name Error response (Section 7.2.2). In other words, the authoritative name server will act as if the owner name of the NSEC3 RR did not exist. ๐Ÿ‘ป

Note that NSEC3 RRs are returned as a result of an AXFR or IXFR query. ๐ŸŒธ

7.2.9. Server Response to a Run-Time Collision ๐Ÿ’ฅ

If the hash of a non-existing QNAME collides with the owner name of an existing NSEC3 RR, then the server will be unable to return a response that proves that QNAME does not exist. In this case, the server MUST return a response with an RCODE of 2 (server failure). ๐Ÿ˜ฑ

Note that with the hash algorithm specified in this document, SHA-1, such collisions are highly unlikely. ๐Ÿซง

7.3. Secondary Servers ๐Ÿ›‹๏ธ

Secondary servers (and maybe other entities) need to reliably figure out which NSEC3 parameters (i.e., hash, salt, and iterations) are present at every hashed owner name, so they can choose the right set of NSEC3 RRs for negative responses. This is indicated by an NSEC3PARAM RR present at the zone apex. ๐Ÿ’œ

If there are multiple NSEC3PARAM RRs present, there are multiple valid NSEC3 chains present. The server must choose one of them, but may use any criteria to do so. ๐ŸŽฒ

7.4. Zones Using Unknown Hash Algorithms ๐Ÿšซ

Zones that are signed according to this specification, but use an unrecognized NSEC3 hash algorithm value, cannot be effectively served. Such zones SHOULD be rejected when loading. Servers SHOULD respond with RCODE=2 (server failure) responses when handling queries that would fall under such zones. ๐Ÿ™ƒ

7.5. Dynamic Update ๐ŸŽ€

okay so a zone signed using NSEC3 may accept dynamic updates [RFC2136] ๐Ÿ’… but NSEC3 brings some extra drama for updates, so pay attention bestie ๐Ÿซถ

Adding and removing names in a zone MUST account for the creation or removal of empty non-terminals ๐ŸŒธ

  • When removing a name with a corresponding NSEC3 RR, any NSEC3 RRs corresponding to empty non-terminals created by that name MUST be removed. Note that more than one name may be asserting the existence of a particular empty non-terminal. ๐Ÿ™ˆ
  • When adding a name that requires adding an NSEC3 RR, NSEC3 RRs MUST also be added for any empty non-terminals that are created. That is, if there is not an existing NSEC3 RR matching an empty non-terminal, it must be created and added. โœจ

The presence of Opt-Out in a zone means that some additions or delegations of names will not require changes to the NSEC3 RRs in a zone ๐Ÿฆ‹

  • When removing a delegation RRSet, if that delegation does not have a matching NSEC3 RR, then it was opted out. In this case, nothing further needs to be done. ๐Ÿ’œ
  • When adding a delegation RRSet, if the "next closer" name of the delegation is covered by an existing Opt-Out NSEC3 RR, then the delegation MAY be added without modifying the NSEC3 RRs in the zone. ๐Ÿงš

The presence of Opt-Out in a zone also means that when adding or removing NSEC3 RRs, the value of the Opt-Out flag that should be set in new or modified NSEC3 RRs is ambiguous ๐Ÿค” Servers SHOULD follow this set of basic rules to resolve the ambiguity ๐Ÿ‘‘

The central concept to these rules is that the state of the Opt-Out flag of the covering NSEC3 RR is preserved. โœจ

  • When removing an NSEC3 RR, the value of the Opt-Out flag for the previous NSEC3 RR (the one whose next hashed owner name is modified) should not be changed. ๐ŸŒˆ
  • When adding an NSEC3 RR, the value of the Opt-Out flag is set to the value of the Opt-Out flag of the NSEC3 RR that previously covered the owner name of the NSEC3 RR. That is, the now previous NSEC3 RR. ๐Ÿ’…

If the zone in question is consistent with its use of the Opt-Out flag (that is, all NSEC3 RRs in the zone have the same value for the flag) then these rules will retain that consistency. If the zone is not consistent in the use of the flag (i.e., a partially Opt-Out zone), then these rules will not retain the same pattern of use of the Opt-Out flag. ๐Ÿ˜ญ

For zones that partially use the Opt-Out flag, if there is a logical pattern for that use, the pattern could be maintained by using a local policy on the server. ๐Ÿ“


8. Validator Considerations ๐Ÿฆ‹

8.1. Responses with Unknown Hash Types ๐Ÿ™ˆ

A validator MUST ignore NSEC3 RRs with unknown hash types. The practical result of this is that responses containing only such NSEC3 RRs will generally be considered bogus. ๐Ÿ’€

8.2. Verifying NSEC3 RRs โœจ

A validator MUST ignore NSEC3 RRs with a Flag fields value other than zero or one. ๐Ÿงš

A validator MAY treat a response as bogus if the response contains NSEC3 RRs that contain different values for hash algorithm, iterations, or salt from each other for that zone. ๐Ÿ‘€

8.3. Closest Encloser Proof ๐Ÿ’œ

In order to verify a closest encloser proof, the validator MUST find the longest name, X, such that:

  • X is an ancestor of QNAME that is matched by an NSEC3 RR present in the response. This is a candidate for the closest encloser, and
  • The name one label longer than X (but still an ancestor of -- or equal to -- QNAME) is covered by an NSEC3 RR present in the response.

One possible algorithm for verifying this proof is as follows ๐ŸŒธ

  1. Set SNAME=QNAME. Clear the flag.
  2. Check whether SNAME exists:
    • If there is no NSEC3 RR in the response that matches SNAME (i.e., an NSEC3 RR whose owner name is the same as the hash of SNAME, prepended as a single label to the zone name), clear the flag.
    • If there is an NSEC3 RR in the response that covers SNAME, set the flag.
    • If there is a matching NSEC3 RR in the response and the flag was set, then the proof is complete, and SNAME is the closest encloser.
    • If there is a matching NSEC3 RR in the response, but the flag is not set, then the response is bogus.
  3. Truncate SNAME by one label from the left, go to step 2.

Once the closest encloser has been discovered, the validator MUST check that the NSEC3 RR that has the closest encloser as the original owner name is from the proper zone. The DNAME type bit must not be set and the NS type bit may only be set if the SOA type bit is set. If this is not the case, it would be an indication that an attacker is using them to falsely deny the existence of RRs for which the server is not authoritative. ๐Ÿšจ

Yikes! If that check fails, somebody could be sneakily using these bits to make RRs look like they don't exist when the server isn't even authoritative for them. Not cute. ๐Ÿ˜ค

In the following descriptions, the phrase "a closest (provable) encloser proof for X" means that the algorithm above (or an equivalent algorithm) proves that X does not exist by proving that an ancestor of X is its closest encloser. ๐Ÿฆ‹

8.4. Validating Name Error Responses ๐Ÿ’…

A validator MUST verify that there is a closest encloser proof for QNAME present in the response and that there is an NSEC3 RR that covers the wildcard at the closest encloser (i.e., the name formed by prepending the asterisk label to the closest encloser). ๐Ÿซถ

8.5. Validating No Data Responses, QTYPE is not DS ๐ŸŒˆ

The validator MUST verify that an NSEC3 RR that matches QNAME is present and that both the QTYPE and the CNAME type are not set in its Type Bit Maps field. โœจ

Note that this test also covers the case where the NSEC3 RR exists because it corresponds to an empty non-terminal, in which case the NSEC3 RR will have an empty Type Bit Maps field. ๐Ÿงš

8.6. Validating No Data Responses, QTYPE is DS ๐Ÿ‘‘

If there is an NSEC3 RR that matches QNAME present in the response, then that NSEC3 RR MUST NOT have the bits corresponding to DS and CNAME set in its Type Bit Maps field. ๐Ÿ™ˆ

If there is no such NSEC3 RR, then the validator MUST verify that a closest provable encloser proof for QNAME is present in the response, and that the NSEC3 RR that covers the "next closer" name has the Opt-Out bit set. ๐Ÿ’œ

8.7. Validating Wildcard No Data Responses ๐Ÿ“

The validator MUST verify a closest encloser proof for QNAME and MUST find an NSEC3 RR present in the response that matches the wildcard name generated by prepending the asterisk label to the closest encloser. Furthermore, the bits corresponding to both QTYPE and CNAME MUST NOT be set in the wildcard matching NSEC3 RR. ๐ŸŒธ

8.8. Validating Wildcard Answer Responses ๐Ÿฆ‹

The verified wildcard answer RRSet in the response provides the validator with a (candidate) closest encloser for QNAME. This closest encloser is the immediate ancestor to the generating wildcard. ๐Ÿงš

Validators MUST verify that there is an NSEC3 RR that covers the "next closer" name to QNAME present in the response. This proves that QNAME itself did not exist and that the correct wildcard was used to generate the response. ๐Ÿ’–

8.9. Validating Referrals to Unsigned Subzones ๐ŸŒˆ

The delegation name in a referral is the owner name of the NS RRSet present in the authority section of the referral response. ๐ŸŽ€

If there is an NSEC3 RR present in the response that matches the delegation name, then the validator MUST ensure that the NS bit is set and that the DS bit is not set in the Type Bit Maps field of the NSEC3 RR. The validator MUST also ensure that the NSEC3 RR is from the correct (i.e., parent) zone. This is done by ensuring that the SOA bit is not set in the Type Bit Maps field of this NSEC3 RR. ๐Ÿ‘‘

Note that the presence of an NS bit implies the absence of a DNAME bit, so there is no need to check for the DNAME bit in the Type Bit Maps field of the NSEC3 RR. ๐Ÿง 

If there is no NSEC3 RR present that matches the delegation name, then the validator MUST verify a closest provable encloser proof for the delegation name. The validator MUST verify that the Opt-Out bit is set in the NSEC3 RR that covers the "next closer" name to the delegation name. ๐Ÿ’…


9. Resolver Considerations ๐Ÿงš

9.1. NSEC3 Resource Record Caching ๐Ÿ’œ

Caching resolvers MUST be able to retrieve the appropriate NSEC3 RRs when returning responses that contain them. In DNSSEC [RFC4035], in many cases it is possible to find the correct NSEC RR to return in a response by name (e.g., when returning a referral, the NSEC RR will always have the same owner name as the delegation). With this specification, that will not be true, nor will a cache be able to calculate the name(s) of the appropriate NSEC3 RR(s). Implementations may need to use new methods for caching and retrieving NSEC3 RRs. ๐Ÿซถ

9.2. Use of the AD Bit ๐Ÿ”ฅ

The AD bit, as defined by [RFC4035], MUST NOT be set when returning a response containing a closest (provable) encloser proof in which the NSEC3 RR that covers the "next closer" name has the Opt-Out bit set. ๐Ÿ™ˆ

This rule is based on what this closest encloser proof actually proves: names that would be covered by the Opt-Out NSEC3 RR may or may not exist as insecure delegations. As such, not all the data in responses containing such closest encloser proofs will have been cryptographically verified, so the AD bit cannot be set. ๐ŸŒธ


10. Special Considerations ๐Ÿ‘‘

10.1. Domain Name Length Restrictions โœจ

Zones signed using this specification have additional domain name length restrictions imposed upon them. In particular, zones with names that, when converted into hashed owner names exceed the 255 octet length limit imposed by [RFC1035], cannot use this specification. ๐ŸŒˆ

The actual maximum length of a domain name in a particular zone depends on both the length of the zone name (versus the whole domain name) and the particular hash function used. ๐Ÿงš

As an example, SHA-1 produces a hash of 160 bits. The base-32 encoding of 160 bits results in 32 characters. The 32 characters are prepended to the name of the zone as a single label, which includes a length field of a single octet. The maximum length of the zone name, when using SHA-1, is 222 octets (255 - 33). ๐ŸŽ€

10.2. DNAME at the Zone Apex ๐Ÿฆ‹

The DNAME specification in Section 3 of [RFC2672] has a 'no-descendants' limitation. If a DNAME RR is present at node N, there MUST be no data at any descendant of N. ๐Ÿ’…

If N is the apex of the zone, there will be NSEC3 and RRSIG types present at descendants of N. This specification updates the DNAME specification to allow NSEC3 and RRSIG types at descendants of the apex regardless of the existence of DNAME at the apex. ๐Ÿ’–

10.3. Iterations ๐Ÿ”ข

okay so the number of iterations is how the zone owner picks how expensive it is to hash a name, and that means how expensive it is to build a dictionary of names ๐Ÿ’ธ. this is totally different from salt! salt is what stops anyone from reusing one precomputed dictionary forever ๐Ÿง‚

obviously the iteration count also affects the zone owner's cost of signing and serving the zone, plus the validator's cost of verifying responses from it ๐Ÿ˜ค. so there's an upper limit. it's based on the number of iterations that roughly costs the same as verifying an RRSet โœจ

the limits are based on the size of the smallest zone signing key, rounded up to the nearest table value (or rounded down if the key is bigger than the biggest table value) ๐ŸŽ€

A zone owner MUST NOT use a value higher than shown in the table below for iterations for the given key size. A resolver MAY treat a response with a higher value as insecure, after the validator has verified that the signature over the NSEC3 RR is correct. ๐Ÿšซ

                     +----------+------------+
                     | Key Size | Iterations |
                     +----------+------------+
                     | 1024     | 150        |
                     | 2048     | 500        |
                     | 4096     | 2,500      |
                     +----------+------------+

this table is based on an approximation of the ratio between the cost of an SHA-1 calculation and the cost of an RSA verification. for 1024 bit keys that's 150 to 1, for 2048 bit keys it's 500 to 1, and for 4096 bit keys it's 2500 to 1 ๐Ÿ“Š

the ratio between SHA-1 calculation and DSA verification is even higher, 1500 to 1 for 1024 bit keys ๐Ÿ‘€. a higher iteration count hurts performance, and DSA verification is already more expensive than RSA at the same key size. so the values in the table MUST be used independent of the key algorithm ๐Ÿ’…


10.4. Transitioning a Signed Zone from NSEC to NSEC3 ๐Ÿ”„

when you're moving an already signed and trusted zone over to this spec, you have to be careful so clients don't start failing validation halfway through ๐Ÿ˜ฌ

here's the basic procedure:

  1. Transition all DNSKEYs to DNSKEYs using the algorithm aliases described in Section 2. The actual method for safely and securely changing the DNSKEY RRSet of the zone is outside the scope of this specification. However, the end result MUST be that all DS RRs in the parent use the specified algorithm aliases.

once that transition is done, all NSEC3-unaware clients will treat the zone as insecure. at this point the authoritative server still returns negative and wildcard responses that contain NSEC RRs ๐Ÿซ 

  1. Add signed NSEC3 RRs to the zone, either incrementally or all at once. If adding incrementally, then the last RRSet added MUST be the NSEC3PARAM RRSet.
  2. Once the NSEC3PARAM RRSet is added, the server switches to serving negative and wildcard responses with NSEC3 RRs according to this specification ๐ŸŽ‰
  3. Remove the NSEC RRs, either incrementally or all at once ๐Ÿงน

10.5. Transitioning a Signed Zone from NSEC3 to NSEC ๐Ÿ”™

wanna safely go back to a DNSSEC [RFC4035] signed zone? just run the procedure above in reverse ๐Ÿชž

  1. Add NSEC RRs incrementally or all at once.
  2. Remove the NSEC3PARAM RRSet. This signals the server to use the NSEC RRs for negative and wildcard responses ๐Ÿšฆ
  3. Remove the NSEC3 RRs, either incrementally or all at once.
  4. Transition all of the DNSKEYs to DNSSEC algorithm identifiers. Once that's done, all NSEC3-unaware clients will treat the zone as secure ๐Ÿ”

11. IANA Considerations ๐Ÿฆ‹

okay so the NSEC3 and NSEC3PARAM RR formats both have a hash algorithm parameter, but this document doesn't define a specific way to safely switch from one NSEC3 hash algorithm to another. so if you ever specify a new hash algorithm for NSEC3, you MUST also define a transition mechanism for it ๐Ÿ› ๏ธ

this document updates the IANA registry "DOMAIN NAME SYSTEM PARAMETERS" (http://www.iana.org/assignments/dns-parameters) in the sub-registry "TYPES" by defining two new types ๐ŸŽ€. Section 3 defines the NSEC3 RR type 50, and Section 4 defines the NSEC3PARAM RR type 51.

it also updates the IANA registry "DNS SECURITY ALGORITHM NUMBERS -- per [RFC4035]" (http://www.iana.org/assignments/dns-sec-alg-numbers). Section 2 defines the aliases DSA-NSEC3-SHA1 (6) and RSASHA1-NSEC3-SHA1 (7). those are for the existing DSA and RSASHA1 registrations when they're combined with the NSEC3 hash algorithm SHA1 ๐Ÿ”—

since these algorithm numbers are aliases for existing DNSKEY algorithm numbers, the flags that exist for the original algorithm are valid for the alias algorithm too ๐Ÿ’œ

this document creates a new IANA registry for NSEC3 flags, called "DNSSEC NSEC3 Flags". its initial contents are:

     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   |   |   |   |   |   |   |   |Opt|
   |   |   |   |   |   |   |   |Out|
   +---+---+---+---+---+---+---+---+

bit 7 is the Opt-Out flag.

bits 0 - 6 are available for assignment.

assigning more NSEC3 flags in this registry requires IETF Standards Action [RFC2434] ๐Ÿ“œ

this document also creates a new IANA registry for NSEC3PARAM flags, called "DNSSEC NSEC3PARAM Flags". its initial contents are:

     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   |   |   |   |   |   |   |   | 0 |
   +---+---+---+---+---+---+---+---+

bit 7 is reserved and must be 0.

bits 0 - 6 are available for assignment.

assigning more NSEC3PARAM flags in this registry requires IETF Standards Action [RFC2434] too ๐Ÿ™ƒ

last one! this document creates a new IANA registry for NSEC3 hash algorithms, called "DNSSEC NSEC3 Hash Algorithms". its initial contents are:

   0 is Reserved.

   1 is SHA-1.

   2-255 Available for assignment.

assigning more NSEC3 hash algorithms in this registry requires IETF Standards Action [RFC2434] ๐ŸŒˆ


12. Security Considerations ๐Ÿ’€

this part is the serious one, bestie, so read it with your whole chest ๐Ÿซถ

12.1. Hashing Considerations ๐Ÿง‚

12.1.1. Dictionary Attacks ๐Ÿ“–

NSEC3 RRs can still be hit with dictionary attacks. the attacker grabs all the NSEC3 RRs, hashes every likely domain name, compares those hashes against the ones in the NSEC3 RRs, and basically enumerates the zone ๐Ÿ˜ฑ. these attacks are way more expensive than enumerating the original NSEC RRs would've been. and honestly, the same attack could also be run straight against the name server by querying for every likely name, though that would be a lot more detectable ๐Ÿ‘€. the cost of this off-line attack can be tuned by setting the number of iterations in the NSEC3 RR ๐ŸŽš๏ธ

zones are also open to a pre-calculated dictionary attack. that means a list of hashes for all likely names gets computed once, and then NSEC3 RRs are scanned on a regular basis and compared against those precomputed hashes ๐Ÿ—‚๏ธ. changing the salt on a regular basis is how you stop that one ๐Ÿง‚

The salt SHOULD be at least 64 bits long and unpredictable, so that an attacker cannot anticipate the value of the salt and compute the next set of dictionaries before the zone is published ๐Ÿ”ฎ

12.1.2. Collisions ๐Ÿ’ฅ

hash collisions between QNAME and the owner name of an NSEC3 RR might happen. when they do, it's impossible to prove the non-existence of the colliding QNAME. however, with SHA-1 this is highly unlikely, on the order of 1 in 2^160 ๐ŸŽฒ. note that DNSSEC already relies on the assumption that a cryptographic hash function is second pre-image resistant, since these hash functions are used for generating and validating signatures and DS RRs ๐Ÿ”

12.1.3. Transitioning to a New Hash Algorithm ๐Ÿ”

even though the NSEC3 and NSEC3PARAM RR formats include a hash algorithm parameter, this document doesn't define a specific mechanism for safely moving from one NSEC3 hash algorithm to another. so when you specify a new hash algorithm for NSEC3, a transition mechanism MUST also be defined ๐Ÿ™. it's possible the only practical and palatable transition mechanisms need an intermediate step to an insecure state, or to a state that uses NSEC records instead of NSEC3 ๐Ÿซฃ

12.1.4. Using High Iteration Values ๐Ÿšจ

since validators should treat responses containing NSEC3 RRs with high iteration values as insecure, just having one signed NSEC3 RR with a high iteration value in a zone gives attackers a possible downgrade attack ๐Ÿ˜ˆ

the attack is simple. the attacker removes any existing NSEC3 RRs from a response, then replaces them or adds a single (or multiple) NSEC3 RR with a high iterations value to the response. validators are then forced to treat the response as insecure ๐Ÿ™€. this attack only works when all of the following conditions are met:

  • There is at least one signed NSEC3 RR that uses a high iterations value present in the zone.
  • The attacker has access to one or more of these NSEC3 RRs. This is trivially true when the NSEC3 RRs with high iteration values are being returned in typical responses, but may also be true if the attacker can access the zone via AXFR or IXFR queries, or any other methodology.

using a high number of iterations also opens an extra denial-of-service opportunity against servers, since servers must calculate several hashes per negative or wildcard response ๐Ÿ”ฅ

12.2. Opt-Out Considerations ๐ŸŒธ

the Opt-Out Flag (O) lets unsigned names, in the form of delegations to unsigned zones, exist inside an otherwise signed zone ๐ŸŒท. all unsigned names are, by definition, insecure, and their validity or existence can't be cryptographically proven ๐Ÿฅฒ

in general:

  • Resource records with unsigned names (whether existing or not) suffer from the same vulnerabilities as RRs in an unsigned zone. These vulnerabilities are described in more detail in [RFC3833] (note in particular Section 2.3, "Name Chaining" and Section 2.6, "Authenticated Denial of Domain Names").
  • Resource records with signed names have the same security whether or not Opt-Out is used.

note that with or without Opt-Out, an insecure delegation can be undetectably altered by an attacker ๐Ÿ‘ป. because of this, the main difference in security when using Opt-Out is losing the ability to prove the existence or nonexistence of an insecure delegation within the span of an Opt-Out NSEC3 RR ๐Ÿซฅ

so yeah, a malicious entity may be able to insert or delete RRs with unsigned names. these are normally NS RRs, but this also includes signed wildcard expansions (the wildcard RR itself is signed, but its expanded name is an unsigned name) ๐Ÿ˜ญ

being able to add a delegation is functionally the same as being able to add any RR type. an attacker just has to forge a delegation to a name server under their control and place whatever RRs they need at the subzone apex ๐Ÿ’€

while in particular cases this issue might not be a big security problem, in general it should not be lightly dismissed ๐Ÿ™…โ€โ™€๏ธ. so it is strongly RECOMMENDED that Opt-Out be used sparingly. in particular, zone signing tools SHOULD NOT default to using Opt-Out, and MAY choose to not support Opt-Out at all ๐Ÿ’…โœจ

12.3. Other Considerations ๐Ÿ‘€

okay so walking the NSEC3 RRs will basically reveal how many RRs are in the zone (empty non-terminals count too ๐Ÿ™ˆ) and what types are there. you could add dummy entries to hide that, but honestly an upper limit can always be found anyway ๐Ÿ’€

13. References ๐Ÿ“š

13.1. Normative References

  • [RFC1034] Mockapetris, P., "Domain names - concepts and facilities", STD 13, RFC 1034, November 1987.
  • [RFC1035] Mockapetris, P., "Domain names - implementation and specification", STD 13, RFC 1035, November 1987.
  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [RFC2136] Vixie, P., Thomson, S., Rekhter, Y., and J. Bound, "Dynamic Updates in the Domain Name System (DNS UPDATE)", RFC 2136, April 1997.
  • [RFC2181] Elz, R. and R. Bush, "Clarifications to the DNS Specification", RFC 2181, July 1997.
  • [RFC2308] Andrews, M., "Negative Caching of DNS Queries (DNS NCACHE)", RFC 2308, March 1998.
  • [RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 2434, October 1998.
  • [RFC2929] Eastlake, D., Brunner-Williams, E., and B. Manning, "Domain Name System (DNS) IANA Considerations", BCP 42, RFC 2929, September 2000.
  • [RFC3597] Gustafsson, A., "Handling of Unknown DNS Resource Record (RR) Types", RFC 3597, September 2003.
  • [RFC4033] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, "DNS Security Introduction and Requirements", RFC 4033, March 2005.
  • [RFC4034] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, "Resource Records for the DNS Security Extensions", RFC 4034, March 2005.
  • [RFC4035] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, "Protocol Modifications for the DNS Security Extensions", RFC 4035, March 2005.
  • [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, October 2006.

13.2. Informative References

  • [DNSEXT-NO] Josefsson, S., "Authenticating Denial of Existence in DNS with Minimum Disclosure", Work in Progress, July 2000.
  • [DNSEXT-NSEC2v2] Laurie, B., "DNSSEC NSEC2 Owner and RDATA Format", Work in Progress, December 2004.
  • [RFC2672] Crawford, M., "Non-Terminal DNS Name Redirection", RFC 2672, August 1999.
  • [RFC2898] Kaliski, B., "PKCS #5: Password-Based Cryptography Specification Version 2.0", RFC 2898, September 2000.
  • [RFC3833] Atkins, D. and R. Austein, "Threat Analysis of the Domain Name System (DNS)", RFC 3833, August 2004.
  • [RFC4592] Lewis, E., "The Role of Wildcards in the Domain Name System", RFC 4592, July 2006.
  • [RFC4956] Arends, R., Kosters, M., and D. Blacka, "DNS Security (DNSSEC) Opt-In", RFC 4956, July 2007.

Appendix A. Example Zone ๐Ÿง

this is a zone showing its NSEC3 RRs, and they can also be used as test vectors for the hash algorithm โœจ the overall TTL and class live in the SOA RR, so they get left out below for clarity.

the zone is preceded by a list with the hashes of the original ownernames ๐Ÿ”ฎ

; H(example)       = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom
; H(a.example)     = 35mthgpgcu1qg68fab165klnsnk3dpvl
; H(ai.example)    = gjeqe526plbf1g8mklp59enfd789njgi
; H(ns1.example)   = 2t7b4g4vsa5smi47k61mv5bv1a22bojr
; H(ns2.example)   = q04jkcevqvmu85r014c7dkba38o0ji5r
; H(w.example)     = k8udemvp1j2f7eg6jebps17vp3n8i58h
; H(*.w.example)   = r53bq7cc2uvmubfu5ocmm6pers9tk9en
; H(x.w.example)   = b4um86eghhds6nea196smvmlo4ors995
; H(y.w.example)   = ji6neoaepv8b5o6k4ev33abha8ht9fgc
; H(x.y.w.example) = 2vptu5timamqttgl4luu9kg21e0aor3s
; H(xx.example)    = t644ebqk9bibcna874givr6joj62mlhv
; H(2t7b4g4vsa5smi47k61mv5bv1a22bojr.example)
;                  = kohar7mbb8dc2ce8a9qvl8hon4k53uhi
example. 3600  IN SOA  ns1.example. bugs.x.w.example. 1 3600 300 (
                       3600000 3600 )
               RRSIG   SOA 7 1 3600 20150420235959 20051021000000 (
                       40430 example.
                       Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i
                       q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd
                       VI2LmKusbZsT0Q== )
               NS      ns1.example.
               NS      ns2.example.
               RRSIG   NS 7 1 3600 20150420235959 20051021000000 (
                       40430 example.
                       PVOgtMK1HHeSTau+HwDWC8Ts+6C8qtqd4pQJ
                       qOtdEVgg+MA+ai4fWDEhu3qHJyLcQ9tbD2vv
                       CnMXjtz6SyObxA== )
               MX      1 xx.example.
               RRSIG   MX 7 1 3600 20150420235959 20051021000000 (
                       40430 example.
                       GgQ1A9xs47k42VPvpL/a1BWUz/6XsnHkjotw
                       9So8MQtZtl2wJBsnOQsaoHrRCrRbyriEl/GZ
                       n9Mto/Kx+wBo+w== )
               DNSKEY  256 3 7 AwEAAaetidLzsKWUt4swWR8yu0wPHPiUi8LU (
                       sAD0QPWU+wzt89epO6tHzkMBVDkC7qphQO2h
                       TY4hHn9npWFRw5BYubE= )

               DNSKEY  257 3 7 AwEAAcUlFV1vhmqx6NSOUOq2R/dsR7Xm3upJ (
                       j7IommWSpJABVfW8Q0rOvXdM6kzt+TAu92L9
                       AbsUdblMFin8CVF3n4s= )
               RRSIG   DNSKEY 7 1 3600 20150420235959 (
                       20051021000000 12708 example.
                       AuU4juU9RaxescSmStrQks3Gh9FblGBlVU31
                       uzMZ/U/FpsUb8aC6QZS+sTsJXnLnz7flGOsm
                       MGQZf3bH+QsCtg== )
               NSEC3PARAM 1 0 12 aabbccdd
               RRSIG   NSEC3PARAM 7 1 3600 20150420235959 (
                       20051021000000 40430 example.
                       C1Gl8tPZNtnjlrYWDeeUV/sGLCyy/IHie2re
                       rN05XSA3Pq0U3+4VvGWYWdUMfflOdxqnXHwJ
                       TLQsjlkynhG6Cg== )
0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd (
                       2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS
                       SOA NSEC3PARAM RRSIG )
               RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 (
                       40430 example.
                       OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL
                       IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762
                       BOCXJZMnpuwhpA== )
2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. A 192.0.2.127
               RRSIG   A 7 2 3600 20150420235959 20051021000000 (
                       40430 example.
                       h6c++bzhRuWWt2bykN6mjaTNBcXNq5UuL5Ed
                       K+iDP4eY8I0kSiKaCjg3tC1SQkeloMeub2GW
                       k8p6xHMPZumXlw== )
               NSEC3   1 1 12 aabbccdd (
                       2vptu5timamqttgl4luu9kg21e0aor3s A RRSIG )
               RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 (
                       40430 example.
                       OmBvJ1Vgg1hCKMXHFiNeIYHK9XVW0iLDLwJN
                       4TFoNxZuP03gAXEI634YwOc4YBNITrj413iq
                       NI6mRk/r1dOSUw== )
2vptu5timamqttgl4luu9kg21e0aor3s.example. NSEC3 1 1 12 aabbccdd (
                       35mthgpgcu1qg68fab165klnsnk3dpvl MX RRSIG )
               RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 (
                       40430 example.
                       KL1V2oFYghNV0Hm7Tf2vpJjM6l+0g1JCcVYG
                       VfI0lKrhPmTsOA96cLEACgo1x8I7kApJX+ob
                       TuktZ+sdsZPY1w== )
35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd (
                       b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )

               RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 (
                       40430 example.
                       g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ
                       Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ
                       XtAIR3chwgW+SA== )
a.example.     NS      ns1.a.example.
               NS      ns2.a.example.
               DS      58470 5 1 (
                       3079F1593EBAD6DC121E202A8B766A6A4837206C )
               RRSIG   DS 7 2 3600 20150420235959 20051021000000 (
                       40430 example.
                       XacFcQVHLVzdoc45EJhN616zQ4mEXtE8FzUh
                       M2KWjfy1VfRKD9r1MeVGwwoukOKgJxBPFsWo
                       o722vZ4UZ2dIdA== )
ns1.a.example. A       192.0.2.5
ns2.a.example. A       192.0.2.6
ai.example.    A       192.0.2.9
               RRSIG   A 7 2 3600 20150420235959 20051021000000 (
                       40430 example.
                       hVe+wKYMlObTRPhX0NL67GxeZfdxqr/QeR6F
                       tfdAj5+FgYxyzPEjIzvKWy00hWIl6wD3Vws+
                       rznEn8sQ64UdqA== )
               HINFO   "KLH-10" "ITS"
               RRSIG   HINFO 7 2 3600 20150420235959 20051021000000 (
                       40430 example.
                       Yi42uOq43eyO6qXHNvwwfFnIustWgV5urFcx
                       enkLvs6pKRh00VBjODmf3Z4nMO7IOl6nHSQ1
                       v0wLHpEZG7Xj2w== )
               AAAA    2001:db8:0:0:0:0:f00:baa9
               RRSIG   AAAA 7 2 3600 20150420235959 20051021000000 (
                       40430 example.
                       LcdxKaCB5bGZwPDg+3JJ4O02zoMBrjxqlf6W
                       uaHQZZfTUpb9Nf2nxFGe2XRPfR5tpJT6GdRG
                       cHueLuXkMjBArQ== )
b4um86eghhds6nea196smvmlo4ors995.example. NSEC3 1 1 12 aabbccdd (
                       gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG )
               RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 (
                       40430 example.
                       ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh
                       5u4m/CUiwtblEVOaAKKZd7S959OeiX43aLX3
                       pOv0TSTyiTxIZg== )
c.example.     NS      ns1.c.example.
               NS      ns2.c.example.
ns1.c.example. A       192.0.2.7
ns2.c.example. A       192.0.2.8
gjeqe526plbf1g8mklp59enfd789njgi.example. NSEC3 1 1 12 aabbccdd (
                       ji6neoaepv8b5o6k4ev33abha8ht9fgc HINFO A AAAA
                       RRSIG )
                  RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          IVnezTJ9iqblFF97vPSmfXZ5Zozngx3KX3by
                          LTZC4QBH2dFWhf6scrGFZB980AfCxoD9qbbK
                          Dy+rdGIeRSVNyw== )
   ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. NSEC3 1 1 12 aabbccdd (
                          k8udemvp1j2f7eg6jebps17vp3n8i58h )
                  RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          gPkFp1s2QDQ6wQzcg1uSebZ61W33rUBDcTj7
                          2F3kQ490fEdp7k1BUIfbcZtPbX3YCpE+sIt0
                          MpzVSKfTwx4uYA== )
   k8udemvp1j2f7eg6jebps17vp3n8i58h.example. NSEC3 1 1 12 aabbccdd (
                          kohar7mbb8dc2ce8a9qvl8hon4k53uhi )
                  RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          FtXGbvF0+wf8iWkyo73enAuVx03klN+pILBK
                          S6qCcftVtfH4yVzsEZquJ27NHR7ruxJWDNMt
                          Otx7w9WfcIg62A== )
   kohar7mbb8dc2ce8a9qvl8hon4k53uhi.example. NSEC3 1 1 12 aabbccdd (
                          q04jkcevqvmu85r014c7dkba38o0ji5r A RRSIG )
                  RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          VrDXs2uVW21N08SyQIz88zml+y4ZCInTwgDr
                          6zz43yAg+LFERjOrj3Ojct51ac7Dp4eZbf9F
                          QJazmASFKGxGXg== )
   ns1.example.   A       192.0.2.1
                  RRSIG   A 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          bu6kx73n6XEunoVGuRfAgY7EF/AJqHy7hj0j
                          kiqJjB0dOrx3wuz9SaBeGfqWIdn/uta3SavN
                          4FRvZR9SCFHF5Q== )
   ns2.example.   A       192.0.2.2
                  RRSIG   A 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          ktQ3TqE0CfRfki0Rb/Ip5BM0VnxelbuejCC4
                          zpLbFKA/7eD7UNAwxMgxJPtbdST+syjYSJaj
                          4IHfeX6n8vfoGA== )
   q04jkcevqvmu85r014c7dkba38o0ji5r.example. NSEC3 1 1 12 aabbccdd (
                          r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG )
                  RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3
                          ZxlMKimoPAyqletMlEWwLfFia7sdpSzn+ZlN
                          NlkxWcLsIlMmUg== )

   r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. NSEC3 1 1 12 aabbccdd (
                          t644ebqk9bibcna874givr6joj62mlhv MX RRSIG )
                  RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          aupviViruXs4bDg9rCbezzBMf9h1ZlDvbW/C
                          ZFKulIGXXLj8B/fsDJarXVDA9bnUoRhEbKp+
                          HF1FWKW7RIJdtQ== )
   t644ebqk9bibcna874givr6joj62mlhv.example. NSEC3 1 1 12 aabbccdd (
                          0p9mhaveqvm6t7vbl5lop2u3t2rp3tom HINFO A AAAA
                          RRSIG )
                  RRSIG   NSEC3 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          RAjGECB8P7O+F4Pa4Dx3tC0M+Z3KmlLKImca
                          fb9XWwx+NWUNz7NBEDBQHivIyKPVDkChcePI
                          X1xPl1ATNa+8Dw== )
   *.w.example.   MX      1 ai.example.
                  RRSIG   MX 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          CikebjQwGQPwijVcxgcZcSJKtfynugtlBiKb
                          9FcBTrmOoyQ4InoWVudhCWsh/URX3lc4WRUM
                          ivEBP6+4KS3ldA== )
   x.w.example.   MX      1 xx.example.
                  RRSIG   MX 7 3 3600 20150420235959 20051021000000 (
                          40430 example.
                          IrK3tq/tHFIBF0scHiE/1IwMAvckS/55hAVv
                          QyxTFbkAdDloP3NbZzu+yoSsr3b3OX6qbBpY
                          7WCtwwekLKRAwQ== )
   x.y.w.example. MX      1 xx.example.
                  RRSIG   MX 7 4 3600 20150420235959 20051021000000 (
                          40430 example.
                          MqSt5HqJIN8+SLlzTOImrh5h9Xa6gDvAW/Gn
                          nbdPc6Z7nXvCpLPJj/5lCwx3VuzVOjkbvXze
                          8/8Ccl2Zn2hbug== )
   xx.example.    A       192.0.2.10
                  RRSIG   A 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          T35hBWEZ017VC5u2c4OriKyVn/pu+fVK4AlX
                          YOxJ6iQylfV2HQIKjv6b7DzINB3aF/wjJqgX
                          pQvhq+Ac6+ZiFg== )
                  HINFO   "KLH-10" "TOPS-20"
                  RRSIG   HINFO 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          KimG+rDd+7VA1zRsu0ITNAQUTRlpnsmqWrih
                          FRnU+bRa93v2e5oFNFYCs3Rqgv62K93N7AhW
                          6Jfqj/8NzWjvKg== )
                  AAAA    2001:db8:0:0:0:0:f00:baaa
                  RRSIG   AAAA 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          IXBcXORITNwd8h3gNwyxtYFvAupS/CYWufVe
                          uBUX0O25ivBCULjZjpDxFSxfohb/KA7YRdxE
                          NzYfMItpILl/Xw== )

Appendix B. Example Responses โœจ

The examples in this section are response messages built on the signed zone example from Appendix A, so you can see exactly how the pieces fit together ๐Ÿ’–

B.1. Name Error ๐Ÿ™ˆ

This one is an authoritative name error ๐Ÿ’€ The NSEC3 RRs are doing the heavy lifting here: they prove the name doesn't exist, and that there's no wildcard RR that should have been expanded.

;; Header: QR AA DO RCODE=3
;;
;; Question
a.c.x.w.example.         IN A

;; Answer
;; (empty)

;; Authority

example.       SOA     ns1.example. bugs.x.w.example. 1 3600 300 (
                       3600000 3600 )
example.       RRSIG   SOA 7 1 3600 20150420235959 20051021000000 (
                       40430 example.
                       Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i
                       q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd
                       VI2LmKusbZsT0Q== )

;; NSEC3 RR that covers the "next closer" name (c.x.w.example)
;; H(c.x.w.example) = 0va5bpr2ou0vk0lbqeeljri88laipsfh

0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd (
                       2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS
                       SOA NSEC3PARAM RRSIG )
0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 (
                       20150420235959 20051021000000 40430 example.
                       OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL
                       IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762
                       BOCXJZMnpuwhpA== )

;; NSEC3 RR that matches the closest encloser (x.w.example)
;; H(x.w.example) = b4um86eghhds6nea196smvmlo4ors995

b4um86eghhds6nea196smvmlo4ors995.example. NSEC3 1 1 12 aabbccdd (
                       gjeqe526plbf1g8mklp59enfd789njgi MX RRSIG )
b4um86eghhds6nea196smvmlo4ors995.example. RRSIG NSEC3 7 2 3600 (
                       20150420235959 20051021000000 40430 example.
                       ZkPG3M32lmoHM6pa3D6gZFGB/rhL//Bs3Omh
                       5u4m/CUiwtblEVOaAKKZd7S959OeiX43aLX3
                       pOv0TSTyiTxIZg== )

;; NSEC3 RR that covers wildcard at the closest encloser (*.x.w.example)
;; H(*.x.w.example) = 92pqneegtaue7pjatc3l3qnk738c6v5m

35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd (
                       b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 (
                       20150420235959 20051021000000 40430 example.
                       g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ
                       Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ
                       XtAIR3chwgW+SA== )

;; Additional
;; (empty)

So the query got back three NSEC3 RRs, and together they prove the requested data doesn't exist and that no wildcard expansion applies ๐Ÿฆ‹ The whole thing is authenticated by checking those NSEC3 RRs. The RRSIGs say the NSEC3 RRs were signed by an "example" DNSKEY using algorithm 7 with key tag 40430, so the resolver needs that DNSKEY RR to authenticate the answer ๐Ÿ”

Here's the vibe check. One of the NSEC3 owner names matches the closest encloser. Another NSEC3 RR proves there's no longer name, and the last one proves there's no wildcard RRSet that should've been expanded. You find the closest encloser by applying the algorithm in Section 8.3 ๐ŸŒธ

In this example, 'x.w.example' hashes to 'b4um86eghhds6nea196smvmlo4ors995', which tells you it might be the closest encloser. To prove that 'c.x.w.example' and '*.x.w.example' don't exist, you hash those names too, giving '0va5bpr2ou0vk0lbqeeljri88laipsfh' and '92pqneegtaue7pjatc3l3qnk738c6v5m' respectively. The first and last NSEC3 RRs prove that those hashed owner names don't exist ๐Ÿ’…

B.2. No Data Error ๐Ÿ“

This is a "no data" response ๐ŸŽ€ The NSEC3 RR proves that the name exists, but the requested RR type doesn't.

;; Header: QR AA DO RCODE=0
;;
;; Question
ns1.example.        IN MX

;; Answer
;; (empty)

;; Authority
example.       SOA     ns1.example. bugs.x.w.example. 1 3600 300 (
                       3600000 3600 )
example.       RRSIG   SOA 7 1 3600 20150420235959 20051021000000 (
                       40430 example.
                       Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i
                       q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd
                       VI2LmKusbZsT0Q== )

;; NSEC3 RR matches the QNAME and shows that the MX type bit is not set.

2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. NSEC3 1 1 12 aabbccdd (
                       2vptu5timamqttgl4luu9kg21e0aor3s A RRSIG )
2t7b4g4vsa5smi47k61mv5bv1a22bojr.example. RRSIG NSEC3 7 2 3600 (
                       20150420235959 20051021000000 40430 example.
                       OmBvJ1Vgg1hCKMXHFiNeIYHK9XVW0iLDLwJN
                       4TFoNxZuP03gAXEI634YwOc4YBNITrj413iq
                       NI6mRk/r1dOSUw== )
;; Additional
;; (empty)

The query returned one NSEC3 RR that proves the requested name exists, since "ns1.example." hashes to "2t7b4g4vsa5smi47k61mv5bv1a22bojr" โœจ It also shows that the requested RR type is missing, because type MX isn't in the NSEC3 RR's type code list. And it wasn't a CNAME either, since type CNAME is absent from that list too ๐Ÿงš

B.2.1. No Data Error, Empty Non-Terminal

okay bestie, this one is a "no data" answer caused by an empty non-terminal ๐ŸŒธ The NSEC3 RR proves the name exists and that the requested RR type doesn't ๐Ÿ’…

 ;; Header: QR AA DO RCODE=0
 ;;
 ;; Question
 y.w.example.        IN A

 ;; Answer
 ;; (empty)

 ;; Authority
 example.       SOA     ns1.example. bugs.x.w.example. 1 3600 300 (
                        3600000 3600 )
 example.       RRSIG   SOA 7 1 3600 20150420235959 20051021000000 (
                        40430 example.
                        Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i
                        q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd
                        VI2LmKusbZsT0Q== )

 ;; NSEC3 RR matches the QNAME and shows that the A type bit is not set.

 ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. NSEC3 1 1 12 aabbccdd (
                        k8udemvp1j2f7eg6jebps17vp3n8i58h )
 ji6neoaepv8b5o6k4ev33abha8ht9fgc.example. RRSIG NSEC3 7 2 3600 (
                        20150420235959 20051021000000 40430 example.
                        gPkFp1s2QDQ6wQzcg1uSebZ61W33rUBDcTj7
                        2F3kQ490fEdp7k1BUIfbcZtPbX3YCpE+sIt0
                        MpzVSKfTwx4uYA== )

 ;; Additional
 ;; (empty)

The query returned an NSEC3 RR that proves the requested name exists (y.w.example. hashes to ji6neoaepv8b5o6k4ev33abha8ht9fgc), but the requested RR type doesn't exist (Type A is absent in the Type Bit Maps field of the NSEC3 RR). โœจ Note that, unlike an empty non-terminal proof using NSECs, this is identical to a No Data Error. ๐Ÿ™ˆ This example is solely mentioned to be complete.


B.3. Referral to an Opt-Out Unsigned Zone

the NSEC3 RRs prove that nothing for this delegation was signed ๐Ÿฆ‹ There's no proof that the unsigned delegation exists, so don't go looking for one ๐Ÿ˜ญ

   ;; Header: QR DO RCODE=0
   ;;
   ;; Question
   mc.c.example.       IN MX

   ;; Answer
   ;; (empty)

   ;; Authority
   c.example.     NS      ns1.c.example.
                  NS      ns2.c.example.

   ;; NSEC3 RR that covers the "next closer" name (c.example)
   ;; H(c.example) = 4g6p9u5gvfshp30pqecj98b3maqbn1ck

   35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd (
                          b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
   35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 (
                          20150420235959 20051021000000 40430 example.
                          g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ
                          Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ
                          XtAIR3chwgW+SA== )

   ;; NSEC3 RR that matches the closest encloser (example)
   ;; H(example) = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom

   0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd (
                          2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS
                          SOA NSEC3PARAM RRSIG )
   0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 (
                          20150420235959 20051021000000 40430 example.
                          OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL
                          IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762
                          BOCXJZMnpuwhpA== )

   ;; Additional
   ns1.c.example. A       192.0.2.7
   ns2.c.example. A       192.0.2.8

The query returned a referral to the unsigned c.example. zone ๐ŸŒˆ The response says the closest provable encloser of c.example is example, since the hash of c.example (4g6p9u5gvfshp30pqecj98b3maqbn1ck) is covered by the first NSEC3 RR and its Opt-Out bit is set. ๐Ÿซถ


B.4. Wildcard Expansion

a query answered with a response containing a wildcard expansion ๐Ÿงš The label count in the RRSIG RRSet in the answer section tells you a wildcard RRSet got expanded to make this response, and the NSEC3 RR proves no "next closer" name exists in the zone ๐Ÿ’œ

   ;; Header: QR AA DO RCODE=0
   ;;
   ;; Question
   a.z.w.example. IN MX

   ;; Answer
   a.z.w.example. MX      1 ai.example.
   a.z.w.example. RRSIG   MX 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          CikebjQwGQPwijVcxgcZcSJKtfynugtlBiKb
                          9FcBTrmOoyQ4InoWVudhCWsh/URX3lc4WRUM
                          ivEBP6+4KS3ldA== )

   ;; Authority
   example.       NS      ns1.example.
   example.       NS      ns2.example.
   example.       RRSIG   NS 7 1 3600 20150420235959 20051021000000 (
                          40430 example.
                          PVOgtMK1HHeSTau+HwDWC8Ts+6C8qtqd4pQJ
                          qOtdEVgg+MA+ai4fWDEhu3qHJyLcQ9tbD2vv
                          CnMXjtz6SyObxA== )

   ;; NSEC3 RR that covers the "next closer" name (z.w.example)
   ;; H(z.w.example) = qlu7gtfaeh0ek0c05ksfhdpbcgglbe03

   q04jkcevqvmu85r014c7dkba38o0ji5r.example. NSEC3 1 1 12 aabbccdd (
                          r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG )
   q04jkcevqvmu85r014c7dkba38o0ji5r.example. RRSIG NSEC3 7 2 3600 (
                          20150420235959 20051021000000 40430 example.
                          hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3
                          ZxlMKimoPAyqletMlEWwLfFia7sdpSzn+ZlN
                          NlkxWcLsIlMmUg== )

   ;; Additional
   ai.example.    A       192.0.2.9
   ai.example.    RRSIG   A 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          hVe+wKYMlObTRPhX0NL67GxeZfdxqr/QeR6F
                          tfdAj5+FgYxyzPEjIzvKWy00hWIl6wD3Vws+
                          rznEn8sQ64UdqA== )
   ai.example.    AAAA    2001:db8:0:0:0:0:f00:baa9
   ai.example.    RRSIG   AAAA 7 2 3600 20150420235959 20051021000000 (
                          40430 example.
                          LcdxKaCB5bGZwPDg+3JJ4O02zoMBrjxqlf6W
                          uaHQZZfTUpb9Nf2nxFGe2XRPfR5tpJT6GdRG
                          cHueLuXkMjBArQ== )

The query returned an answer produced by a wildcard expansion โœจ The answer section has a wildcard RRSet expanded just like it would be in a traditional DNS response. The RRSIG Labels field value of 2 tells you the answer came from wildcard expansion, since a.z.w.example has 4 labels. ๐Ÿฆ‹ This also shows that w.example exists, so there's no need for an NSEC3 RR that matches the closest encloser.

The NSEC3 RR proves that no closer match could have been used to answer this query. ๐Ÿ‘‘


B.5. Wildcard No Data Error

a "no data" response for a name covered by a wildcard ๐Ÿ“ The NSEC3 RRs prove that the matching wildcard name doesn't have any RRs of the requested type, and that no closer match exists in the zone.

   ;; Header: QR AA DO RCODE=0
   ;;
   ;; Question
   a.z.w.example.      IN AAAA

   ;; Answer
   ;; (empty)

   ;; Authority
   example.       SOA     ns1.example. bugs.x.w.example. 1 3600 300 (
                          3600000 3600 )
   example.       RRSIG   SOA 7 1 3600 20150420235959 20051021000000 (
                          40430 example.
                          Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i
                          q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd
                          VI2LmKusbZsT0Q== )

   ;; NSEC3 RR that matches the closest encloser (w.example)
   ;; H(w.example) = k8udemvp1j2f7eg6jebps17vp3n8i58h

   k8udemvp1j2f7eg6jebps17vp3n8i58h.example. NSEC3 1 1 12 aabbccdd (
                          kohar7mbb8dc2ce8a9qvl8hon4k53uhi )
   k8udemvp1j2f7eg6jebps17vp3n8i58h.example. RRSIG NSEC3 7 2 3600 (
                          20150420235959 20051021000000 40430 example.
                          FtXGbvF0+wf8iWkyo73enAuVx03klN+pILBK
                          S6qCcftVtfH4yVzsEZquJ27NHR7ruxJWDNMt
                          Otx7w9WfcIg62A== )

   ;; NSEC3 RR that covers the "next closer" name (z.w.example)
   ;; H(z.w.example) = qlu7gtfaeh0ek0c05ksfhdpbcgglbe03

   q04jkcevqvmu85r014c7dkba38o0ji5r.example. NSEC3 1 1 12 aabbccdd (
                          r53bq7cc2uvmubfu5ocmm6pers9tk9en A RRSIG )
   q04jkcevqvmu85r014c7dkba38o0ji5r.example. RRSIG NSEC3 7 2 3600 (
                          20150420235959 20051021000000 40430 example.
                          hV5I89b+4FHJDATp09g4bbN0R1F845CaXpL3
                          ZxlMKimoPAyqletMlEWwLfFia7sdpSzn+ZlN
                          NlkxWcLsIlMmUg== )

   ;; NSEC3 RR that matches a wildcard at the closest encloser.
   ;; H(*.w.example) = r53bq7cc2uvmubfu5ocmm6pers9tk9en

   r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. NSEC3 1 1 12 aabbccdd (
                          t644ebqk9bibcna874givr6joj62mlhv MX RRSIG )
   r53bq7cc2uvmubfu5ocmm6pers9tk9en.example. RRSIG NSEC3 7 2 3600 (
                          20150420235959 20051021000000 40430 example.
                          aupviViruXs4bDg9rCbezzBMf9h1ZlDvbW/C
                          ZFKulIGXXLj8B/fsDJarXVDA9bnUoRhEbKp+
                          HF1FWKW7RIJdtQ== )

   ;; Additional
   ;; (empty)

The query returned the NSEC3 RRs that prove the requested data doesn't exist and no wildcard RR applies ๐Ÿ’–


B.6. DS Child Zone No Data Error

a "no data" response for a QTYPE=DS query that got sent by mistake to a name server for the child zone ๐Ÿ™ˆ

;; Header: QR AA DO RCODE=0
;;
;; Question
example.            IN DS

;; Answer
;; (empty)

;; Authority
example.       SOA     ns1.example. bugs.x.w.example. 1 3600 300 (
                       3600000 3600 )
example.       RRSIG   SOA 7 1 3600 20150420235959 20051021000000 (
                       40430 example.
                       Hu25UIyNPmvPIVBrldN+9Mlp9Zql39qaUd8i
                       q4ZLlYWfUUbbAS41pG+68z81q1xhkYAcEyHd
                       VI2LmKusbZsT0Q== )

;; NSEC3 RR matches the QNAME and shows that the DS type bit is not set.

0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd (
                       2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS
                       SOA NSEC3PARAM RRSIG )
0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600
                       20150420235959 20051021000000 40430 example.
                       OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL
                       IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762
                       BOCXJZMnpuwhpA== )

;; Additional
;; (empty)

The query returned an NSEC3 RR showing that the requested was answered by the server authoritative for the zone "example". ๐ŸŒธ The NSEC3 RR shows an SOA RR is present, which tells you this NSEC3 RR comes from the apex of the child, not from the zone cut of the parent. ๐Ÿงš Queries for the "example" DS RRSet should be sent to the parent servers (which, in this case, are the root servers). ๐Ÿ‘‘


Appendix C. Special Considerations

the following paragraphs clarify specific behavior and explain special considerations for implementations ๐ŸŽ€

C.1. Salting ๐Ÿง‚โœจ

okay so salt is basically the secret ingredient that makes a precomputed dictionary way more annoying to use ๐Ÿ’…. Adding salt to the original owner names before hashing means every extra bit of salt doubles the cost of a dictionary of pre-generated hash values, since there has to be an entry for every word combined with every possible salt value. The NSEC3 RR can carry up to 2040 bits (255 octets) of salt, which multiplies the cost by 2^2040 ๐Ÿซ . In practice, that means an attacker has to recompute the whole dictionary every time the salt changes.

Including a salt does not change how much work it takes to construct NSEC3 RRs, no matter how big the salt is. It does make the NSEC3 RR bigger though, so there's a tradeoff ๐ŸŽ€.

There MUST be at least one complete set of NSEC3 RRs for the zone using the same salt value. That's non-negotiable, bestie ๐Ÿ’–.

The salt SHOULD be changed periodically so nobody can pre-compute with one single salt forever ๐Ÿฆ‹. It is RECOMMENDED that the salt be changed for every re-signing, which is the iconic move โœจ.

Now, this could make a resolver see RRs with different salt values for the same zone, and that's totally fine ๐Ÿ™Œ. Each RR stands alone: it denies the set of owner names whose hashes, using the salt in that NSEC3 RR, fall between the two hashes in that NSEC3 RR. Only the server needs a complete set of NSEC3 RRs with the same salt, so it can answer every possible query ๐Ÿงš.

There is no rule against having NSEC3 RRs with different salts in the same zone ๐ŸŒˆ. However, so that authoritative servers can consistently find covering NSEC3 RRs, the authoritative server MUST choose a single set of parameters (algorithm, salt, and iterations) to use when selecting NSEC3 RRs. Main character energy means being consistent ๐Ÿ‘‘.

C.2. Hash Collision ๐Ÿ’ฅ

Hash collisions happen when different messages end up with the same hash value ๐Ÿ™ˆ. The expected number of domain names needed to give a 1 in 2 chance of a single collision is about 2^(n/2) for a hash of length n bits (i.e., 2^80 for SHA-1). ngl that probability is extremely low ๐Ÿ˜ญ, but the next parts cover avoiding collisions and figuring out the damage if someone attacks using hash collisions.

C.2.1. Avoiding Hash Collisions During Generation ๐Ÿ›ก๏ธ

During generation of NSEC3 RRs, hash values are supposedly unique ๐Ÿ“. In the (academic) case of a collision happening anyway, an alternative salt MUST be chosen and all hash values MUST be regenerated. Plan B, but make it fast ๐Ÿƒโ€โ™€๏ธ.

C.2.2. Second Preimage Requirement Analysis ๐Ÿ”

A cryptographic hash function has a second-preimage resistance property ๐Ÿ”. That means it is computationally infeasible to find another message with the same hash value as a given message. So, given preimage X, finding a second preimage X' != X such that hash(X) = hash(X') is basically impossible. The work factor for finding a second preimage is of the order of 2^160 for SHA-1. To mount an attack using an existing NSEC3 RR, an adversary needs to find a second preimage, which is a seriously extreme move ๐Ÿ’€.

Okay, but say an adversary is somehow capable of pulling that off. The actual damage is that a response message can be generated claiming that a certain QNAME (i.e., the second pre-image) does exist, while in reality QNAME does not exist. That's a false positive ๐Ÿ˜ฌ. It will either cause a security-aware resolver to re-query for the non-existent name, or to fail the initial query. Note that the adversary can't mount this attack on an existing name, but only on a name that the adversary can't choose and that does not yet exist ๐Ÿ™…โ€โ™€๏ธ.


Authors' Addresses ๐ŸŽ€

Ben Laurie
Nominet
17 Perryn Road
London  W3 7LR
England

Phone: +44 20 8735 0686
EMail: ben@links.org


Geoffrey Sisson
Nominet
Minerva House
Edmund Halley Road
Oxford Science Park
Oxford  OX4 4DQ
UNITED KINGDOM

Phone: +44 1865 332211
EMail: geoff-s@panix.com


Roy Arends
Nominet
Minerva House
Edmund Halley Road
Oxford Science Park
Oxford  OX4 4DQ
UNITED KINGDOM

Phone: +44 1865 332211
EMail: roy@nominet.org.uk


David Blacka
VeriSign, Inc.
21355 Ridgetop Circle
Dulles, VA  20166
US

Phone: +1 703 948 3200
EMail: davidb@verisign.com

Copyright (C) The IETF Trust (2008).

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE IETF TRUST AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.


Intellectual Property ๐ŸŒธ

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document, or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.

Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org. ๐Ÿ’œ

๐Ÿ“ฆ where this page comes from