Why does DNSSEC's NSEC record let anyone list every name in a signed zone, and what does NSEC3 change about it?
answer
- each record names a neighbour
- the chain loops back to the apex
- hash the owner names instead
- guessing still works offline
basics
~20 sEach NSEC names the next existing name, so following the chain from the apex lists the whole zone. NSEC3 hashes owner names with SHA-1, so the chain shows hashes, not names, though guessable names still fall to offline dictionary attacks.
solid answer
~50 sAn `NSEC` record's **Next Domain Name** is the next real name in canonical order, so a party that keeps asking for names inside successive gaps collects the zone's complete list. RFC 4033 calls this out: not an attack on DNS itself, but a way to map hosts, and it sidesteps a policy of refusing zone transfers. `NSEC3` (RFC 5155) replaces each owner name with a SHA-1 hash (hash algorithm 1) of the name and a salt, base32hex-encoded as one label under the zone, and chains the hashes in hash order. A walker then collects hashes and type bitmaps rather than names. That raises the cost without closing the gap: anyone can hash candidate names offline and compare, and RFC 9276 notes most published names are guessable. `NSEC3` also still reveals how many names exist and which record types they hold.
go deeper
Remember that DNSSEC proves data is genuine but keeps nothing secret, and that NSEC records can reveal a zone's full name list.
Explain how the Next Domain Name field enables walking, how NSEC3 hashes owner names into a hash-ordered chain, and what an offline dictionary attack still recovers.
Judge whether enumeration matters for a given zone, cite RFC 9276's parameters, and know that only online minimally covering answers truly stop walking.
Frame the choice as disclosure policy against cost: cleartext simplicity, hashed obscurity with validator CPU, or online signing with keys on the servers.
## Why a plain NSEC chain exposes the zone An `NSEC` record (type 47) proves a gap by naming both ends: its owner name and its **Next Domain Name**, the next existing name in canonical order. That is exactly what makes a negative answer verifiable - and exactly what makes it informative. Every negative response hands out one more pair of real names, and the last record points back to the apex, so the chain is a closed list of everything in the zone. RFC 4033's security considerations say it plainly: DNSSEC "introduces the ability for a hostile party to enumerate all the names in a zone by following the NSEC chain". It adds that this is not an attack on the DNS itself, but it lets an outsider map hosts and resources. RFC 4470 points out the operational sting: an operator who refuses zone transfers (`AXFR`) to strangers finds the `NSEC` chain gives the same list away. ## Does it matter? - DNSSEC was deliberately designed **without confidentiality** (RFC 4033). Names in public DNS are meant to be looked up; they also leak through mail headers, certificate logs and links (RFC 9276 section 2.3). - RFC 6781 (Informational) notes that structured zones such as `in-addr.arpa` reverse zones can be enumerated with ordinary queries anyway, and a tiny zone with only `www` and `mail` is trivially guessed. - Some operators still have policy, regulatory or contractual reasons - RFC 6781 cites zones whose list is only available under a non-disclosure agreement. For them, `NSEC` is a real disclosure. ## What NSEC3 changes `NSEC3` (type 50, RFC 5155) keeps the chain-of-gaps idea but builds it over **hashes**: | | `NSEC` | `NSEC3` | |---|---|---| | Owner name | the real name | base32hex of the hash, prepended as one label to the zone name | | Points to | Next Domain Name (cleartext) | Next Hashed Owner Name (binary hash) | | Order | canonical DNS name order | hash order | | A walker learns | every name | every hash, plus each name's types | | Extra cost | none beyond the signature check | hashing on the server and in every validator | | Opt-out for unsigned delegations | no | yes | The hash is computed as `IH(salt, x, 0) = H(x || salt)`, repeated once more for each extra **iteration**, where `x` is the full owner name in canonical wire form. RFC 5155 defines one hash algorithm, SHA-1 (value 1), giving 20-octet hashes and 32-character labels. A companion record, `NSEC3PARAM` (type 51) at the apex, tells authoritative servers which algorithm, iteration count and salt the chain uses; validators read the parameters inside each `NSEC3`, not `NSEC3PARAM`. ## What NSEC3 does not hide 1. **Guessable names.** RFC 5155 section 12.1.1 concedes that an attacker can collect the hashes and then hash likely names offline, comparing results. RFC 9276 adds that GPU-based studies show `NSEC3` gives only moderate protection, and a short dictionary of common prefixes (`www`, `mail`, `login`) recovers many labels. 2. **Size and shape.** RFC 6781 notes `NSEC3` still reveals the number of names and which types exist. 3. **Salt and iterations do little.** Because the full zone name is hashed, a dictionary built for one zone is useless for another - the zone name already acts as a per-zone salt. A constant extra salt adds nothing, and extra iterations cost defenders as much as attackers; RFC 9276 sets the recommended parameters to SHA-1, no extra iterations, empty salt (`1 0 0 -`). ## Choosing between them - If the zone's names are guessable or already public, prefer `NSEC`: it is simpler and cheaper, and RFC 9276 says `NSEC` SHOULD be used when `NSEC3`'s features are not needed. - If a policy requires the list not be handed out on request, or the zone needs opt-out for masses of unsigned delegations, use `NSEC3` with the RFC 9276 parameters - accepting that it is a speed bump, not a wall. - If enumeration must genuinely stop, only **minimally covering** records generated per query by an online signer (RFC 4470, or RFC 9824 compact denial) do that, at the price of keeping signing keys on the servers. The defender's summary: `NSEC` publishes the list outright, `NSEC3` publishes a hashed list that a determined party can largely reverse, and neither encrypts anything.
- If NSEC3 hashes can be guessed offline, what actually stops a signed zone being enumerated?Records whose span covers only the queried name, generated and signed per query by an online signer: minimally covering `NSEC` (RFC 4470), the `NSEC3` variant dubbed 'white lies', or RFC 9824 compact denial. Walking then takes about as many queries as guessing every name. The price is private keys on internet-facing servers, signing work per negative answer, and no reusable spans for resolvers.
- Why does NSEC3 hash the fully qualified name rather than just the leftmost label?Hashing the full name in canonical form makes every zone's hash space different: `www.example.org` and `www.example.net` hash to unrelated values, so a precomputed dictionary for one zone cannot be reused on another. RFC 9276 calls this an implicit salt, which is one reason it judges the explicit salt field to add little.
saying these in an interview costs you the question
- Signing a zone with DNSSEC keeps its names private, because DNSSEC encrypts the data.
- NSEC3 makes listing a zone's names impossible.
- Zone walking only works where the server allows zone transfers.
- A fixed NSEC3 salt stops offline guessing of the hashed names.
- NSEC3 hides how many names a zone contains.