RFC 9276

Guidance for NSEC3 Parameter Settings

๐Ÿ“… published August 2022, from ietf

RFC 9276: Guidance for NSEC3 Parameter Settings ๐ŸŽ€

okay bestie, grab a drink because this one is about NSEC3 โœจ It's a Best Current Practice, so it's the IETF's recommended way of doing things, not a brand new protocol. It's BCP 236, which is RFC 9276, written in August 2022 by W. Hardaker from USC/ISI and V. Dukhovni from Bloomberg, L.P. It's a Best Current Practice document, and it updates RFC 5155 (the original NSEC3 spec). It's listed under ISSN 2070-1721 ๐Ÿฆ‹

Abstract โœจ

NSEC3 is a DNSSEC mechanism that gives you proof of nonexistence by showing there are no names between two domain names in a zone. The lowkey genius part is that unlike its sibling NSEC, NSEC3 doesn't directly reveal those bounding domain name pairs ๐Ÿ™ˆ This document gives guidance on setting NSEC3 parameters, based on what people have actually seen when deploying it. It updates RFC 5155 with advice on picking the iteration and salt parameters ๐Ÿ’œ

Status of This Memo ๐ŸŒธ

This memo documents an Internet Best Current Practice.

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It went through public review and was approved for publication by the Internet Engineering Steering Group (IESG). More info on BCPs is in Section 2 of RFC 7841.

For the current status of this document, any errata, and how to send feedback, check https://www.rfc-editor.org/info/rfc9276.

Copyright (c) 2022 IETF Trust and the persons identified as the document authors. All rights reserved.

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they stand on the date this document was published. Please read them carefully, because they explain your rights and restrictions for this document. Code Components pulled out of this document must include Revised BSD License text, as described in Section 4.e of the Trust Legal Provisions, and they come without warranty, as described in the Revised BSD License.

Table of Contents ๐Ÿงš

1.  Introduction
  1.1.  Requirements Notation
2.  NSEC3 Parameter Value Discussions
  2.1.  Algorithms
  2.2.  Flags
  2.3.  Iterations
  2.4.  Salt
3.  Recommendations for Deploying and Validating NSEC3 Records
  3.1.  Best Practice for Zone Publishers
  3.2.  Recommendation for Validating Resolvers
  3.3.  Recommendation for Primary and Secondary Relationships
4.  Security Considerations
5.  Operational Considerations
6.  IANA Considerations
7.  References
  7.1.  Normative References
  7.2.  Informative References
Appendix A.  Deployment Measurements at Time of Publication
Appendix B.  Computational Burdens of Processing NSEC3 Iterations
Acknowledgments
Authors' Addresses

1. Introduction ๐ŸŒˆ

Okay so, NSEC gives you proof of nonexistence, meaning signed DNS records that prove a given name or a given Resource Record Type (RRTYPE) doesn't exist in a DNSSEC-signed zone [RFC4035]. NSEC3 [RFC5155] does the same job, but the names of valid nodes in the zone get scrambled through hashing, possibly with multiple rounds of it. Right now, only SHA-1 is actually in use on the Internet ๐Ÿ”ฅ

NSEC3 also has "opt-out support", which lets a whole block of unsigned delegations get covered by one NSEC3 record. This is a big deal for large registries, because with opt-out they only need to sign as many NSEC3 records as there are signed DS or other Resource Record sets (RRsets) in the zone. Unsigned delegations don't need extra NSEC3 records ๐Ÿ™Œ The catch is that you give up some of the tamper-resistance of the proof of nonexistence in exchange for lower memory and CPU overhead. It's a tradeoff, bestie.

NSEC3 records have a bunch of tunable parameters, set in an NSEC3PARAM record at the zone apex. Those are the hash algorithm, the processing flags, the number of hash iterations, and the salt. Each one has security and operational considerations that affect both zone owners and validating resolvers. This document shares some best-practice recommendations for setting them ๐Ÿ’–

1.1. Requirements Notation

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. So if you see them in caps, they carry the BCP 14 weight. Lowercase is just regular words, babe ๐Ÿ’…

2. NSEC3 Parameter Value Discussions ๐Ÿฆ‹

This section gives the background on the parameters for the NSEC3 and NSEC3PARAM RRTYPEs. Think of it as the lore before the main event โœจ

2.1. Algorithms

This document doesn't cover the algorithm field. If you want guidance on which DNSSEC algorithms to use, the reading is [RFC8624] ๐Ÿ“š

2.2. Flags

The NSEC3PARAM flags field only has reserved and unassigned flags right now. The individual NSEC3 records, though, do have an "Opt-Out" flag [RFC5155], which says whether that NSEC3 record provides proof of nonexistence. Generally, NSEC3 with the Opt-Out flag enabled should only be used in large, highly dynamic zones where only a small percentage of delegations are signed. The payoff is fewer signature creations when new delegations get added to the zone ๐Ÿ™Œ This usually only makes sense for super huge registration points that push zone updates faster than real-time signing can handle, or when you're on memory-constrained hardware.

If you're an operator thinking about NSEC3, carefully weigh the costs and benefits of NSEC3 versus NSEC. It's giving "do the math first" energy ๐Ÿงฎ Smaller zones, or large but relatively static ones, are encouraged to skip the opt-out flag and use DNSSEC's authenticated denial of existence instead. Main character energy is knowing when you don't need the fancy stuff ๐Ÿ‘‘

2.3. Iterations

NSEC3 records get made by hashing the input domain first, and then repeating that same hash algorithm a number of times, based on the iteration parameter in the NSEC3PARAM and NSEC3 records. The first hash is usually enough to discourage zone enumeration by "zone walking" an unhashed NSEC chain ๐Ÿ•ต๏ธโ€โ™€๏ธ

Here's a note on how [RFC5155] describes the Iterations field:

   |  The Iterations field defines the number of additional times the
   |  hash function has been performed.

So an NSEC3 record with an Iterations field of 0 actually requires one hash iteration. Plot twist, right? ๐Ÿ˜ญ

Only determined people with serious resources are likely to try and uncover hashed values, no matter how many extra iterations get performed. If an adversary really wants to burn significant CPU to run an offline dictionary attack on a zone's NSEC3 chain, they'll probably still find most of the "guessable" names, however many extra iterations you add ๐Ÿ’€

Most names in the DNS aren't really secret or unpredictable. They're published to be memorable and used by humans. They also show up in tons of other network logs, like email logs, certificate transparency logs, web page links, intrusion-detection systems, malware scanners, email archives, and so on. A simple dictionary of common domain name prefixes (www, mail, imap, login, database, etc.) can quickly reveal a huge number of labels in a zone. So there are growing performance costs but shrinking returns from adding hash iterations beyond the first one ๐Ÿ“‰

Section 10.3 of [RFC5155] sets the upper bounds for how many hash iterations to use, but there isn't any published guidance for zone owners on good values to pick. Recent academic studies have shown that NSEC3 hashing provides only moderate protection [GPUNSEC3] [ZONEENUM] ๐Ÿค“

2.4. Salt

NSEC3 records come with an extra salt value, which can be combined with a Fully Qualified Domain Name (FQDN) to influence the resulting hash. The properties of this extra salt are pretty complicated, so buckle up ๐ŸŽข

In cryptography, salts generally add a layer of protection against offline, stored dictionary attacks by mixing the value to be hashed with a unique "salt" value. This stops adversaries from building and keeping one dictionary that can turn a hash output back into the value it came from ๐Ÿ”

DNS is a different story. The hashed names in NSEC3 records are always implicitly "salted" by hashing the FQDN from each zone. So no single pre-computed table speeds up dictionary attacks against multiple target zones. An attacker has to compute a complete dictionary for each zone, which is expensive in both storage and CPU time ๐Ÿ’ธ

To get the role of the extra NSEC3 salt field, we need to look at how a typical zone walking attack works. It usually has two phases, online and offline. In the online phase, an attacker "walks the zone" by enumerating (almost) all the hashes in the NSEC3 records and storing them for later. Then, in the offline cracking phase, the attacker tries to crack the underlying hash. Here's the key thing: the extra salt value only raises the cost of the attack if the salt changes during the online phase. In other words, a constant extra salt value doesn't change the cost of the attack at all ๐Ÿ™ƒ

Changing a zone's salt means building a complete new NSEC3 chain. That's true whether you re-sign the whole zone at once or sign it incrementally in the background, where the new salt only turns on once every name in the chain has been done. So re-salting is a very complex operation, with big CPU time, memory, and bandwidth costs. Re-salting very often isn't practical, and the extra salt field ends up basically useless ๐Ÿซ 

3. Recommendations for Deploying and Validating NSEC3 Records ๐Ÿ’œ

The next subsections give recommendations for the different operating realms within the DNS. That's where we get into the actual "do this" advice, so stay tuned for part 2 ๐Ÿฆ‹

3.1. Best Practice for Zone Publishers ๐Ÿ’…

Okay bestie, first things first ๐ŸŽ€. If you don't actually need the operational or security features NSEC3 brings, then NSEC SHOULD be used in preference to NSEC3. NSEC3 asks for more computational power (see Appendix B) from both authoritative servers and validating clients ๐Ÿ˜ญ. Finding matching NSEC3 records for randomly generated prefixes in a DNS zone is genuinely complicated, and NSEC kinda sidesteps that whole mess โœจ. If you still need NSEC3, then an iterations count of 0 MUST be used to keep the compute burden chill. Extra iteration counts other than 0 make CPU-exhausting DoS attacks hit harder, and they also raise the risk of interoperability problems ๐Ÿ’€.

Deploying NSEC with minimally covering NSEC records [RFC4470] also has a cost, so zone owners should measure the computational difference between deploying [RFC4470] and deploying NSEC3 ๐Ÿงฎ.

Okay, so across all zones, the recommended NSEC3 parameters look like this ๐Ÿ“:

; SHA-1, no extra iterations, empty salt:
;
bcp.example. IN NSEC3PARAM 1 0 0 -

For small zones, using opt-out-based NSEC3 records is NOT RECOMMENDED ๐Ÿ™…โ€โ™€๏ธ. For very large and sparsely signed zones, where most of the records are insecure delegations, opt-out MAY be used ๐ŸŒธ.

Operators SHOULD NOT use a salt by indicating a zero-length salt value instead (represented as a "-" in the presentation format) ๐Ÿ™ˆ.

If you do use salts, keep in mind that the NSEC3PARAM RR isn't used by validating resolvers (see Section 4 of [RFC5155]). That means the iterations and salt parameters can be changed without waiting for RRsets to expire from caches. But the catch is that a complete new NSEC3 chain has to be constructed and the full zone re-signed ๐Ÿ”.


3.2. Recommendation for Validating Resolvers ๐Ÿง 

Open (public) DNSSEC validating resolvers have been growing like crazy, and they're often squeezed on compute when anonymous clients come knocking. So this document recommends that validating resolvers lower their iteration count limits over time ๐Ÿ“‰. Specifically, validating resolver operators and validating resolver software implementers are encouraged to keep an eye on NSEC3 iteration count deployment trends and keep lowering their acceptable iteration limits as time goes on.

Here's the tea โ˜•: treating a high iterations count as insecure leaves zones open to attack. So validating resolver operators and validating resolver software implementers are further encouraged to lower their default limit for returning SERVFAIL when processing NSEC3 parameters with large iteration count values. Check out Appendix A for measurements taken near the time this document was published, plus some potential starting points ๐Ÿ”.

Validating resolvers MAY return an insecure response to their clients when processing NSEC3 records with iterations larger than 0. But note this: a validating resolver returning an insecure response MUST still validate the signature over the NSEC3 record, so you can be sure the iteration count wasn't altered since the record was published (see Section 10.3 of [RFC5155]) ๐Ÿ”.

Validating resolvers MAY also return a SERVFAIL response when processing NSEC3 records with iterations larger than 0. They MAY choose to ignore authoritative server responses with iteration counts greater than 0, which will likely end up returning a SERVFAIL to the client when no acceptable responses come back from the authoritative servers ๐Ÿ™ƒ.

Validating resolvers that return an insecure or SERVFAIL answer to their client after receiving and validating an unsupported NSEC3 parameter from the authoritative server(s) SHOULD return an Extended DNS Error (EDE) [RFC8914] EDNS0 option of value 27 ๐Ÿท๏ธ. Validating resolvers that choose to ignore a response with an unsupported iteration count (and that don't validate the signature) MUST NOT return this EDE option. Don't be that resolver ๐Ÿ™….

Note that this specification updates [RFC5155] by significantly decreasing the requirements originally specified in Section 10.3 of [RFC5155]. For arguments on how to handle responses with a non-zero iteration count, see the Security Considerations (Section 4) ๐Ÿ“–.


3.3. Recommendation for Primary and Secondary Relationships ๐Ÿค

Primary and secondary authoritative servers for a zone that aren't run by the same operational staff, and/or don't use the same software and configuration, must take into account the potential differences in NSEC3 iteration support ๐Ÿ‘ฏ.

Operators of secondary services should advertise the parameter limits their servers support. On the flip side, operators of primary servers need to make sure their secondaries support the NSEC3 parameters they expect to use in their zones. To keep things reliable, after primaries change their iteration counts, they should query their secondaries with known nonexistent labels to verify the secondary servers are responding as expected ๐Ÿ”Žโœจ.


4. Security Considerations ๐Ÿ”’

This entire document discusses security considerations with various parameter selections of NSEC3 and NSEC3PARAM fields ๐Ÿ›ก๏ธ.

This is the part that's dramatic ๐Ÿ˜ค. The point where a validating resolver returns insecure versus the point where it returns SERVFAIL must be considered carefully. Say a validating resolver treats a zone as insecure above a particular value (like 100), and returns SERVFAIL above a much higher point (like 500). Then it leaves the zone open to attacker-in-the-middle attacks as if the zone were unsigned between those values ๐Ÿ’€. So validating resolver operators and software implementers SHOULD set the point above which a zone is treated as insecure, for certain NSEC3 iteration values, to the same point where the validating resolver starts returning SERVFAIL ๐Ÿšจ.


5. Operational Considerations ๐Ÿ› ๏ธ

This entire document discusses operational considerations with various parameter selections of NSEC3 and NSEC3PARAM fields ๐Ÿง‘โ€๐Ÿ’ป.


6. IANA Considerations ๐Ÿ“‹

IANA has allocated the following code in the First Come First Served range [RFC8126] of the "Extended DNS Error Codes" registry within the "Domain Name System (DNS) Parameters" registry ๐ŸŽ‰:

INFO-CODE:  27
Purpose:  Unsupported NSEC3 iterations value
Reference:  RFC 9276

7. References ๐Ÿ“š

7.1. Normative References

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, https://www.rfc-editor.org/info/rfc2119.

[RFC4035] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose, "Protocol Modifications for the DNS Security Extensions", RFC 4035, DOI 10.17487/RFC4035, March 2005, https://www.rfc-editor.org/info/rfc4035.

[RFC4470] Weiler, S. and J. Ihren, "Minimally Covering NSEC Records and DNSSEC On-line Signing", RFC 4470, DOI 10.17487/RFC4470, April 2006, https://www.rfc-editor.org/info/rfc4470.

[RFC5155] Laurie, B., Sisson, G., Arends, R., and D. Blacka, "DNS Security (DNSSEC) Hashed Authenticated Denial of Existence", RFC 5155, DOI 10.17487/RFC5155, March 2008, https://www.rfc-editor.org/info/rfc5155.

[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, https://www.rfc-editor.org/info/rfc8174.

[RFC8914] Kumari, W., Hunt, E., Arends, R., Hardaker, W., and D. Lawrence, "Extended DNS Errors", RFC 8914, DOI 10.17487/RFC8914, October 2020, https://www.rfc-editor.org/info/rfc8914.

7.2. Informative References

[GPUNSEC3] Wander, M., Schwittmann, L., Boelmann, C., and T. Weis, "GPU-Based NSEC3 Hash Breaking", DOI 10.1109/NCA.2014.27, August 2014, https://doi.org/10.1109/NCA.2014.27.

[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 8126, DOI 10.17487/RFC8126, June 2017, https://www.rfc-editor.org/info/rfc8126.

[RFC8624] Wouters, P. and O. Sury, "Algorithm Implementation Requirements and Usage Guidance for DNSSEC", RFC 8624, DOI 10.17487/RFC8624, June 2019, https://www.rfc-editor.org/info/rfc8624.

[ZONEENUM] Wang, Z., Xiao, L., and R. Wang, "An efficient DNSSEC zone enumeration algorithm", DOI 10.2495/MIIT130591, April 2014, https://doi.org/10.2495/MIIT130591.


Appendix A. Deployment Measurements at Time of Publication ๐Ÿ“Š

At the time of publication, setting an upper limit of 100 iterations for treating a zone as insecure is interoperable without significant problems. But at the same time, it still enables CPU-exhausting DoS attacks ๐Ÿ˜ฌ.

At the time of publication, returning SERVFAIL beyond 500 iterations appears to be interoperable without significant problems โœ….


Appendix B. Computational Burdens of Processing NSEC3 Iterations ๐Ÿงฎ

The queries per second (QPS) of authoritative servers will decrease because of computational overhead when they process DNS requests for zones with higher NSEC3 iteration counts. The table below shows the drop in QPS for various iteration counts ๐Ÿ“‰.

           +============+=============================+
           | Iterations | QPS [% of 0 Iterations QPS] |
           +============+=============================+
           | 0          | 100%                        |
           +------------+-----------------------------+
           | 10         | 89%                         |
           +------------+-----------------------------+
           | 20         | 82%                         |
           +------------+-----------------------------+
           | 50         | 64%                         |
           +------------+-----------------------------+
           | 100        | 47%                         |
           +------------+-----------------------------+
           | 150        | 38%                         |
           +------------+-----------------------------+

Table 1: Drop in QPS for Various Iteration Counts


Acknowledgments ๐Ÿซถ

The authors would like to thank the participants in the dns-operations discussion, which took place on mattermost hosted by DNS-OARC ๐Ÿ’œ.

Additionally, the following people contributed text or review comments to this document ๐ŸŒˆ:

  • Vladimir Cunat
  • Tony Finch
  • Paul Hoffman
  • Warren Kumari
  • Alexander Mayrhofer
  • Matthijs Mekking
  • Florian Obser
  • Petr Spacek
  • Paul Vixie
  • Tim Wicinski

Authors' Addresses โœ‰๏ธ

Wes Hardaker USC/ISI Email: ietf@hardakers.net

Viktor Dukhovni Bloomberg, L.P. Email: ietf-dane@dukhovni.org

๐Ÿ“ฆ where this page comes from