An NSEC record lists the next existing name in a zone, and thus makes it trivial to retrieve all the names from the zone. This can also be done with NSEC3, but an adversary will then retrieve all the hashed names. With DNSSEC on-line signing, zone walking can be prevented by faking the next owner name.
To prevent retrieval of the next owner name with NSEC, a different, non-existing (according to the existence rules in []#RFC4592, Section 2.2) name is used. However, not just any name can be used because a validator may make assumptions on the size of the span the NSEC record covers. The span must be large enough to cover the QNAME, but not too large that it covers existing names.
introduces a scheme for generating minimally covering NSEC records. These records use a next owner name that is lexically closer to the NSEC owner name than the actual next owner name, ensuring that no existing names are covered. The next owner name can be derived from the QNAME with the use of so-called epsilon functions.
For example, to deny the existence of b.example.org
in the zone from
, the following NSEC record could have been generated:
a.example.org. NSEC c.example.org. RRSIG NSEC
This record also proves that b.example.org
also does not exist, but an
adversary cannot use the next owner name in a zone walking attack. Note the
type bitmap only has the RRSIG and NSEC set, because states:
The generated NSEC record's type bitmap MUST have the RRSIG and NSEC bits set and SHOULD NOT have any other bits set.
This is because the NSEC records may appear at names that did not exist
before the zone was signed. In this case however, a.example.org
exists
with other RR types and we could have also set the A and TXT types in the
bitmap.
Because DNS ordering is very strict, the span should be shortened to a minimum.
In order to do so, the last character in the leftmost label of the NSEC owner
name needs to be decremented and the label must be filled with octets of value
255 until the label length reaches the maximum of 63 octets. The next owner
name is the QNAME with a leading label with a single null octet added. This
gives the following minimally covering record for b.example.org
:
a\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255
\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255
\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255
\255\255\255\255\255\255\255\255\255\255\255.example.org. (
NSEC \000.b.example.org. RRSIG NSEC )
The same principle of minimally covering spans can be applied to NSEC3 records. This mechanism has been dubbed "NSEC3 White Lies" when it was implemented in Phreebird . Here, the NSEC3 owner name is the hash of the QNAME minus one and the next owner name is the hash of the QNAME plus one.
The following NSEC3 white lie denies b.example.org
(recall this hashes to
iuu8l5lmt76jeltp0bir3tmg4u3uu8e7
):
iuu8l5lmt76jeltp0bir3tmg4u3uu8e6.example.org. (
NSEC3 1 0 2 DEAD IUU815LMT76JELTP0BIR3TMG4U3UU8E8 )
The type bitmap is empty in this case. If the hash of b.example.org
- 1 is a
collision with an existing name, the bitmap should have been filled with the
RR types that exist at that name. This record actually denies the existence
of the next closer name (which is
conveniently b.example.org
). Of course the NSEC3 records to match the
closest encloser and the one to deny the wildcard are still required.
These can be generated too:
# Matching `example.org`: `15bg9l6359f5ch23e34ddua6n1rihl9h`
15bg9l6359f5ch23e34ddua6n1rihl9h.example.org. (
NSEC3 1 0 2 DEAD 15BG9L6359F5CH23E34DDUA6N1RIHL9I NS SOA RRSIG
DNSKEY NSEC3PARAM )
# Covering `*.example.org`: `22670trplhsr72pqqmedltg1kdqeolb7`
22670trplhsr72pqqmedltg1kdqeolb6.example.org.(
NSEC3 1 0 2 DEAD 22670TRPLHSR72PQQMEDLTG1KDQEOLB8 )
The following owner names are used in this document. The
origin for these names is example.org
.
Original Name Hashed Name
a
04sknapca5al7qos3km2l9tl3p5okq4c
1.h
117gercprcjgg8j04ev1ndrk8d1jt14k
@
15bg9l6359f5ch23e34ddua6n1rihl9h
h
1avvqn74sg75ukfvf25dgcethgq638ek
*
22670trplhsr72pqqmedltg1kdqeolb7
3
75b9id679qqov6ldfhd8ocshsssb6jvq
2
7t70drg4ekc28v93q7gnbleopa7vlp6q
3.3
8555t7qegau7pjtksnbchg4td2m0jnpj
d
a6edkb6v8vl5ol8jnqqlt74qmj7heb84
*.2
fbq73bfkjlrkdoqs27k5qf81aqqd7hho
b
iuu8l5lmt76jeltp0bir3tmg4u3uu8e7
x.2
ndtu6dste50pr4a1f2qvr1v31g00i2i1
^[tab:hashed-owner::Hashed owner names for "example.org" in hash order.]
[This section should be removed by the RFC editor before publishing]
- Initial document.
- Style and language changes;
- Figure captions;
- Security considerations added;
- Fix erroneous NSEC3 RR;
- Section on CNAMEs added;
- More detailed text on closest encloser proof.
- Lowercase NSEC3 hashed ownernames and add reference to Base32;
- Process the comments from Joe Abley and Geoff Huston.
- Added section about Opt-Out;
- Move experimental records in their own section;
- Added DNAME reference with respect to wildcards;
- Clarify the difference between the wildcard answers;
- Add more context about the NO record;
- Elaborate more about the EXIST records and its problems;
- Added more text about the NSEC3PARAM records;
- Apply assorted fixes throughout the document;
- Moved table with hashed owner names to appendix.
- Changed affiliation for R. Gieben;
- Some minor updates.
- Added NS record in all zone examples;
- Some tweaks in the text regarding on-line signing;
- Add more text on a non-working "generic non-existence records".
- Add appendix on on-line signing;
- Add text on usefulness of NSEC3.
- Minor fixes and adjustments.