A DNSSEC zone signed with NSEC3PARAM 1 0 100 AABBCCDD gets insecure or SERVFAIL negative answers from some validating resolvers; why, and what does RFC 9276 say to set?
answer
- hash work on every negative answer
- a resolver's iteration ceiling
- a salt that never changes
- RFC 9276, BCP 236
basics
~20 sEvery extra NSEC3 iteration adds hashing to each negative answer for servers and validators, so resolvers may treat counts above 0 as insecure or fail them. RFC 9276 requires 0 extra iterations and advises an empty salt: 1 0 0 -.
solid answer
~50 sThe Iterations field counts *additional* SHA-1 rounds, so `100` means 101 hashes per name - work the authoritative server does for every negative or wildcard answer and every validator repeats when checking one. RFC 9276 (BCP 236) found the extra rounds buy little, since guessable names fall to an offline dictionary anyway, while they cut throughput (about 47% of the zero-iteration rate at 100 in its measurements) and widen a CPU-exhaustion target. So: if you use `NSEC3`, iterations `MUST` be 0, and you `SHOULD NOT` use a salt - the hashed full name already makes each zone's dictionary unique, and a constant salt adds nothing. Validators `MAY` treat a count above 0 as insecure, or return SERVFAIL, ideally with Extended DNS Error 27. Re-sign with `NSEC3PARAM 1 0 0 -` and confirm every secondary serves the new chain.
code
dns · 5 lines; before: 100 extra SHA-1 rounds and a fixed 4-octet salt
example.org. IN NSEC3PARAM 1 0 100 AABBCCDD
; after: RFC 9276 parameters - SHA-1, no extra iterations, empty salt
example.org. IN NSEC3PARAM 1 0 0 -go deeper
Recall that NSEC3 hashes names, that its parameters are an algorithm, flags, an iteration count and a salt, and that today's advice is zero extra iterations and no salt.
Explain the iterated hash, why an Iterations value of 0 still means one hash, and why a hashed full name already gives each zone its own dictionary.
Diagnose insecure or SERVFAIL negative answers from an iteration limit, cite RFC 9276 and Extended DNS Error 27, and run the re-sign including a check of every secondary.
Treat NSEC3 parameters as an ecosystem cost: every validator pays for your iterations, so the defensible choice is the one that adds the least work for no real protection.
## Reading the record `NSEC3PARAM` (type 51, RFC 5155 section 4) sits at the zone apex and tells authoritative servers which `NSEC3` chain to use when building negative answers. Its presentation format is four fields: | Field | Value here | Meaning | |---|---|---| | Hash Algorithm | `1` | SHA-1, the one hash algorithm RFC 5155 defines | | Flags | `0` | must be zero; an `NSEC3PARAM` with any other value is ignored | | Iterations | `100` | 100 hashing rounds **after** the first | | Salt | `AABBCCDD` | four octets, hex; `-` means an empty salt | Validators never read `NSEC3PARAM`; they take the same parameters from each `NSEC3` record in a response. Those are the values that cost them work. ## What iterations cost and what they buy RFC 5155 section 5 defines the hash as: ```pseudocode IH(salt, x, 0) = H(x || salt) IH(salt, x, k) = H(IH(salt, x, k-1) || salt) for k > 0 hashed owner = IH(salt, canonical owner name, iterations) ``` So an Iterations value of 0 still means one SHA-1 computation, and 100 means 101. An authoritative server computes these for each negative or wildcard response, and a validator recomputes them for every name it checks - a closest encloser proof alone involves several candidate names. RFC 9276 Appendix B measured authoritative throughput against the zero-iteration rate: | Extra iterations | Queries per second | |---|---| | 0 | 100% | | 10 | 89% | | 50 | 64% | | 100 | 47% | | 150 | 38% | What the cost buys is small. RFC 9276 section 2.3 argues that a determined party cracks the guessable names regardless of the count, because names are chosen to be memorable and leak elsewhere. RFC 5155 originally allowed up to 150, 500 or 2,500 iterations depending on the zone-signing key's size; RFC 9276 updates RFC 5155 and lowers that sharply. ## Why the salt is functionally useless - The full owner name, zone included, is hashed, so no precomputed table works across zones - every zone is already implicitly salted. - A walker collects the hashes once and cracks them offline. A salt only raises the cost if it **changes during collection**; a constant salt changes nothing. - Changing the salt means building and signing a complete new `NSEC3` chain, so frequent re-salting is impractical. RFC 9276 concludes that operators `SHOULD NOT` use a salt. - This reverses older advice: RFC 5155 section 12.1.1 asked for a salt of at least 64 bits, unpredictable and changed regularly to defeat precomputed dictionaries. RFC 9276 found the regular change impractical and the constant salt useless, so the older advice is history. ## Why some resolvers reject this zone RFC 9276 section 3.2 gives validating resolvers three options for iterations above 0: 1. Return an **insecure** answer, but only after validating the `NSEC3` signature, so an attacker cannot simply raise the count in transit. 2. Return **SERVFAIL**. 3. Ignore servers sending such counts, which usually ends in SERVFAIL too. In the first two cases the resolver `SHOULD` attach Extended DNS Error **27**, "Unsupported NSEC3 iterations value". RFC 9276 also asks resolvers to keep their insecure and SERVFAIL thresholds equal, because between them the zone is validated as if unsigned and open to forged answers. Its Appendix A recorded that, at publication, treating counts above 100 as insecure and failing those above 500 were interoperable starting points, with limits expected to fall. RFC 5155 section 12.1.4 adds a downgrade risk: one signed high-iteration `NSEC3` in a zone gives an on-path attacker a record that pushes validators to "insecure". ## Fixing the zone 1. Decide whether `NSEC3` is needed at all: RFC 9276 says `NSEC` `SHOULD` be used when `NSEC3`'s features are not. 2. If it is, re-sign with `NSEC3PARAM 1 0 0 -`. That builds a complete new chain, but because validators do not use `NSEC3PARAM`, there is no cache-expiry wait for the parameter change itself. 3. Check every secondary: RFC 9276 section 3.3 asks primaries to query their secondaries with known nonexistent labels after an iteration change, since a secondary run by another team may support different limits. 4. Watch for Extended DNS Error 27 in answers from validating resolvers you can query; its disappearance after the re-sign is a sign the new chain is reaching them. 5. Treat opt-out as a separate decision; the `NSEC3PARAM` flags stay 0 either way.
- Why should a validating resolver's 'treat as insecure' and 'return SERVFAIL' iteration limits be the same number?Between the two limits, the resolver validates the zone as unsigned, so an on-path attacker can forge answers the zone's owner signed. RFC 9276 section 4 gives the example of insecure above 100 and SERVFAIL above 500 and says implementers SHOULD set both points equal.
- Does changing an NSEC3 zone's salt or iteration count require waiting for resolver caches to expire?Not for the parameter change itself: validators do not read `NSEC3PARAM`, so RFC 9276 notes no wait for cached RRsets is needed. The zone still needs a complete new `NSEC3` chain and a full re-sign, which is why frequent re-salting is impractical.
saying these in an interview costs you the question
- An NSEC3 Iterations value of 0 means the owner names are not hashed at all.
- More NSEC3 iterations meaningfully protect guessable names from offline cracking.
- A fixed NSEC3 salt protects names the way a password salt protects a password file.
- RFC 5155 allows up to 2,500 iterations, so 100 is a conservative, safe choice.
- Validating resolvers learn the hash parameters from the apex NSEC3PARAM record.