RFC 4035

Protocol Modifications for the DNS Security Extensions

πŸ“… published March 2005, from ietf

Protocol Modifications for the DNS Security Extensions πŸŽ€

Part 1 of 12, more coming bestie! πŸ’–

Okay so this one is written by five people, and the title block is doing a LOT of work. It's RFC 4035, and it was written by R. Arends at Telematica Instituut, R. Austein at ISC, M. Larson at VeriSign, D. Massey at Colorado State University, and S. Rose at NIST. It's part of the Network Working Group series, it's dated March 2005, and it's on the Standards Track πŸ”₯. It obsoletes RFC 2535, 3008, 3090, 3445, 3655, 3658, 3755, 3757, and 3845. It also updates RFC 1034, 1035, 2136, 2181, 2308, 3225, 3007, 3597, and 3226. Sooo many RFCs being glowed up at once πŸ’…βœ¨

Status of This Memo 🌸

This document specifies an Internet standards track protocol for the Internet community, and it's asking for discussion and suggestions for improvements 🫢. If you want to know where this protocol stands in terms of standardization, check the current edition of the "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited, so share the tea πŸ“.

Copyright (C) The Internet Society (2005).

Abstract πŸ’œ

This document is part of a family of documents that describe the DNS Security Extensions (DNSSEC) πŸ”. DNSSEC is a collection of new resource records and protocol modifications that add data origin authentication and data integrity to the DNS, which is literally the main character glow-up we needed πŸ‘‘. This document describes the DNSSEC protocol modifications and defines the concept of a signed zone, along with the requirements for serving and resolving with DNSSEC. These techniques let a security-aware resolver authenticate both DNS resource records and authoritative DNS error indications. Iconic, no notes 😭

This document obsoletes RFC 2535 and incorporates changes from all updates to RFC 2535.

Table of Contents 🧚

   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
       1.1.  Background and Related Documents . . . . . . . . . . . .  4
       1.2.  Reserved Words . . . . . . . . . . . . . . . . . . . . .  4
   2.  Zone Signing . . . . . . . . . . . . . . . . . . . . . . . . .  4
       2.1.  Including DNSKEY RRs in a Zone . . . . . . . . . . . . .  5
       2.2.  Including RRSIG RRs in a Zone  . . . . . . . . . . . . .  5
       2.3.  Including NSEC RRs in a Zone . . . . . . . . . . . . . .  6
       2.4.  Including DS RRs in a Zone . . . . . . . . . . . . . . .  7
       2.5.  Changes to the CNAME Resource Record.  . . . . . . . . .  7
       2.6.  DNSSEC RR Types Appearing at Zone Cuts.  . . . . . . . .  8
       2.7.  Example of a Secure Zone . . . . . . . . . . . . . . . .  8
   3.  Serving  . . . . . . . . . . . . . . . . . . . . . . . . . . .  8
       3.1.  Authoritative Name Servers . . . . . . . . . . . . . . .  9
             3.1.1.  Including RRSIG RRs in a Response  . . . . . . . 10
             3.1.2.  Including DNSKEY RRs in a Response . . . . . . . 11
             3.1.3.  Including NSEC RRs in a Response . . . . . . . . 11
             3.1.4.  Including DS RRs in a Response . . . . . . . . . 14
             3.1.5.  Responding to Queries for Type AXFR or IXFR  . . 15
             3.1.6.  The AD and CD Bits in an Authoritative Response. 16
       3.2.  Recursive Name Servers . . . . . . . . . . . . . . . . . 17
             3.2.1.  The DO Bit . . . . . . . . . . . . . . . . . . . 17
             3.2.2.  The CD Bit . . . . . . . . . . . . . . . . . . . 17
             3.2.3.  The AD Bit . . . . . . . . . . . . . . . . . . . 18
       3.3.  Example DNSSEC Responses . . . . . . . . . . . . . . . . 19
   4.  Resolving  . . . . . . . . . . . . . . . . . . . . . . . . . . 19
       4.1.  EDNS Support . . . . . . . . . . . . . . . . . . . . . . 19
       4.2.  Signature Verification Support . . . . . . . . . . . . . 19
       4.3.  Determining Security Status of Data  . . . . . . . . . . 20
       4.4.  Configured Trust Anchors . . . . . . . . . . . . . . . . 21
       4.5.  Response Caching . . . . . . . . . . . . . . . . . . . . 21
       4.6.  Handling of the CD and AD Bits . . . . . . . . . . . . . 22
       4.7.  Caching BAD Data . . . . . . . . . . . . . . . . . . . . 22
       4.8.  Synthesized CNAMEs . . . . . . . . . . . . . . . . . . . 23
       4.9.  Stub Resolvers . . . . . . . . . . . . . . . . . . . . . 23
             4.9.1.  Handling of the DO Bit . . . . . . . . . . . . . 24
             4.9.2.  Handling of the CD Bit . . . . . . . . . . . . . 24
             4.9.3.  Handling of the AD Bit . . . . . . . . . . . . . 24
   5.  Authenticating DNS Responses . . . . . . . . . . . . . . . . . 25
       5.1.  Special Considerations for Islands of Security . . . . . 26
       5.2.  Authenticating Referrals . . . . . . . . . . . . . . . . 26
       5.3.  Authenticating an RRset with an RRSIG RR . . . . . . . . 28
             5.3.1.  Checking the RRSIG RR Validity . . . . . . . . . 28
             5.3.2.  Reconstructing the Signed Data . . . . . . . . . 29
             5.3.3.  Checking the Signature . . . . . . . . . . . . . 31
             5.3.4.  Authenticating a Wildcard Expanded RRset
                     Positive Response. . . . . . . . . . . . . . . . 32

       5.4.  Authenticated Denial of Existence  . . . . . . . . . . . 32
       5.5.  Resolver Behavior When Signatures Do Not Validate  . . . 33
       5.6.  Authentication Example . . . . . . . . . . . . . . . . . 33
   6.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 33
   7.  Security Considerations  . . . . . . . . . . . . . . . . . . . 33
   8.  Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 34
   9.  References . . . . . . . . . . . . . . . . . . . . . . . . . . 34
       9.1.  Normative References . . . . . . . . . . . . . . . . . . 34
       9.2.  Informative References . . . . . . . . . . . . . . . . . 35
   A.  Signed Zone Example  . . . . . . . . . . . . . . . . . . . . . 36
   B.  Example Responses  . . . . . . . . . . . . . . . . . . . . . . 41
       B.1.  Answer . . . . . . . . . . . . . . . . . . . . . . . . . 41
       B.2.  Name Error . . . . . . . . . . . . . . . . . . . . . . . 43
       B.3.  No Data Error  . . . . . . . . . . . . . . . . . . . . . 44
       B.4.  Referral to Signed Zone  . . . . . . . . . . . . . . . . 44
       B.5.  Referral to Unsigned Zone  . . . . . . . . . . . . . . . 45
       B.6.  Wildcard Expansion . . . . . . . . . . . . . . . . . . . 46
       B.7.  Wildcard No Data Error . . . . . . . . . . . . . . . . . 47
       B.8.  DS Child Zone No Data Error  . . . . . . . . . . . . . . 48
   C.  Authentication Examples  . . . . . . . . . . . . . . . . . . . 49
       C.1.  Authenticating an Answer . . . . . . . . . . . . . . . . 49
             C.1.1.  Authenticating the Example DNSKEY RR . . . . . . 49
       C.2.  Name Error . . . . . . . . . . . . . . . . . . . . . . . 50
       C.3.  No Data Error  . . . . . . . . . . . . . . . . . . . . . 50
       C.4.  Referral to Signed Zone  . . . . . . . . . . . . . . . . 50
       C.5.  Referral to Unsigned Zone  . . . . . . . . . . . . . . . 51
       C.6.  Wildcard Expansion . . . . . . . . . . . . . . . . . . . 51
       C.7.  Wildcard No Data Error . . . . . . . . . . . . . . . . . 51
       C.8.  DS Child Zone No Data Error  . . . . . . . . . . . . . . 51
   Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 52
   Full Copyright Statement . . . . . . . . . . . . . . . . . . . . . 53

1. Introduction ✨

Okay so the DNS Security Extensions (DNSSEC) are a collection of new resource records and protocol modifications that add data origin authentication and data integrity to the DNS πŸ”. This document defines the DNSSEC protocol modifications. Section 2 defines the concept of a signed zone and lists the requirements for zone signing. Section 3 describes the changes to authoritative name server behavior that are needed to handle signed zones. Section 4 describes what entities with security-aware resolver functions do. Finally, Section 5 explains how to use DNSSEC RRs to authenticate a response πŸ¦‹

This document is part of a family of documents defining DNSSEC, and they should all be read together as a set 🫢.

[RFC4033] has an introduction to DNSSEC and definitions of common terms, and it assumes you're already familiar with this document. Yes, the reader is assumed to know it πŸ™ˆ [RFC4033] also has a list of other documents that this document set updates and obsoletes.

[RFC4034] defines the DNSSEC resource records πŸ’…

You're also expected to be comfy with the basic DNS concepts from [RFC1034], [RFC1035], and the later documents that update them, especially [RFC2181] and [RFC2308] 🌈

This document defines the DNSSEC protocol operations ⭐

1.2. Reserved Words πŸŽ€

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] πŸ’œ

2. Zone Signing 🌸

DNSSEC brings in the concept of signed zones. A signed zone includes DNS Public Key (DNSKEY), Resource Record Signature (RRSIG), Next Secure (NSEC), and (optionally) Delegation Signer (DS) records, following the rules in Sections 2.1, 2.2, 2.3, and 2.4, in that order. A zone that doesn't include these records under the rules in this section is an unsigned zone πŸ“

DNSSEC needs a change to the definition of the CNAME resource record ([RFC1035]). Section 2.5 changes the CNAME RR so that RRSIG and NSEC RRs can show up at the same owner name as a CNAME RR does πŸ‘‘

DNSSEC also specifies where two new RR types go, NSEC and DS. They can be placed on the parental side of a zone cut (that is, at a delegation point). This is an exception to the general rule against putting data in the parent zone at a zone cut, so it's a whole vibe shift 😭 Section 2.6 describes this change.

2.1. Including DNSKEY RRs in a Zone πŸ”‘

To sign a zone, the zone's administrator generates one or more public/private key pairs and uses the private key(s) to sign authoritative RRsets in the zone 🧚 For each private key used to create RRSIG RRs in a zone, the zone SHOULD include a zone DNSKEY RR containing the corresponding public key. A zone key DNSKEY RR MUST have the Zone Key bit of the flags RDATA field set (see Section 2.1.1 of [RFC4034]). Public keys tied to other DNS operations MAY be stored in DNSKEY RRs that are not marked as zone keys, but they MUST NOT be used to verify RRSIGs. Not me having to remember all of this πŸ’€

If the zone administrator wants a signed zone to be usable other than as an island of security, the zone apex MUST contain at least one DNSKEY RR to act as a secure entry point into the zone. That secure entry point can then be the target of a secure delegation via a corresponding DS RR in the parent zone (see [RFC4034]) ✨

Part 1 complete, more parts coming, don't go anywhere! 🌈

2.2. Including RRSIG RRs in a Zone ✨

Okay bestie, so for every authoritative RRset in a signed zone, there MUST be at least one RRSIG record that meets these requirements 🫢

  • The RRSIG owner name lines up with the RRset owner name.
  • The RRSIG class matches the RRset class.
  • The RRSIG Type Covered field matches the RRset type.
  • The RRSIG Original TTL field matches the TTL of the RRset.
  • The RRSIG RR's TTL matches the TTL of the RRset.
  • The RRSIG Labels field matches the number of labels in the RRset owner name, not counting the null root label and not counting the leftmost label if it is a wildcard.
  • The RRSIG Signer's Name field matches the name of the zone containing the RRset.
  • The RRSIG Algorithm, Signer's Name, and Key Tag fields identify a zone key DNSKEY record at the zone apex.

The process for building the RRSIG RR for a given RRset is covered in [RFC4034] πŸ’…. An RRset MAY have multiple RRSIG RRs attached to it. Here's the iconic part πŸ‘‘: RRSIG RRs are so closely tied to the RRsets they sign that they don't form RRsets like every other DNS RR type does. So the TTL values among RRSIG RRs with a common owner name don't follow the RRset rules from [RFC2181]. Not me treating them differently, but it's literally the spec πŸ’€

An RRSIG RR itself MUST NOT be signed πŸ™ˆ. Signing an RRSIG would add no value and would create an infinite loop in the signing process. Bestie, nobody wants that loop.

The NS RRset at the zone apex name MUST be signed. But the NS RRsets at delegation points (the NS RRsets in the parent zone that delegate the name to the child zone's name servers) MUST NOT be signed 🌸. Glue address RRsets tied to delegations MUST NOT be signed either.

There MUST be an RRSIG for each RRset using at least one DNSKEY of each algorithm in the zone apex DNSKEY RRset. And the apex DNSKEY RRset itself MUST be signed by each algorithm showing up in the DS RRset at the delegating parent (if there is one) πŸ”₯

2.3. Including NSEC RRs in a Zone πŸ¦‹

Each owner name in the zone that has authoritative data or a delegation point NS RRset MUST have an NSEC resource record. The format of NSEC RRs and how to build the NSEC RR for a given name are described in [RFC4034] ✨

The TTL value for any NSEC RR SHOULD be the same as the minimum TTL value field in the zone SOA RR πŸŽ€

An NSEC record (and its associated RRSIG RRset) MUST NOT be the only RRset at any particular owner name. Put differently, the signing process MUST NOT create NSEC or RRSIG RRs for owner name nodes that weren't the owner name of any RRset before the zone got signed πŸ™…β€β™€οΈ The main reasons are namespace consistency between signed and unsigned versions of the same zone, plus cutting down the risk of response inconsistency in security oblivious recursive name servers. Very responsible of them, honestly πŸ’œ

The type bitmap of every NSEC resource record in a signed zone MUST indicate the presence of both the NSEC record itself and its corresponding RRSIG record 🧚

Okay, this difference is subtle but worth highlighting πŸ‘€. RRSIG records sit at the owner names of all authoritative RRsets. NSEC records sit at the owner names of all names the signed zone is authoritative for, plus the owner names of delegations from the signed zone to its children. Neither NSEC nor RRSIG records show up (in the parent zone) at the owner names of glue address RRsets. Note though that this distinction is mostly only visible during the zone signing process, since NSEC RRsets are authoritative data and therefore get signed. So any owner name with an NSEC RRset will also have RRSIG RRs in the signed zone πŸ’–

The bitmap for the NSEC RR at a delegation point needs special attention πŸ“. Bits for the delegation NS RRset and for any RRsets the parent zone has authoritative data for MUST be set. Bits for any non-NS RRset the parent is not authoritative for MUST be clear.

2.4. Including DS RRs in a Zone 🌈

The DS resource record is what builds authentication chains between DNS zones πŸ”— A DS RRset SHOULD be present at a delegation point when the child zone is signed. The DS RRset MAY contain multiple records, each one referencing a public key in the child zone that's used to verify the RRSIGs in that zone. All DS RRsets in a zone MUST be signed, and DS RRsets MUST NOT appear at a zone's apex πŸ™…β€β™€οΈ

A DS RR SHOULD point to a DNSKEY RR that's present in the child's apex DNSKEY RRset, and the child's apex DNSKEY RRset SHOULD be signed by the matching private key. DS RRs that fail these conditions aren't useful for validation. But since the DS RR and its DNSKEY RR live in different zones, and the DNS is only loosely consistent, temporary mismatches can happen. Not a disaster, just the internet being the internet 🫠

The TTL of a DS RRset SHOULD match the TTL of the delegating NS RRset (that is, the NS RRset from the same zone that contains the DS RRset) ⭐

Building a DS RR means you need to know the matching DNSKEY RR in the child zone. That implies communication between the child and parent zones. This communication is an operational matter that this document doesn't cover πŸ€·β€β™€οΈ

2.5. Changes to the CNAME Resource Record πŸ’…

If a CNAME RRset is present at a name in a signed zone, the appropriate RRSIG and NSEC RRsets are REQUIRED at that name. A KEY RRset at that name for secure dynamic update purposes is also allowed ([RFC3007]). Other types MUST NOT be present at that name πŸ™ˆ

This is a change to the original CNAME definition in [RFC1034]. The original definition didn't let any other types coexist with a CNAME record, but a signed zone needs NSEC and RRSIG RRs for every authoritative name. To fix this clash, this spec modifies the CNAME resource record definition so it can coexist with NSEC and RRSIG RRs. Problem solved, slay πŸ‘‘

2.6. DNSSEC RR Types Appearing at Zone Cuts 🌸

DNSSEC brought in two new RR types that are unusual because they can show up on the parental side of a zone cut. At the parental side of a zone cut (that is, at a delegation point), NSEC RRs are REQUIRED at the owner name. A DS RR could also be there if the zone being delegated is signed and wants a chain of authentication to the parent zone πŸ”— This is an exception to the original DNS specification ([RFC1034]), which said only NS RRsets could appear on the parental side of a zone cut. Plot twist 😭

This specification updates the original DNS specification to allow NSEC and DS RR types on the parent side of a zone cut. These RRsets are authoritative for the parent when they appear there ✨

2.7. Example of a Secure Zone 🧚

Appendix A shows a complete example of a small signed zone πŸŽ€


3. Serving πŸ’œ

This section describes the behavior of entities that include security-aware name server functions. In a lot of cases those functions will be part of a security-aware recursive name server, but a security-aware authoritative name server has some of the same requirements πŸ¦‹ Functions specific to security-aware recursive name servers are covered in Section 3.2, and functions specific to authoritative servers are covered in Section 3.1.

In the following discussion, the terms "SNAME", "SCLASS", and "STYPE" mean what they mean in [RFC1034] πŸ“–

A security-aware name server MUST support the EDNS0 ([RFC2671]) message size extension, MUST support a message size of at least 1220 octets, and SHOULD support a message size of 4000 octets. Since IPv6 packets can only be fragmented by the source host, a security aware name server SHOULD take steps to make sure that UDP datagrams it transmits over IPv6 get fragmented, if necessary, at the minimum IPv6 MTU, unless the path MTU is known 🌈 For more on packet size and fragmentation, check out [RFC1122], [RFC2460], and [RFC3226] πŸ€“

A security-aware name server that receives a DNS query that doesn't include the EDNS OPT pseudo-RR, or that has the DO bit clear, MUST treat the RRSIG, DNSKEY, and NSEC RRs as it would any other RRset, and MUST NOT perform any of the additional processing described below πŸ™…β€β™€οΈ Because the DS RR type has the peculiar property of only existing in the parent zone at delegation points, DS RRs always need some special processing, as described in Section 3.1.4.1 πŸ“

Security aware name servers that get explicit queries for security RR types matching the content of more than one zone they serve (for example, NSEC and RRSIG RRs above and below a delegation point where the server is authoritative for both zones) should behave self-consistently 🫢 As long as the response is always consistent for each query to the name server, the name server MAY return one of the following:

  • The above-delegation RRsets.
  • The below-delegation RRsets.
  • Both above and below-delegation RRsets.
  • Empty answer section (no records).
  • Some other response.
  • An error.

DNSSEC allocates two new bits in the DNS message header: the CD (Checking Disabled) bit and the AD (Authentic Data) bit ✨ The CD bit is controlled by resolvers, so a security-aware name server MUST copy the CD bit from a query into the corresponding response. The AD bit is controlled by name servers, so a security-aware name server MUST ignore the setting of the AD bit in queries. See Sections 3.1.6, 3.2.2, 3.2.3, 4, and 4.9 for the details on how these bits behave πŸŽ€

A security aware name server that synthesizes CNAME RRs from DNAME RRs as described in [RFC2672] SHOULD NOT generate signatures for the synthesized CNAME RRs 🧚

3.1. Authoritative Name Servers πŸ‘‘

Upon receiving a relevant query that has the EDNS ([RFC2671]) OPT pseudo-RR DO bit ([RFC3225]) set, a security-aware authoritative name server for a signed zone MUST include additional RRSIG, NSEC, and DS RRs, following these rules:

  • RRSIG RRs that can be used to authenticate a response MUST be included in the response according to the rules in Section 3.1.1.
  • NSEC RRs that can be used to provide authenticated denial of existence MUST be included in the response automatically according to the rules in Section 3.1.3.
  • Either a DS RRset or an NSEC RR proving that no DS RRs exist MUST be included in referrals automatically according to the rules in Section 3.1.4.

These rules only apply to responses where the semantics convey information about whether resource records are present or absent. In other words, these rules aren't meant to rule out responses like RCODE 4 ("Not Implemented") or RCODE 5 ("Refused") πŸ™ƒ

DNSSEC doesn't change the DNS zone transfer protocol 🚚 Section 3.1.5 covers the zone transfer requirements.

3.1.1. Including RRSIG RRs in a Response ✨

Okay so, when a query has the DO bit set, a security-aware authoritative name server SHOULD attempt to send RRSIG RRs that a security-aware resolver can use to authenticate the RRsets in the response. πŸ” A name server SHOULD make every attempt to keep the RRset and its associated RRSIG(s) together in a response. Here's how the inclusion rules work:

  • When a signed RRset goes in the Answer section, the name server MUST also place its RRSIG RRs in the Answer section. The RRSIG RRs get higher priority for inclusion than any other RRsets that might need to fit, so they're basically the VIPs πŸ‘‘. If there isn't space for these RRSIG RRs, the name server MUST set the TC bit.
  • When a signed RRset goes in the Authority section, the name server MUST also place its RRSIG RRs in the Authority section. Same deal: RRSIG RRs have higher priority for inclusion than any other RRsets that might need to fit. If there isn't space for them, the name server MUST set the TC bit.
  • When a signed RRset goes in the Additional section, the name server MUST also place its RRSIG RRs in the Additional section. If there's room for the RRset but not its RRSIG RRs, the name server MAY keep the RRset and drop the RRSIG RRs. If that happens, the name server MUST NOT set the TC bit just because these RRSIG RRs didn't fit. πŸ™ˆ

3.1.2. Including DNSKEY RRs in a Response πŸ”‘

When a query has the DO bit set and asks for the SOA or NS RRs at the apex of a signed zone, a security-aware authoritative name server for that zone MAY return the zone apex DNSKEY RRset in the Additional section. Lowkey the DNSKEY RRset and its RRSIG RRs are the lowest priority here, so anything else that would go in the Additional section gets first dibs πŸ’…. The name server SHOULD NOT include the DNSKEY RRset unless there's enough room in the response message for both the DNSKEY RRset and its RRSIG RR(s). If there isn't room for both the DNSKEY and RRSIG RRs, the name server MUST omit them, and it MUST NOT set the TC bit just because these RRs didn't fit (see Section 3.1.1).

3.1.3. Including NSEC RRs in a Response 🧚

When a query has the DO bit set, a security-aware authoritative name server for a signed zone MUST include NSEC RRs in each of the following cases:

  • No Data: The zone contains RRsets that exactly match <SNAME, SCLASS>, but it does not contain any RRsets that exactly match <SNAME, SCLASS, STYPE>.
  • Name Error: The zone does not contain any RRsets that match <SNAME, SCLASS>, either exactly or via wildcard name expansion.
  • Wildcard Answer: The zone does not contain any RRsets that exactly match <SNAME, SCLASS>, but it does contain an RRset that matches <SNAME, SCLASS, STYPE> via wildcard name expansion.
  • Wildcard No Data: The zone does not contain any RRsets that exactly match <SNAME, SCLASS>, and it does contain one or more RRsets that match <SNAME, SCLASS> via wildcard name expansion, but it does not contain any RRsets that match <SNAME, SCLASS, STYPE> via wildcard name expansion.

In each of these cases, the name server includes NSEC RRs in the response. Those NSEC RRs prove that an exact match for <SNAME, SCLASS, STYPE> wasn't in the zone, and that the response being returned is correct given the zone's data. It's the receipts, bestie 🧾✨.

3.1.3.1. Including NSEC RRs: No Data Response πŸ«₯

If the zone contains RRsets matching <SNAME, SCLASS> but no RRset matching <SNAME, SCLASS, STYPE>, then the name server MUST include the NSEC RR for <SNAME, SCLASS> along with its associated RRSIG RR(s) in the Authority section of the response (see Section 3.1.1). If there isn't space for the NSEC RR or its associated RRSIG RR(s), the name server MUST set the TC bit (see Section 3.1.1).

Since the search name exists, wildcard name expansion doesn't apply to this query. A single signed NSEC RR is enough to prove that the requested RR type doesn't exist. Main character energy, one NSEC is all it takes πŸŽ€.

3.1.3.2. Including NSEC RRs: Name Error Response 🚫

If the zone doesn't contain any RRsets matching <SNAME, SCLASS>, either exactly or via wildcard name expansion, then the name server MUST include the following NSEC RRs in the Authority section, along with their associated RRSIG RRs:

  • An NSEC RR proving that there is no exact match for <SNAME, SCLASS>.
  • An NSEC RR proving that the zone contains no RRsets that would match <SNAME, SCLASS> via wildcard name expansion.

Sometimes one single NSEC RR can prove both of these points. If it does, the name server SHOULD only include that NSEC RR and its RRSIG RR(s) once in the Authority section. ♻️

If there isn't space for these NSEC and RRSIG RRs, the name server MUST set the TC bit (see Section 3.1.1).

The owner names of these NSEC and RRSIG RRs are not subject to wildcard name expansion when they're included in the Authority section of the response. Hands off the wildcard, they're not a wildcard πŸ™…β€β™€οΈ.

Note that this form of response covers cases where SNAME corresponds to an empty non-terminal name within the zone. That's a name that isn't the owner name for any RRset, but it IS the parent name of one or more RRsets. Plot twist, it's giving "exists but doesn't" 🌸.

3.1.3.3. Including NSEC RRs: Wildcard Answer Response πŸƒ

If the zone doesn't contain any RRsets that exactly match <SNAME, SCLASS>, but it does contain an RRset that matches <SNAME, SCLASS, STYPE> via wildcard name expansion, the name server MUST include the wildcard-expanded answer and the corresponding wildcard-expanded RRSIG RRs in the Answer section. It MUST also include, in the Authority section, an NSEC RR and associated RRSIG RR(s) proving that the zone doesn't contain a closer match for <SNAME, SCLASS>. If there isn't space for the answer, the NSEC RRs, and the RRSIG RRs, the name server MUST set the TC bit (see Section 3.1.1). 🧩

3.1.3.4. Including NSEC RRs: Wildcard No Data Response 🌈

This one's a combo of the previous cases πŸ’–. The zone doesn't contain an exact match for <SNAME, SCLASS>. Although the zone does contain RRsets that match <SNAME, SCLASS> via wildcard expansion, none of those RRsets matches STYPE. The name server MUST include the following NSEC RRs in the Authority section, along with their associated RRSIG RRs:

  • An NSEC RR proving that there are no RRsets matching STYPE at the wildcard owner name that matched <SNAME, SCLASS> via wildcard expansion.
  • An NSEC RR proving that there are no RRsets in the zone that would have been a closer match for <SNAME, SCLASS>.

Again, a single NSEC RR might prove both of these points. If it does, the name server SHOULD only include that NSEC RR and its RRSIG RR(s) once in the Authority section.

The owner names of these NSEC and RRSIG RRs are not subject to wildcard name expansion when they're included in the Authority section of the response. If there isn't space for these NSEC and RRSIG RRs, the name server MUST set the TC bit (see Section 3.1.1).

3.1.3.5. Finding the Right NSEC RRs πŸ”

As explained above, there are several situations where a security-aware authoritative name server has to find an NSEC RR that proves no RRsets matching a particular SNAME exist. Finding one inside an authoritative zone is pretty simple, at least in concept. The following discussion assumes the name server is authoritative for the zone that would have held the non-existent RRsets matching SNAME. The algorithm below is written for clarity, not efficiency, so no judgment if it's a little extra 🫢.

To find the NSEC that proves no RRsets matching name N exist in the zone Z that would have held them, build a sequence, S. It consists of the owner names of every RRset in Z, sorted into canonical order ([RFC4034]), with no duplicate names. Then find the name M that would have immediately preceded N in S if any RRsets with owner name N had existed. M is the owner name of the NSEC RR that proves no RRsets exist with owner name N. Ta-da πŸͺ„.

The algorithm for finding the NSEC RR that proves a given name isn't covered by any applicable wildcard is similar, but it needs one extra step. To be precise, the algorithm for finding the NSEC proving that no RRsets exist with the applicable wildcard name is exactly the same as the algorithm for finding the NSEC RR that proves RRsets with any other owner name don't exist. The missing piece is working out the name of the non-existent applicable wildcard. In practice that's easy, because the authoritative name server has already checked for the presence of exactly that wildcard name as part of step (1)(c) of the normal lookup algorithm described in Section 4.3.2 of [RFC1034]. πŸ’…βœ¨

3.1.4. Including DS RRs in a Response 🎁

When a query has the DO bit set, a security-aware authoritative name server that returns a referral includes DNSSEC data along with the NS RRset.

If a DS RRset is present at the delegation point, the name server MUST return both the DS RRset and its associated RRSIG RR(s) in the Authority section, along with the NS RRset.

If no DS RRset is present at the delegation point, the name server MUST return both the NSEC RR that proves the DS RRset isn't present and that NSEC RR's associated RRSIG RR(s), along with the NS RRset. The name server MUST place the NS RRset before the NSEC RRset and its associated RRSIG RR(s). The order is literally everything πŸ™Œ.

Including these DS, NSEC, and RRSIG RRs makes referral messages bigger, and it may cause some or all glue RRs to be omitted. If there isn't space for the DS or NSEC RRset and its associated RRSIG RRs, the name server MUST set the TC bit (see Section 3.1.1). πŸ₯Ή

3.1.4.1. Responding to Queries for DS RRs πŸ’–

okay so the DS record type is kinda unusual πŸ¦‹ It only ever shows up on the parent zone's side of a zone cut. Like, the DS RRset for "foo.example" lives in the "example" zone, and it's not stored in "foo.example" itself 😭 That means both name servers and resolvers need special processing rules. The child zone's name server is authoritative for the name at the zone cut under the normal DNS rules, but the child zone doesn't actually contain the DS RRset. Plot twist 🌸

A security-aware resolver sends queries to the parent zone when it needs a DS RR at a delegation point (see Section 4.2). BUT special rules are needed so we don't confuse security-oblivious resolvers that might end up handling that query. That can happen when a network setup forces a security-aware resolver to route its queries through a security-oblivious recursive name server πŸ™ˆ The rest of this section explains how a security-aware name server handles DS queries so that doesn't happen πŸ’…

The special processing only kicks in when all of these are true:

  • The name server has received a query for the DS RRset at a zone cut.
  • The name server is authoritative for the child zone.
  • The name server is not authoritative for the parent zone.
  • The name server does not offer recursion.

In every other case, the name server either has a way to get the DS RRset, or it couldn't have been expected to have it even under the pre-DNSSEC rules. So it can just return the DS RRset or an error response using the normal rules πŸ‘‘

If all of the above are met, though, the name server IS authoritative for SNAME but can't supply the requested RRset 😭 In this case, the name server MUST return an authoritative "no data" response showing that the DS RRset doesn't exist at the child zone's apex. Check out Appendix B.8 for an example of that πŸŽ€


3.1.5. Responding to Queries for Type AXFR or IXFR 🚚

Quick tea: DNSSEC doesn't change how zone transfers work at all πŸ’… A signed zone will have RRSIG, DNSKEY, NSEC, and DS records, but those don't mean anything special for a zone transfer.

An authoritative name server isn't required to check that a zone is properly signed before sending or accepting a transfer. BUT an authoritative name server MAY choose to reject the entire zone transfer if the zone fails to meet any of the signing requirements in Section 2. The main goal of a zone transfer is for every authoritative name server to end up with identical copies of the zone. So if a server does its own zone validation, it MUST NOT selectively reject some RRs and accept others. That would break the whole identical copies thing πŸ™…

DS RRsets only show up on the parental side of a zone cut, and they're authoritative data in the parent zone. Like any other authoritative RRset, the DS RRset MUST be included in zone transfers of the zone where it's authoritative data. For DS, that's the parent zone πŸ’œ

NSEC RRs appear in both the parent and child zones at a zone cut, and they're authoritative data in both. The parental and child NSEC RRs at a zone cut are never identical to each other. The child apex NSEC will always indicate that the child's SOA RR is present, whereas the parental NSEC at the cut will never indicate an SOA RR. As with any other authoritative RRs, NSEC RRs MUST be included in zone transfers of the zone where they're authoritative data. The parental NSEC RR at a zone cut MUST be included in zone transfers of the parent zone, and the NSEC at the child zone's apex MUST be included in zone transfers of the child zone ✨

RRSIG RRs also appear in both the parent and child zones at a zone cut. They're authoritative in whichever zone contains the authoritative RRset that the signature covers. So the RRSIG for a DS RRset or a parental NSEC RR at a zone cut is authoritative in the parent zone, and the RRSIG for any RRset at the child zone's apex is authoritative in the child zone. Parental and child RRSIG RRs at a zone cut are never identical either. The Signer's Name field of an RRSIG in the child apex points to a DNSKEY RR in the child apex, whereas the same field on the parental RRSIG at the cut points to a DNSKEY RR in the parent zone's apex. As with any other authoritative RRs, RRSIG RRs MUST be included in zone transfers of the zone where they're authoritative data 🌈


3.1.6. The AD and CD Bits in an Authoritative Response πŸ™ˆ

The CD and AD bits are designed for communication between security-aware resolvers and security-aware recursive name servers. For the most part, they aren't relevant to query processing by security-aware authoritative name servers 🌸

A security-aware name server doesn't perform signature validation for authoritative data during query processing, even when the CD bit is clear. A security-aware name server SHOULD clear the CD bit when composing an authoritative response.

A security-aware name server MUST NOT set the AD bit in a response unless it considers all RRsets in the Answer and Authority sections of that response to be authentic. A name server's local policy MAY consider data from an authoritative zone to be authentic without further validation. However, the name server MUST NOT do so unless it obtained the authoritative zone via secure means (such as a secure zone transfer mechanism), and it MUST NOT do so unless this behavior has been configured explicitly.

A security-aware name server that supports recursion MUST follow the rules for the CD and AD bits given in Section 3.2 when generating a response that involves data obtained via recursion ✨


3.2. Recursive Name Servers 🧚

As [RFC4033] explains, a security-aware recursive name server is an entity that acts in both the security-aware name server and security-aware resolver roles πŸ’… This section uses the terms "name server side" and "resolver side" to refer to the code within a security-aware recursive name server that implements the security-aware name server role, and the code that implements the security-aware resolver role, respectively.

The resolver side follows the usual rules for caching and negative caching that would apply to any security-aware resolver.

3.2.1. The DO Bit πŸ¦‹

The resolver side of a security-aware recursive name server MUST set the DO bit when sending requests, regardless of the state of the DO bit in the initiating request received by the name server side. If the DO bit in an initiating query is not set, the name server side MUST strip any authenticating DNSSEC RRs from the response, but MUST NOT strip any DNSSEC RR types that the initiating query explicitly requested πŸŽ€

3.2.2. The CD Bit πŸ”₯

The CD bit exists so a security-aware resolver can disable signature validation during a security-aware name server's processing of a particular query.

The name server side MUST copy the setting of the CD bit from a query to the corresponding response.

The name server side of a security-aware recursive name server MUST pass the state of the CD bit to the resolver side along with the rest of an initiating query. That way the resolver side knows whether it's required to verify the response data it returns to the name server side. If the CD bit is set, it indicates that the originating resolver is willing to perform whatever authentication its local policy requires. So the resolver side of the recursive name server need not perform authentication on the RRsets in the response. When the CD bit is set, the recursive name server SHOULD, if possible, return the requested data to the originating resolver, even if the recursive name server's local authentication policy would reject the records in question. In other words, by setting the CD bit, the originating resolver has taken responsibility for its own authentication, so the recursive name server should not interfere πŸ’–

If the resolver side implements a BAD cache (see Section 4.7) and the name server side receives a query that matches an entry in the resolver side's BAD cache, the name server side's response depends on the state of the CD bit in the original query. If the CD bit is set, the name server side SHOULD return the data from the BAD cache. If the CD bit is not set, the name server side MUST return RCODE 2 (server failure).

The point of the rule above is to hand raw data to clients that can do their own signature verification, while still protecting clients that rely on the resolver side of a security-aware recursive name server to do those checks. Lots of the reasons signature validation might fail involve conditions that don't apply equally to the recursive name server and to the client that invoked it. For example, the recursive name server's clock may be set incorrectly, or the client may know about a relevant island of security that the recursive name server doesn't share. In those cases, "protecting" a client that can do its own signature validation from ever seeing the "bad" data doesn't actually help the client πŸ™„

3.2.3. The AD Bit 🌸

The name server side of a security-aware recursive name server MUST NOT set the AD bit in a response unless it considers all RRsets in the Answer and Authority sections of the response to be authentic. The name server side SHOULD set the AD bit if and only if the resolver side considers all RRsets in the Answer section, and any relevant negative response RRs in the Authority section, to be authentic. The resolver side MUST follow the procedure described in Section 5 to determine whether the RRs in question are authentic. However, for backward compatibility, a recursive name server MAY set the AD bit when a response includes unsigned CNAME RRs, if those CNAME RRs demonstrably could have been synthesized from an authentic DNAME RR that is also included in the response, according to the synthesis rules described in [RFC2672] πŸ¦‹

3.3. Example DNSSEC Responses πŸŽ€

See Appendix B for example response packets.

4. Resolving ✨

This section describes the behavior of entities that include security-aware resolver functions. In many cases such functions will be part of a security-aware recursive name server, but a stand-alone security-aware resolver has many of the same requirements. Functions specific to security-aware recursive name servers are described in Section 3.2 πŸ’œ

4.1. EDNS Support πŸ’–

okay bestie, first things first πŸŽ€ a security-aware resolver MUST include an EDNS ([RFC2671]) OPT pseudo-RR with the DO ([RFC3225]) bit set whenever it sends queries. no skipping this one πŸ’…

a security-aware resolver MUST support a message size of at least 1220 octets, SHOULD support 4000 octets, and MUST use the sender's UDP payload size field in the EDNS OPT pseudo-RR to advertise the message size it's willing to accept. its IP layer also MUST handle fragmented UDP packets correctly, whether those fragments came in over IPv4 or IPv6 πŸ¦‹ for the reasoning behind all this, check out [RFC1122], [RFC2460], and [RFC3226].

4.2. Signature Verification Support πŸ”₯

a security-aware resolver MUST support the signature verification mechanisms described in Section 5, and it SHOULD apply them to every response it receives. the exceptions (the no-validation-for-you list πŸ™ˆ) are when:

  • the security-aware resolver is part of a security-aware recursive name server, and the response is the result of recursion on behalf of a query received with the CD bit set;
  • the response is the result of a query generated directly through some form of application interface that told the security-aware resolver not to validate this query; or
  • validation for this query has been turned off by local policy.

a security-aware resolver's signature verification support MUST include verification of wildcard owner names. that part is non-negotiable, periodt ✨

security-aware resolvers MAY query for missing security RRs to try to validate things. but implementations that choose to do this must be aware that the answers they get back may not be enough to validate the original response πŸ₯Ί for example, a zone update may have changed (or deleted) the info you wanted between your first query and your follow-up.

when a security-aware iterative-mode resolver is trying to retrieve missing NSEC RRs that live on the parent side of a zone cut, it MUST query the name servers for the parent zone, not the child zone. same energy for a missing DS: a security-aware iterative-mode resolver MUST query the name servers for the parent zone, not the child zone πŸ‘‘ this is because security-aware name servers need special processing rules to handle the DS RR (see Section 3.1.4.1). and sometimes the resolver also needs special rules to find the parent's name servers if it doesn't already have the parent's NS RRset. to find that NS RRset, the resolver can start with the delegation name, strip off the leftmost label, and query for an NS RRset under that name. if there's no NS RRset at that name, it strips off the next leftmost label and retries, repeating this walk up the tree until it either finds the NS RRset or runs out of labels 🌈

4.3. Determining Security Status of Data 🧚

a security-aware resolver MUST be able to figure out whether it should expect a particular RRset to be signed. more precisely, a security-aware resolver must be able to tell apart four cases:

  • Secure: an RRset for which the resolver can build a chain of signed DNSKEY and DS RRs from a trusted security anchor down to the RRset. here the RRset should be signed, and it's subject to signature validation like we talked about above.
  • Insecure: an RRset for which the resolver knows there's no chain of signed DNSKEY and DS RRs from any trusted starting point to the RRset. this can happen when the target RRset lives in an unsigned zone or under a descendent of an unsigned zone. in this case the RRset may or may not be signed, but the resolver won't be able to verify the signature.
  • Bogus: an RRset where the resolver believes it ought to be able to build a chain of trust, but can't, either because signatures fail to validate for some reason or because data the relevant DNSSEC RRs say should be there is missing. this case may point to an attack, but it may also point to a configuration error or some form of data corruption 😬
  • Indeterminate: an RRset where the resolver can't determine whether it should be signed, because it can't get the DNSSEC RRs it needs. this can happen when the security-aware resolver can't reach security-aware name servers for the relevant zones.

4.4. Configured Trust Anchors πŸ”‘

a security-aware resolver MUST be able to be configured with at least one trusted public key or DS RR, and it SHOULD be able to be configured with multiple trusted public keys or DS RRs. without a configured trust anchor, a security-aware resolver can't validate signatures at all, so it SHOULD have a reasonably robust way to get those keys when it boots πŸ›Ÿ some examples would be some form of non-volatile storage (like a disk drive) or some form of trusted local network configuration mechanism.

also, trust anchors cover key material that gets updated in a secure manner. that secure manner could be through physical media, a key exchange protocol, or some other out-of-band means 🫢

4.5. Response Caching πŸ“

a security-aware resolver SHOULD cache each response as a single atomic entry that holds the entire answer, including the named RRset and any associated DNSSEC RRs. it SHOULD throw away the whole atomic entry when any of the RRs in it expire. most of the time the right cache index for the atomic entry is the triple <QNAME, QTYPE, QCLASS>, but in cases like the response form described in Section 3.1.3.2 the right cache index is the double <QNAME,QCLASS> ✨

the reason for all this is that, between the first query and when the cached data expires, the authoritative data might have changed (for example, through dynamic update) πŸ‘€

there are two situations where this matters:

  1. by using the RRSIG record, it's possible to deduce that an answer was synthesized from a wildcard. a security-aware recursive name server could store that wildcard data and use it to generate positive responses to queries for names other than the one the original answer was first received for.
  2. NSEC RRs received to prove that a name doesn't exist could be reused by a security-aware resolver to prove that any name in the range they span doesn't exist either.

in theory, a resolver could use wildcards or NSEC RRs to generate positive and negative responses (respectively) until the TTL or the signatures on those records expire. but it seems prudent for resolvers to avoid blocking new authoritative data or synthesizing new data on their own πŸ™…β€β™€οΈ resolvers that follow this advice will have a more consistent view of the namespace πŸ’œ

4.6. Handling of the CD and AD Bits πŸŽ€

a security-aware resolver MAY set a query's CD bit to say that it takes responsibility for doing whatever authentication its local policy requires on the RRsets in the response. see Section 3.2 for how this bit changes the behavior of security-aware recursive name servers.

a security-aware resolver MUST clear the AD bit when composing query messages. this protects against buggy name servers that blindly copy header bits they don't understand from the query into the response πŸ€¦β€β™€οΈ

a resolver MUST disregard the meaning of the CD and AD bits in a response, unless the response was obtained over a secure channel or the resolver was specifically configured to trust the message header bits without a secure channel. no trusting random header bits, bestie πŸ™…β€β™€οΈ

4.7. Caching BAD Data πŸ’€

lowkey, a lot of validation errors are transient, but some are way more persistent, like the ones caused by administrative mistakes (failing to re-sign a zone, clock skew, and so on). requerying won't help in those cases, so validating resolvers could end up generating a ton of unnecessary DNS traffic by repeatedly querying RRsets with persistent validation failures 😭

to stop that pointless traffic, security-aware resolvers MAY cache data with invalid signatures, with some restrictions 🧊

conceptually, caching this is similar to negative caching ([RFC2308]), except that instead of caching a valid negative response, the resolver is caching the fact that a particular answer failed to validate. this document calls a cache of data with invalid signatures a "BAD cache" πŸ’…

resolvers that implement a BAD cache MUST take steps to keep the cache from being useful as a denial-of-service attack amplifier. in particular:

  • since RRsets that fail to validate don't have trustworthy TTLs, the implementation MUST assign a TTL. this TTL SHOULD be small, so that the effect of caching the results of an attack is limited πŸ›‘οΈ
  • to avoid caching a transient validation failure (which might be the result of an attack), resolvers SHOULD track queries that result in validation failures, and SHOULD only answer from the BAD cache after the number of times responses to queries for that particular <QNAME, QTYPE, QCLASS> have failed to validate exceeds a threshold value.
resolvers MUST NOT return RRsets from the BAD cache unless the resolver is not required to validate the signatures of those RRsets under the rules in Section 4.2 of this document. this is a big one, so don't skip it 🚨 see Section 3.2.2 for how responses from a security-aware recursive name server interact with a BAD cache.

4.8. Synthesized CNAMEs 🌸

a validating security-aware resolver MUST treat the signature of a valid signed DNAME RR as also covering unsigned CNAME RRs that could have been synthesized from that DNAME RR, as described in [RFC2672]. at the very least, it can't reject a response message just because it contains those CNAME RRs 🧠 the resolver MAY keep those CNAME RRs in its cache or in the answers it hands back, but it's not required to do so.

4.9. Stub Resolvers πŸ¦‹

a security-aware stub resolver MUST support the DNSSEC RR types, at least to the extent of not mishandling responses just because they contain DNSSEC RRs. it's giving "don't panic over DNSSEC records" energy ✨

4.9.1. Handling of the DO Bit 🫧

a non-validating security-aware stub resolver MAY include the DNSSEC RRs returned by a security-aware recursive name server in the data it hands back to the application that invoked it, but it's not required to do so. if a non-validating stub resolver wants to do this, it will need to set the DO bit so it actually gets the DNSSEC RRs from the recursive name server πŸ’–

a validating security-aware stub resolver MUST set the DO bit, because otherwise it won't receive the DNSSEC RRs it needs to do signature validation. no DO bit, no validation, no slay πŸ’…πŸ‘‘

4.9.2. Handling of the CD Bit πŸ’…

okay so a non-validating security-aware stub resolver SHOULD NOT set the CD bit when it sends queries, unless the application layer asks for it πŸ™…β€β™€οΈ. the reason is that a non-validating stub resolver is literally relying on its security-aware recursive name server to do the validating for it, so it's not its job.

a validating security-aware stub resolver SHOULD set the CD bit 🫢. if it doesn't, the security-aware recursive name server will answer using its own local policy, and that policy could stop the stub resolver from getting data that its own local policy would have been totally fine with 😭.

4.9.3. Handling of the AD Bit πŸ”

a non-validating security-aware stub resolver MAY choose to look at the AD bit in the response messages it gets. that's how it can check whether the security-aware recursive name server that sent the response says it has cryptographically verified the data in the Answer and Authority sections πŸ•΅οΈβ€β™€οΈ. but bestie, the responses a security-aware stub resolver gets are super dependent on the local policy of that recursive name server πŸ’€. so checking the AD bit might not be worth much practically, except maybe as a debugging aid πŸ› οΈ. either way, a security-aware stub resolver MUST NOT rely on any signature validation that's supposedly done on its behalf, except when it got the data from a trusted security-aware recursive name server over a secure channel πŸ”’. no blind trust, periodt ✨.

a validating security-aware stub resolver SHOULD NOT look at the AD bit in response messages πŸ™ˆ. the reason is that by definition, it does its own signature validation no matter what the AD bit says. so why would it even care πŸ’….


5. Authenticating DNS Responses πŸ”

to use DNSSEC RRs for authentication, a security-aware resolver needs to already know at least one authenticated DNSKEY or DS RR πŸ—οΈ. getting and authenticating that initial trust anchor happens through some external mechanism. for example, a resolver could use an off-line authenticated exchange to get a zone's DNSKEY RR, or to get a DS RR that identifies and authenticates a zone's DNSKEY RR. the rest of this section assumes the resolver has somehow gotten an initial set of trust anchors 🌸.

an initial DNSKEY RR can be used to authenticate a zone's apex DNSKEY RRset πŸ‘‘. to authenticate an apex DNSKEY RRset using an initial key, the resolver MUST:

  1. verify that the initial DNSKEY RR shows up in the apex DNSKEY RRset, and that the DNSKEY RR has the Zone Key Flag (DNSKEY RDATA bit 7) set; and
  2. verify that there is some RRSIG RR covering the apex DNSKEY RRset, and that the combination of the RRSIG RR and the initial DNSKEY RR authenticates the DNSKEY RRset. the process for using an RRSIG RR to authenticate an RRset is described in Section 5.3 🧩.

once the resolver has authenticated the apex DNSKEY RRset using an initial DNSKEY RR, delegations from that zone can be authenticated using DS RRs πŸ¦‹. this lets a resolver start from an initial key and use DS RRsets to keep going recursively down the DNS tree, getting other apex DNSKEY RRsets along the way 🌳. if the resolver were configured with a root DNSKEY RR, and every delegation had a DS RR attached to it, then the resolver could get and validate any apex DNSKEY RRset. the process of using DS RRs to authenticate referrals is described in Section 5.2 πŸŽ€.

Section 5.3 shows how the resolver can use DNSKEY RRs in the apex DNSKEY RRset, plus RRSIG RRs from the zone, to authenticate any other RRsets in the zone. this works once the resolver has authenticated a zone's apex DNSKEY RRset πŸ’œ. Section 5.4 shows how the resolver can use authenticated NSEC RRsets from the zone to prove that an RRset isn't present in the zone πŸ™…β€β™€οΈ.

when a resolver says it supports DNSSEC (by setting the DO bit), a security-aware name server SHOULD try to include the necessary DNSKEY, RRSIG, NSEC, and DS RRsets in a response (see Section 3) πŸ“. however, a security-aware resolver can still get a response that's missing the right DNSSEC RRs 😬. that could be because of configuration issues, like an upstream security-oblivious recursive name server accidentally messing with DNSSEC RRs. it could also be a deliberate attack, where an adversary forges a response, strips DNSSEC RRs out of it, or changes a query so the DNSSEC RRs look like they weren't requested 🚨. the absence of DNSSEC data in a response MUST NOT, by itself, be taken as a sign that no authentication information exists. absolutely not, that's a trap πŸͺ€.

a resolver SHOULD expect authentication information from signed zones 🧁. a resolver SHOULD believe that a zone is signed if it has been configured with public key information for that zone, or if the zone's parent is signed and the delegation from the parent contains a DS RRset ✨.

5.1. Special Considerations for Islands of Security 🏝️

islands of security (see [RFC4033]) are signed zones where it's not possible to build an authentication chain to the zone from its parent πŸ₯Ί. validating signatures inside an island of security means the validator needs some other way of getting an initial authenticated zone key for the island πŸ”‘. if a validator can't get such a key, it SHOULD switch to operating as if the zones in the island of security are unsigned 😢.

all the normal processes for validating responses apply to islands of security πŸ’–. the only difference between normal validation and validation inside an island of security is how the validator gets a trust anchor for the authentication chain πŸͺ„.

5.2. Authenticating Referrals πŸ”—

once the apex DNSKEY RRset for a signed parent zone has been authenticated, DS RRsets can be used to authenticate the delegation to a signed child zone 🧑. a DS RR identifies a DNSKEY RR in the child zone's apex DNSKEY RRset, and it contains a cryptographic digest of the child zone's DNSKEY RR πŸͺͺ. using a strong cryptographic digest algorithm makes it computationally infeasible for an adversary to generate a DNSKEY RR that matches the digest πŸ›‘οΈ. so authenticating the digest lets a resolver authenticate the matching DNSKEY RR, and then the resolver can use that child DNSKEY RR to authenticate the entire child apex DNSKEY RRset πŸ’….

given a DS RR for a delegation, the child zone's apex DNSKEY RRset can be authenticated if all of the following hold:

  • The DS RR has been authenticated using some DNSKEY RR in the parent's apex DNSKEY RRset (see Section 5.3).
  • The Algorithm and Key Tag in the DS RR match the Algorithm field and the key tag of a DNSKEY RR in the child zone's apex DNSKEY RRset, and, when the DNSKEY RR's owner name and RDATA are hashed using the digest algorithm specified in the DS RR's Digest Type field, the resulting digest value matches the Digest field of the DS RR.
  • The matching DNSKEY RR in the child zone has the Zone Flag bit set, the corresponding private key has signed the child zone's apex DNSKEY RRset, and the resulting RRSIG RR authenticates the child zone's apex DNSKEY RRset.

if the referral from the parent zone didn't include a DS RRset, the response should have included a signed NSEC RRset proving that no DS RRset exists for the delegated name (see Section 3.1.4) πŸ•΅οΈ. a security-aware resolver MUST query the name servers for the parent zone for the DS RRset if the referral includes neither a DS RRset nor an NSEC RRset proving that the DS RRset doesn't exist (see Section 4) πŸ“ž.

if the validator authenticates an NSEC RRset proving that no DS RRset is present for this zone, then there's no authentication path leading from the parent to the child πŸ’”. but if the resolver has an initial DNSKEY or DS RR that belongs to the child zone, or to any delegation below the child zone, this initial DNSKEY or DS RR MAY be used to re-establish an authentication path πŸ”„. if no such initial DNSKEY or DS RR exists, the validator can't authenticate RRsets in or below the child zone 😭.

if the validator doesn't support any of the algorithms listed in an authenticated DS RRset, then the resolver has no supported authentication path leading from the parent to the child πŸ™ƒ. the resolver should treat this case the same way it would treat an authenticated NSEC RRset proving that no DS RRset exists, as described above 🎯.

heads up, this one's a little tricky πŸ‘€. for a signed delegation, there are two NSEC RRs associated with the delegated name. one NSEC RR lives in the parent zone and can be used to prove whether a DS RRset exists for the delegated name. the second NSEC RR lives in the child zone and tells you which RRsets are present at the apex of the child zone πŸ—ΊοΈ. the parent NSEC RR and the child NSEC RR can always be told apart, because the SOA bit will be set in the child NSEC RR and clear in the parent NSEC RR 🧠. a security-aware resolver MUST use the parent NSEC RR when it's trying to prove that a DS RRset does not exist 🫑.

if the resolver doesn't support any of the algorithms listed in an authenticated DS RRset, then the resolver won't be able to verify the authentication path to the child zone 😡. in that case, the resolver SHOULD treat the child zone as if it were unsigned 🌈.

5.3. Authenticating an RRset with an RRSIG RR 🧾

a validator can use an RRSIG RR and its matching DNSKEY RR to try to authenticate RRsets πŸ’«. first, the validator checks the RRSIG RR to make sure it covers the RRset, has a valid time interval, and identifies a valid DNSKEY RR βœ…. then the validator builds the canonical form of the signed data by appending the RRSIG RDATA (excluding the Signature Field) to the canonical form of the covered RRset 🧩. finally, the validator uses the public key and signature to authenticate the signed data πŸ”. Sections 5.3.1, 5.3.2, and 5.3.3 describe each step in detail πŸ“–.

5.3.1. Checking the RRSIG RR Validity ✨

okay so a security-aware resolver can use an RRSIG RR to authenticate an RRset if all of these conditions are true 🫢:

  • The RRSIG RR and the RRset MUST have the same owner name and the same class.
  • The RRSIG RR's Signer's Name field MUST be the name of the zone that contains the RRset.
  • The RRSIG RR's Type Covered field MUST equal the RRset's type.
  • The number of labels in the RRset owner name MUST be greater than or equal to the value in the RRSIG RR's Labels field.
  • The validator's notion of the current time MUST be less than or equal to the time listed in the RRSIG RR's Expiration field.
  • The validator's notion of the current time MUST be greater than or equal to the time listed in the RRSIG RR's Inception field.
  • The RRSIG RR's Signer's Name, Algorithm, and Key Tag fields MUST match the owner name, algorithm, and key tag for some DNSKEY RR in the zone's apex DNSKEY RRset.
  • The matching DNSKEY RR MUST be present in the zone's apex DNSKEY RRset, and MUST have the Zone Flag bit (DNSKEY RDATA Flag bit 7) set.

It is possible for more than one DNSKEY RR to match the conditions above. In this case, the validator cannot predetermine which DNSKEY RR to use to authenticate the signature, and it MUST try each matching DNSKEY RR until either the signature is validated or the validator has run out of matching public keys to try. πŸ”‘

Note that this authentication process is only meaningful if the validator authenticates the DNSKEY RR before using it to validate signatures. The matching DNSKEY RR is considered to be authentic if:

  • the apex DNSKEY RRset containing the DNSKEY RR is considered authentic; or
  • the RRset covered by the RRSIG RR is the apex DNSKEY RRset itself, and the DNSKEY RR either matches an authenticated DS RR from the parent zone or matches a trust anchor.

5.3.2. Reconstructing the Signed Data 🧩

Once the RRSIG RR has met the validity requirements described in Section 5.3.1, the validator has to reconstruct the original signed data. The original signed data includes RRSIG RDATA (excluding the Signature field) and the canonical form of the RRset. Aside from being ordered, the canonical form of the RRset might also differ from the received RRset due to DNS name compression, decremented TTLs, or wildcard expansion. The validator should use the following to reconstruct the original signed data:

      signed_data = RRSIG_RDATA | RR(1) | RR(2)...  where

         "|" denotes concatenation

         RRSIG_RDATA is the wire format of the RRSIG RDATA fields
            with the Signature field excluded and the Signer's Name
            in canonical form.

         RR(i) = name | type | class | OrigTTL | RDATA length | RDATA

            name is calculated according to the function below

            class is the RRset's class

            type is the RRset type and all RRs in the class

            OrigTTL is the value from the RRSIG Original TTL field

            All names in the RDATA field are in canonical form
            The set of all RR(i) is sorted into canonical order.

         To calculate the name:
            let rrsig_labels = the value of the RRSIG Labels field

            let fqdn = RRset's fully qualified domain name in
                            canonical form

            let fqdn_labels = Label count of the fqdn above.

            if rrsig_labels = fqdn_labels,
                name = fqdn

            if rrsig_labels < fqdn_labels,
               name = "*." | the rightmost rrsig_label labels of the
                             fqdn

            if rrsig_labels > fqdn_labels
               the RRSIG RR did not pass the necessary validation
               checks and MUST NOT be used to authenticate this
               RRset.

The canonical forms for names and RRsets are defined in [RFC4034].

NSEC RRsets at a delegation boundary need special processing, bestie 🚧. There are two distinct NSEC RRsets associated with a signed delegated name. One NSEC RRset resides in the parent zone, and specifies which RRsets are present at the parent zone. The second NSEC RRset resides at the child zone and identifies which RRsets are present at the apex in the child zone. The parent NSEC RRset and child NSEC RRset can always be distinguished as only a child NSEC RR will indicate that an SOA RRset exists at the name. When reconstructing the original NSEC RRset for the delegation from the parent zone, the NSEC RRs MUST NOT be combined with NSEC RRs from the child zone. When reconstructing the original NSEC RRset for the apex of the child zone, the NSEC RRs MUST NOT be combined with NSEC RRs from the parent zone.

Note that each of the two NSEC RRsets at a delegation point has a corresponding RRSIG RR with an owner name matching the delegated name, and each of these RRSIG RRs is authoritative data associated with the same zone that contains the corresponding NSEC RRset. If necessary, a resolver can tell these RRSIG RRs apart by checking the Signer's Name field. πŸ•΅οΈβ€β™€οΈ

5.3.3. Checking the Signature πŸ”

Once the resolver has validated the RRSIG RR as described in Section 5.3.1 and reconstructed the original signed data as described in Section 5.3.2, the validator can attempt to use the cryptographic signature to authenticate the signed data, and thus (finally!) authenticate the RRset. 😭

The Algorithm field in the RRSIG RR identifies the cryptographic algorithm used to generate the signature. The signature itself is contained in the Signature field of the RRSIG RDATA, and the public key used to verify the signature is contained in the Public Key field of the matching DNSKEY RR(s) (found in Section 5.3.1). [RFC4034] provides a list of algorithm types and provides pointers to the documents that define each algorithm's use.

Note that it is possible for more than one DNSKEY RR to match the conditions in Section 5.3.1. In this case, the validator can only determine which DNSKEY RR is correct by trying each matching public key until the validator either succeeds in validating the signature or runs out of keys to try.

If the Labels field of the RRSIG RR is not equal to the number of labels in the RRset's fully qualified owner name, then the RRset is either invalid or the result of wildcard expansion. The resolver MUST verify that wildcard expansion was applied properly before considering the RRset to be authentic. Section 5.3.4 describes how to determine whether a wildcard was applied properly.

If other RRSIG RRs also cover this RRset, the local resolver security policy determines whether the resolver also has to test these RRSIG RRs and how to resolve conflicts if these RRSIG RRs lead to differing results.

If the resolver accepts the RRset as authentic, the validator MUST set the TTL of the RRSIG RR and each RR in the authenticated RRset to a value no greater than the minimum of:

  • the RRset's TTL as received in the response;
  • the RRSIG RR's TTL as received in the response;
  • the value in the RRSIG RR's Original TTL field; and
  • the difference of the RRSIG RR's Signature Expiration time and the current time.

5.3.4. Authenticating a Wildcard Expanded RRset Positive Response πŸƒ

If the number of labels in an RRset's owner name is greater than the Labels field of the covering RRSIG RR, then the RRset and its covering RRSIG RR were created as a result of wildcard expansion. Once the validator has verified the signature, as described in Section 5.3, it must take additional steps to verify the non-existence of an exact match or closer wildcard match for the query. Section 5.4 discusses these steps.

Note that the response received by the resolver should include all NSEC RRs needed to authenticate the response (see Section 3.1.3).

5.4. Authenticated Denial of Existence πŸ™ˆ

A resolver can use authenticated NSEC RRs to prove that an RRset is not present in a signed zone. Security-aware name servers should automatically include any necessary NSEC RRs for signed zones in their responses to security-aware resolvers.

Denial of existence is determined by the following rules:

  • If the requested RR name matches the owner name of an authenticated NSEC RR, then the NSEC RR's type bit map field lists all RR types present at that owner name, and a resolver can prove that the requested RR type does not exist by checking for the RR type in the bit map. If the number of labels in an authenticated NSEC RR's owner name equals the Labels field of the covering RRSIG RR, then the existence of the NSEC RR proves that wildcard expansion could not have been used to match the request.
  • If the requested RR name would appear after an authenticated NSEC RR's owner name and before the name listed in that NSEC RR's Next Domain Name field according to the canonical DNS name order defined in [RFC4034], then no RRsets with the requested name exist in the zone. However, it is possible that a wildcard could be used to match the requested RR owner name and type, so proving that the requested RRset does not exist also requires proving that no possible wildcard RRset exists that could have been used to generate a positive response.

In addition, security-aware resolvers MUST authenticate the NSEC RRsets that comprise the non-existence proof as described in Section 5.3.

To prove the non-existence of an RRset, the resolver must be able to verify both that the queried RRset does not exist and that no relevant wildcard RRset exists. Proving this may require more than one NSEC RRset from the zone. If the complete set of necessary NSEC RRsets is not present in a response (perhaps due to message truncation), then a security-aware resolver MUST resend the query in order to attempt to obtain the full collection of NSEC RRs necessary to verify the non-existence of the requested RRset. As with all DNS operations, however, the resolver MUST bound the work it puts into answering any particular query.

Since a validated NSEC RR proves the existence of both itself and its corresponding RRSIG RR, a validator MUST ignore the settings of the NSEC and RRSIG bits in an NSEC RR.

5.5. Resolver Behavior When Signatures Do Not Validate 🚫

If for whatever reason none of the RRSIGs can be validated, the response SHOULD be considered BAD. If the validation was being done to service a recursive query, the name server MUST return RCODE 2 to the originating client. However, it MUST return the full response if and only if the original query had the CD bit set. Also see Section 4.7 on caching responses that do not validate.

5.6. Authentication Example πŸŽ€

Appendix C shows an example of the authentication process.

6. IANA Considerations πŸ“‹

[RFC4034] contains a review of the IANA considerations introduced by DNSSEC. The following are additional IANA considerations discussed in this document:

[RFC2535] reserved the CD and AD bits in the message header. The meaning of the AD bit was redefined in [RFC3655], and the meaning of both the CD and AD bit are restated in this document. No new bits in the DNS message header are defined in this document.

[RFC2671] introduced EDNS, and [RFC3225] reserved the DNSSEC OK bit and defined its use. The use is restated but not altered in this document. πŸ¦‹

7. Security Considerations πŸ”

okay bestie, this is the serious section πŸ₯Ί DNSSEC uses public key cryptography to sign and authenticate DNS resource record sets. For terminology and general DNSSEC security considerations, check out [RFC4033]. For the stuff specific to the DNSSEC resource record types, see [RFC4034].

🚨 this part is dramatic, so pay attention: an active attacker who can set the CD bit in a DNS query message, or the AD bit in a DNS response message, can use those bits to totally defeat the protection DNSSEC is trying to give security-oblivious recursive-mode resolvers πŸ’€ That's why a security-aware recursive-mode resolver using these control bits needs a secure channel, no cap. See Sections 3.2.2 and 4.9 for the full tea πŸ«–

The protocol in this document tries to extend the benefits of DNSSEC to security-oblivious stub resolvers πŸ¦‹ But recovering from validation failures is probably specific to each application, so the facilities DNSSEC gives stub resolvers might not be enough 😭 Operators of security-aware recursive name servers have to pay close attention to how the applications using their services behave when they pick a local validation policy. If they don't, the recursive name server could accidentally deny service to the exact clients it's supposed to support πŸ’…


8. Acknowledgements πŸ™Œ

this document was built from the input and ideas of the DNS Extensions Working Group and its mailing list, so a big thank you to everyone 🫢 The editors appreciate all the comments and suggestions they got while revising these security extension specs. Listing everyone who contributed over the decade DNSSEC was in development would be impossible πŸ˜… but [RFC4033] includes a list of some of the participants who were kind enough to comment on these documents ✨


9. References πŸ“š

9.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.
  • [RFC1122] Braden, R., "Requirements for Internet Hosts - Communication Layers", STD 3, RFC 1122, October 1989.
  • [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [RFC2181] Elz, R. and R. Bush, "Clarifications to the DNS Specification", RFC 2181, July 1997.
  • [RFC2460] Deering, S. and R. Hinden, "Internet Protocol, Version 6 (IPv6) Specification", RFC 2460, December 1998.
  • [RFC2671] Vixie, P., "Extension Mechanisms for DNS (EDNS0)", RFC 2671, August 1999.
  • [RFC2672] Crawford, M., "Non-Terminal DNS Name Redirection", RFC 2672, August 1999.
  • [RFC3225] Conrad, D., "Indicating Resolver Support of DNSSEC", RFC 3225, December 2001.
  • [RFC3226] Gudmundsson, O., "DNSSEC and IPv6 A6 aware server/resolver message size requirements", RFC 3226, December 2001.
  • [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 DNS Security Extensions", RFC 4034, March 2005.

9.2. Informative References 🌸

  • [RFC2308] Andrews, M., "Negative Caching of DNS Queries (DNS NCACHE)", RFC 2308, March 1998.
  • [RFC2535] Eastlake 3rd, D., "Domain Name System Security Extensions", RFC 2535, March 1999.
  • [RFC3007] Wellington, B., "Secure Domain Name System (DNS) Dynamic Update", RFC 3007, November 2000.
  • [RFC3655] Wellington, B. and O. Gudmundsson, "Redefinition of DNS Authenticated Data (AD) bit", RFC 3655, November 2003.

Appendix A. Signed Zone Example 🧚

the following example shows a (small) complete signed zone, and it's honestly so pretty to look at πŸŽ€

example.       3600 IN SOA ns1.example. bugs.x.w.example. (
                           1081539377
                           3600
                           300
                           3600000
                           3600
                           )
               3600 RRSIG  SOA 5 1 3600 20040509183619 (
                           20040409183619 38519 example.
                           ONx0k36rcjaxYtcNgq6iQnpNV5+drqYAsC9h
                           7TSJaHCqbhE67Sr6aH2xDUGcqQWu/n0UVzrF
                           vkgO9ebarZ0GWDKcuwlM6eNB5SiX2K74l5LW
                           DA7S/Un/IbtDq4Ay8NMNLQI7Dw7n4p8/rjkB
                           jV7j86HyQgM5e7+miRAz8V01b0I= )
               3600 NS     ns1.example.
               3600 NS     ns2.example.
               3600 RRSIG  NS 5 1 3600 20040509183619 (
                           20040409183619 38519 example.
                           gl13F00f2U0R+SWiXXLHwsMY+qStYy5k6zfd
                           EuivWc+wd1fmbNCyql0Tk7lHTX6UOxc8AgNf
                           4ISFve8XqF4q+o9qlnqIzmppU3LiNeKT4FZ8
                           RO5urFOvoMRTbQxW3U0hXWuggE4g3ZpsHv48
                           0HjMeRaZB/FRPGfJPajngcq6Kwg= )
               3600 MX     1 xx.example.
               3600 RRSIG  MX 5 1 3600 20040509183619 (
                           20040409183619 38519 example.
                           HyDHYVT5KHSZ7HtO/vypumPmSZQrcOP3tzWB
                           2qaKkHVPfau/DgLgS/IKENkYOGL95G4N+NzE
                           VyNU8dcTOckT+ChPcGeVjguQ7a3Ao9Z/ZkUO
                           6gmmUW4b89rz1PUxW4jzUxj66PTwoVtUU/iM
                           W6OISukd1EQt7a0kygkg+PEDxdI= )
               3600 NSEC   a.example. NS SOA MX RRSIG NSEC DNSKEY
               3600 RRSIG  NSEC 5 1 3600 20040509183619 (
                           20040409183619 38519 example.
                           O0k558jHhyrC97ISHnislm4kLMW48C7U7cBm
                           FTfhke5iVqNRVTB1STLMpgpbDIC9hcryoO0V
                           Z9ME5xPzUEhbvGnHd5sfzgFVeGxr5Nyyq4tW
                           SDBgIBiLQUv1ivy29vhXy7WgR62dPrZ0PWvm
                           jfFJ5arXf4nPxp/kEowGgBRzY/U= )
               3600 DNSKEY 256 3 5 (
                           AQOy1bZVvpPqhg4j7EJoM9rI3ZmyEx2OzDBV
                           rZy/lvI5CQePxXHZS4i8dANH4DX3tbHol61e
                           k8EFMcsGXxKciJFHyhl94C+NwILQdzsUlSFo
                           vBZsyl/NX6yEbtw/xN9ZNcrbYvgjjZ/UVPZI
                           ySFNsgEYvh0z2542lzMKR4Dh8uZffQ==
                           )
               3600 DNSKEY 257 3 5 (
                           AQOeX7+baTmvpVHb2CcLnL1dMRWbuscRvHXl
                           LnXwDzvqp4tZVKp1sZMepFb8MvxhhW3y/0QZ
                           syCjczGJ1qk8vJe52iOhInKROVLRwxGpMfzP
                           RLMlGybr51bOV/1se0ODacj3DomyB4QB5gKT
                           Yot/K9alk5/j8vfd4jWCWD+E1Sze0Q==
                           )
               3600 RRSIG  DNSKEY 5 1 3600 20040509183619 (
                           20040409183619 9465 example.
                           ZxgauAuIj+k1YoVEOSlZfx41fcmKzTFHoweZ
                           xYnz99JVQZJ33wFS0Q0jcP7VXKkaElXk9nYJ
                           XevO/7nAbo88iWsMkSpSR6jWzYYKwfrBI/L9
                           hjYmyVO9m6FjQ7uwM4dCP/bIuV/DKqOAK9NY
                           NC3AHfvCV1Tp4VKDqxqG7R5tTVM= )
               3600 RRSIG  DNSKEY 5 1 3600 20040509183619 (
                           20040409183619 38519 example.
                           eGL0s90glUqcOmloo/2y+bSzyEfKVOQViD9Z
                           DNhLz/Yn9CQZlDVRJffACQDAUhXpU/oP34ri
                           bKBpysRXosczFrKqS5Oa0bzMOfXCXup9qHAp
                           eFIku28Vqfr8Nt7cigZLxjK+u0Ws/4lIRjKk
                           7z5OXogYVaFzHKillDt3HRxHIZM= )
a.example.     3600 IN NS  ns1.a.example.
               3600 IN NS  ns2.a.example.
               3600 DS     57855 5 1 (
                           B6DCD485719ADCA18E5F3D48A2331627FDD3
                           636B )
               3600 RRSIG  DS 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                           oXIKit/QtdG64J/CB+Gi8dOvnwRvqrto1AdQ
                           oRkAN15FP3iZ7suB7gvTBmXzCjL7XUgQVcoH
                           kdhyCuzp8W9qJHgRUSwKKkczSyuL64nhgjuD
                           EML8l9wlWVsl7PR2VnZduM9bLyBhaaPmRKX/
                           Fm+v6ccF2EGNLRiY08kdkz+XHHo= )
               3600 NSEC   ai.example. NS DS RRSIG NSEC
               3600 RRSIG  NSEC 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                           cOlYgqJLqlRqmBQ3iap2SyIsK4O5aqpKSoba
                           U9fQ5SMApZmHfq3AgLflkrkXRXvgxTQSKkG2
                           039/cRUs6Jk/25+fi7Xr5nOVJsb0lq4zsB3I
                           BBdjyGDAHE0F5ROJj87996vJupdm1fbH481g
                           sdkOW6Zyqtz3Zos8N0BBkEx+2G4= )
ns1.a.example. 3600 IN A   192.0.2.5
ns2.a.example. 3600 IN A   192.0.2.6
ai.example.    3600 IN A   192.0.2.9
               3600 RRSIG  A 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                              pAOtzLP2MU0tDJUwHOKE5FPIIHmdYsCgTb5B
                              ERGgpnJluA9ixOyf6xxVCgrEJW0WNZSsJicd
                              hBHXfDmAGKUajUUlYSAH8tS4ZnrhyymIvk3u
                              ArDu2wfT130e9UHnumaHHMpUTosKe22PblOy
                              6zrTpg9FkS0XGVmYRvOTNYx2HvQ= )
                  3600 HINFO  "KLH-10" "ITS"
                  3600 RRSIG  HINFO 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              Iq/RGCbBdKzcYzlGE4ovbr5YcB+ezxbZ9W0l
                              e/7WqyvhOO9J16HxhhL7VY/IKmTUY0GGdcfh
                              ZEOCkf4lEykZF9NPok1/R/fWrtzNp8jobuY7
                              AZEcZadp1WdDF3jc2/ndCa5XZhLKD3JzOsBw
                              FvL8sqlS5QS6FY/ijFEDnI4RkZA= )
                  3600 AAAA   2001:db8::f00:baa9
                  3600 RRSIG  AAAA 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              nLcpFuXdT35AcE+EoafOUkl69KB+/e56XmFK
                              kewXG2IadYLKAOBIoR5+VoQV3XgTcofTJNsh
                              1rnF6Eav2zpZB3byI6yo2bwY8MNkr4A7cL9T
                              cMmDwV/hWFKsbGBsj8xSCN/caEL2CWY/5XP2
                              sZM6QjBBLmukH30+w1z3h8PUP2o= )
                  3600 NSEC   b.example. A HINFO AAAA RRSIG NSEC
                  3600 RRSIG  NSEC 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              QoshyPevLcJ/xcRpEtMft1uoIrcrieVcc9pG
                              CScIn5Glnib40T6ayVOimXwdSTZ/8ISXGj4p
                              P8Sh0PlA6olZQ84L453/BUqB8BpdOGky4hsN
                              3AGcLEv1Gr0QMvirQaFcjzOECfnGyBm+wpFL
                              AhS+JOVfDI/79QtyTI0SaDWcg8U= )
   b.example.     3600 IN NS  ns1.b.example.
                  3600 IN NS  ns2.b.example.
                  3600 NSEC   ns1.example. NS RRSIG NSEC
                  3600 RRSIG  NSEC 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              GNuxHn844wfmUhPzGWKJCPY5ttEX/RfjDoOx
                              9ueK1PtYkOWKOOdiJ/PJKCYB3hYX+858dDWS
                              xb2qnV/LSTCNVBnkm6owOpysY97MVj5VQEWs
                              0lm9tFoqjcptQkmQKYPrwUnCSNwvvclSF1xZ
                              vhRXgWT7OuFXldoCG6TfVFMs9xE= )
   ns1.b.example. 3600 IN A   192.0.2.7
   ns2.b.example. 3600 IN A   192.0.2.8
   ns1.example.   3600 IN A   192.0.2.1
                  3600 RRSIG  A 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              F1C9HVhIcs10cZU09G5yIVfKJy5yRQQ3qVet
                              5pGhp82pzhAOMZ3K22JnmK4c+IjUeFp/to06
                              im5FVpHtbFisdjyPq84bhTv8vrXt5AB1wNB+
                              +iAqvIfdgW4sFNC6oADb1hK8QNauw9VePJhK
                              v/iVXSYC0b7mPSU+EOlknFpVECs= )
                  3600 NSEC   ns2.example. A RRSIG NSEC
                  3600 RRSIG  NSEC 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              I4hj+Kt6+8rCcHcUdolks2S+Wzri9h3fHas8
                              1rGN/eILdJHN7JpV6lLGPIh/8fIBkfvdyWnB
                              jjf1q3O7JgYO1UdI7FvBNWqaaEPJK3UkddBq
                              ZIaLi8Qr2XHkjq38BeQsbp8X0+6h4ETWSGT8
                              IZaIGBLryQWGLw6Y6X8dqhlnxJM= )
   ns2.example.   3600 IN A   192.0.2.2
                  3600 RRSIG  A 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              V7cQRw1TR+knlaL1z/psxlS1PcD37JJDaCMq
                              Qo6/u1qFQu6x+wuDHRH22Ap9ulJPQjFwMKOu
                              yfPGQPC8KzGdE3vt5snFEAoE1Vn3mQqtu7SO
                              6amIjk13Kj/jyJ4nGmdRIc/3cM3ipXFhNTKq
                              rdhx8SZ0yy4ObIRzIzvBFLiSS8o= )
                  3600 NSEC   *.w.example. A RRSIG NSEC
                  3600 RRSIG  NSEC 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              N0QzHvaJf5NRw1rE9uxS1Ltb2LZ73Qb9bKGE
                              VyaISkqzGpP3jYJXZJPVTq4UVEsgT3CgeHvb
                              3QbeJ5Dfb2V9NGCHj/OvF/LBxFFWwhLwzngH
                              l+bQAgAcMsLu/nL3nDi1y/JSQjAcdZNDl4bw
                              Ymx28EtgIpo9A0qmP08rMBqs1Jw= )
   *.w.example.   3600 IN MX  1 ai.example.
                  3600 RRSIG  MX 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              OMK8rAZlepfzLWW75Dxd63jy2wswESzxDKG2
                              f9AMN1CytCd10cYISAxfAdvXSZ7xujKAtPbc
                              tvOQ2ofO7AZJ+d01EeeQTVBPq4/6KCWhqe2X
                              TjnkVLNvvhnc0u28aoSsG0+4InvkkOHknKxw
                              4kX18MMR34i8lC36SR5xBni8vHI= )
                  3600 NSEC   x.w.example. MX RRSIG NSEC
                  3600 RRSIG  NSEC 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              r/mZnRC3I/VIcrelgIcteSxDhtsdlTDt8ng9
                              HSBlABOlzLxQtfgTnn8f+aOwJIAFe1Ee5RvU
                              5cVhQJNP5XpXMJHfyps8tVvfxSAXfahpYqtx
                              91gsmcV/1V9/bZAG55CefP9cM4Z9Y9NT9XQ8
                              s1InQ2UoIv6tJEaaKkP701j8OLA= )
   x.w.example.   3600 IN MX  1 xx.example.
                  3600 RRSIG  MX 5 3 3600 20040509183619 (
                              20040409183619 38519 example.
                              Il2WTZ+Bkv+OytBx4LItNW5mjB4RCwhOO8y1
                              XzPHZmZUTVYL7LaA63f6T9ysVBzJRI3KRjAP
                              H3U1qaYnDoN1DrWqmi9RJe4FoObkbcdm7P3I
                              kx70ePCoFgRz1Yq+bVVXCvGuAU4xALv3W/Y1
                              jNSlwZ2mSWKHfxFQxPtLj8s32+k= )
                  3600 NSEC   x.y.w.example. MX RRSIG NSEC
                  3600 RRSIG  NSEC 5 3 3600 20040509183619 (
                              20040409183619 38519 example.
                              aRbpHftxggzgMXdDlym9SsADqMZovZZl2QWK
                              vw8J0tZEUNQByH5Qfnf5N1FqH/pS46UA7A4E
                              mcWBN9PUA1pdPY6RVeaRlZlCr1IkVctvbtaI
                              NJuBba/VHm+pebTbKcAPIvL9tBOoh+to1h6e
                              IjgiM8PXkBQtxPq37wDKALkyn7Q= )
   x.y.w.example. 3600 IN MX  1 xx.example.
                  3600 RRSIG  MX 5 4 3600 20040509183619 (
                              20040409183619 38519 example.
                              k2bJHbwP5LH5qN4is39UiPzjAWYmJA38Hhia
                              t7i9t7nbX/e0FPnvDSQXzcK7UL+zrVA+3MDj
                              q1ub4q3SZgcbLMgexxIW3Va//LVrxkP6Xupq
                              GtOB9prkK54QTl/qZTXfMQpW480YOvVknhvb
                              +gLcMZBnHJ326nb/TOOmrqNmQQE= )
                  3600 NSEC   xx.example. MX RRSIG NSEC
                  3600 RRSIG  NSEC 5 4 3600 20040509183619 (
                              20040409183619 38519 example.
                              OvE6WUzN2ziieJcvKPWbCAyXyP6ef8cr6Csp
                              ArVSTzKSquNwbezZmkU7E34o5lmb6CWSSSpg
                              xw098kNUFnHcQf/LzY2zqRomubrNQhJTiDTX
                              a0ArunJQCzPjOYq5t0SLjm6qp6McJI1AP5Vr
                              QoKqJDCLnoAlcPOPKAm/jJkn3jk= )
   xx.example.    3600 IN A   192.0.2.10
                  3600 RRSIG  A 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              kBF4YxMGWF0D8r0cztL+2fWWOvN1U/GYSpYP
                              7SoKoNQ4fZKyk+weWGlKLIUM+uE1zjVTPXoa
                              0Z6WG0oZp46rkl1EzMcdMgoaeUzzAJ2BMq+Y
                              VdxG9IK1yZkYGY9AgbTOGPoAgbJyO9EPULsx
                              kbIDV6GPPSZVusnZU6OMgdgzHV4= )
                  3600 HINFO  "KLH-10" "TOPS-20"
                  3600 RRSIG  HINFO 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              GY2PLSXmMHkWHfLdggiox8+chWpeMNJLkML0
                              t+U/SXSUsoUdR91KNdNUkTDWamwcF8oFRjhq
                              BcPZ6EqrF+vl5v5oGuvSF7U52epfVTC+wWF8
                              3yCUeUw8YklhLWlvk8gQ15YKth0ITQy8/wI+
                              RgNvuwbioFSEuv2pNlkq0goYxNY= )
                  3600 AAAA   2001:db8::f00:baaa
                  3600 RRSIG  AAAA 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              Zzj0yodDxcBLnnOIwDsuKo5WqiaK24DlKg9C
                              aGaxDFiKgKobUj2jilYQHpGFn2poFRetZd4z
                              ulyQkssz2QHrVrPuTMS22knudCiwP4LWpVTr
                              U4zfeA+rDz9stmSBP/4PekH/x2IoAYnwctd/
                              xS9cL2QgW7FChw16mzlkH6/vsfs= )
                  3600 NSEC   example. A HINFO AAAA RRSIG NSEC
                  3600 RRSIG  NSEC 5 2 3600 20040509183619 (
                              20040409183619 38519 example.
                              ZFWUln6Avc8bmGl5GFjD3BwT530DUZKHNuoY
                              9A8lgXYyrxu+pqgFiRVbyZRQvVB5pccEOT3k
                              mvHgEa/HzbDB4PIYY79W+VHrgOxzdQGGCZzi
                              asXrpSGOWwSOElghPnMIi8xdF7qtCntr382W
                              GghLahumFIpg4MO3LS/prgzVVWo= )

Okay so the apex DNSKEY set has two DNSKEY RRs πŸ”‘, and the DNSKEY RDATA Flags say that both of them are zone keys πŸ’…. One of them also has the SEP flag set and has been used to sign the apex DNSKEY RRset, so this is the key that should be hashed to generate a DS record to be inserted into the parent zone 🫢. The other DNSKEY is used to sign all the other RRsets in the zone πŸ¦‹.

The zone includes a wildcard entry, *.w.example ✨. Note that the name *.w.example is used in constructing NSEC chains, and that the RRSIG covering the *.w.example MX RRset has a label count of 2 🌸.

The zone also includes two delegations 🏑. The delegation to b.example includes an NS RRset, glue address records, and an NSEC RR, and note that only the NSEC RRset is signed πŸ‘€. The delegation to a.example provides a DS RR, and note that only the NSEC and DS RRsets are signed 🧚.

Appendix B. Example Responses πŸŽ€

The examples in this section show response messages using the signed zone example in Appendix A, so you can see exactly what a real answer looks like πŸ’œ.

B.1. Answer πŸŽ€

Okay so this is a successful query to an authoritative server, and it's giving textbook perfect answer energy πŸ’…βœ¨

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

;; Answer
x.w.example.   3600 IN MX  1 xx.example.
x.w.example.   3600 RRSIG  MX 5 3 3600 20040509183619 (
                           20040409183619 38519 example.
                           Il2WTZ+Bkv+OytBx4LItNW5mjB4RCwhOO8y1
                           XzPHZmZUTVYL7LaA63f6T9ysVBzJRI3KRjAP
                           H3U1qaYnDoN1DrWqmi9RJe4FoObkbcdm7P3I
                           kx70ePCoFgRz1Yq+bVVXCvGuAU4xALv3W/Y1
                           jNSlwZ2mSWKHfxFQxPtLj8s32+k= )

;; Authority
example.       3600 NS     ns1.example.
example.       3600 NS     ns2.example.
example.       3600 RRSIG  NS 5 1 3600 20040509183619 (
                           20040409183619 38519 example.
                           gl13F00f2U0R+SWiXXLHwsMY+qStYy5k6zfd
                           EuivWc+wd1fmbNCyql0Tk7lHTX6UOxc8AgNf
                           4ISFve8XqF4q+o9qlnqIzmppU3LiNeKT4FZ8
                           RO5urFOvoMRTbQxW3U0hXWuggE4g3ZpsHv48
                           0HjMeRaZB/FRPGfJPajngcq6Kwg= )

;; Additional
xx.example.    3600 IN A   192.0.2.10
xx.example.    3600 RRSIG  A 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                           kBF4YxMGWF0D8r0cztL+2fWWOvN1U/GYSpYP
                           7SoKoNQ4fZKyk+weWGlKLIUM+uE1zjVTPXoa
                           0Z6WG0oZp46rkl1EzMcdMgoaeUzzAJ2BMq+Y
                           VdxG9IK1yZkYGY9AgbTOGPoAgbJyO9EPULsx
                           kbIDV6GPPSZVusnZU6OMgdgzHV4= )
xx.example.    3600 AAAA   2001:db8::f00:baaa
xx.example.    3600 RRSIG  AAAA 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                           Zzj0yodDxcBLnnOIwDsuKo5WqiaK24DlKg9C
                           aGaxDFiKgKobUj2jilYQHpGFn2poFRetZd4z
                           ulyQkssz2QHrVrPuTMS22knudCiwP4LWpVTr
                           U4zfeA+rDz9stmSBP/4PekH/x2IoAYnwctd/
                           xS9cL2QgW7FChw16mzlkH6/vsfs= )
ns1.example.   3600 IN A   192.0.2.1
ns1.example.   3600 RRSIG  A 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                           F1C9HVhIcs10cZU09G5yIVfKJy5yRQQ3qVet
                           5pGhp82pzhAOMZ3K22JnmK4c+IjUeFp/to06
                           im5FVpHtbFisdjyPq84bhTv8vrXt5AB1wNB+
                           +iAqvIfdgW4sFNC6oADb1hK8QNauw9VePJhK
                           v/iVXSYC0b7mPSU+EOlknFpVECs= )
ns2.example.   3600 IN A   192.0.2.2
ns2.example.   3600 RRSIG  A 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                           V7cQRw1TR+knlaL1z/psxlS1PcD37JJDaCMq
                           Qo6/u1qFQu6x+wuDHRH22Ap9ulJPQjFwMKOu
                           yfPGQPC8KzGdE3vt5snFEAoE1Vn3mQqtu7SO
                           6amIjk13Kj/jyJ4nGmdRIc/3cM3ipXFhNTKq
                           rdhx8SZ0yy4ObIRzIzvBFLiSS8o= )

B.2. Name Error πŸ™ˆ

Bestie, this is an authoritative name error, and the NSEC RRs are doing the heavy lifting here. They prove the name does not exist, and that no covering wildcard exists either. Iconic receipts πŸ§ΎπŸ’œ

;; Header: QR AA DO RCODE=3
;;
;; Question
ml.example.         IN A

;; Answer
;; (empty)

;; Authority
example.       3600 IN SOA ns1.example. bugs.x.w.example. (
                           1081539377
                           3600
                           300
                           3600000
                           3600
                           )
example.       3600 RRSIG  SOA 5 1 3600 20040509183619 (
                           20040409183619 38519 example.
                           ONx0k36rcjaxYtcNgq6iQnpNV5+drqYAsC9h
                           7TSJaHCqbhE67Sr6aH2xDUGcqQWu/n0UVzrF
                           vkgO9ebarZ0GWDKcuwlM6eNB5SiX2K74l5LW
                           DA7S/Un/IbtDq4Ay8NMNLQI7Dw7n4p8/rjkB
                           jV7j86HyQgM5e7+miRAz8V01b0I= )
b.example.     3600 NSEC   ns1.example. NS RRSIG NSEC
b.example.     3600 RRSIG  NSEC 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                           GNuxHn844wfmUhPzGWKJCPY5ttEX/RfjDoOx
                           9ueK1PtYkOWKOOdiJ/PJKCYB3hYX+858dDWS
                           xb2qnV/LSTCNVBnkm6owOpysY97MVj5VQEWs
                           0lm9tFoqjcptQkmQKYPrwUnCSNwvvclSF1xZ
                           vhRXgWT7OuFXldoCG6TfVFMs9xE= )
example.       3600 NSEC   a.example. NS SOA MX RRSIG NSEC DNSKEY
example.       3600 RRSIG  NSEC 5 1 3600 20040509183619 (
                           20040409183619 38519 example.
                           O0k558jHhyrC97ISHnislm4kLMW48C7U7cBm
                           FTfhke5iVqNRVTB1STLMpgpbDIC9hcryoO0V
                           Z9ME5xPzUEhbvGnHd5sfzgFVeGxr5Nyyq4tW
                           SDBgIBiLQUv1ivy29vhXy7WgR62dPrZ0PWvm
                           jfFJ5arXf4nPxp/kEowGgBRzY/U= )

;; Additional
;; (empty)

B.3. No Data Error πŸ’–

This one's a "no data" response, and it's giving "the name exists but that record type doesn't" vibes 🌸. The NSEC RR is the proof that the name is real and the requested RR type is missing.

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

;; Answer
;; (empty)

;; Authority
example.       3600 IN SOA ns1.example. bugs.x.w.example. (
                           1081539377
                           3600
                           300
                           3600000
                           3600
                           )
example.       3600 RRSIG  SOA 5 1 3600 20040509183619 (
                           20040409183619 38519 example.
                           ONx0k36rcjaxYtcNgq6iQnpNV5+drqYAsC9h
                           7TSJaHCqbhE67Sr6aH2xDUGcqQWu/n0UVzrF
                           vkgO9ebarZ0GWDKcuwlM6eNB5SiX2K74l5LW
                           DA7S/Un/IbtDq4Ay8NMNLQI7Dw7n4p8/rjkB
                           jV7j86HyQgM5e7+miRAz8V01b0I= )
ns1.example.   3600 NSEC   ns2.example. A RRSIG NSEC
ns1.example.   3600 RRSIG  NSEC 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                           I4hj+Kt6+8rCcHcUdolks2S+Wzri9h3fHas8
                           1rGN/eILdJHN7JpV6lLGPIh/8fIBkfvdyWnB
                           jjf1q3O7JgYO1UdI7FvBNWqaaEPJK3UkddBq
                           ZIaLi8Qr2XHkjq38BeQsbp8X0+6h4ETWSGT8
                           IZaIGBLryQWGLw6Y6X8dqhlnxJM= )

;; Additional
;; (empty)

B.4. Referral to Signed Zone 🧚

Referral to a signed zone, and this is the main character moment πŸ‘‘. The DS RR holds the data the resolver needs to validate the DNSKEY RR at the child zone's apex.

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

;; Answer
;; (empty)

;; Authority
a.example.     3600 IN NS  ns1.a.example.
a.example.     3600 IN NS  ns2.a.example.
a.example.     3600 DS     57855 5 1 (
                           B6DCD485719ADCA18E5F3D48A2331627FDD3
                           636B )
a.example.     3600 RRSIG  DS 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                           oXIKit/QtdG64J/CB+Gi8dOvnwRvqrto1AdQ
                           oRkAN15FP3iZ7suB7gvTBmXzCjL7XUgQVcoH
                           kdhyCuzp8W9qJHgRUSwKKkczSyuL64nhgjuD
                           EML8l9wlWVsl7PR2VnZduM9bLyBhaaPmRKX/
                           Fm+v6ccF2EGNLRiY08kdkz+XHHo= )

;; Additional
ns1.a.example. 3600 IN A   192.0.2.5
ns2.a.example. 3600 IN A   192.0.2.6

B.5. Referral to Unsigned Zone 🌈

Referral to an unsigned zone! The NSEC RR is the receipt proving there's no DS RR for this delegation in the parent zone. Lowkey a clean little plot twist πŸ¦‹

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

;; Answer
;; (empty)

;; Authority
b.example.     3600 IN NS  ns1.b.example.
b.example.     3600 IN NS  ns2.b.example.
b.example.     3600 NSEC   ns1.example. NS RRSIG NSEC
b.example.     3600 RRSIG  NSEC 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                           GNuxHn844wfmUhPzGWKJCPY5ttEX/RfjDoOx
                           9ueK1PtYkOWKOOdiJ/PJKCYB3hYX+858dDWS
                           xb2qnV/LSTCNVBnkm6owOpysY97MVj5VQEWs
                           0lm9tFoqjcptQkmQKYPrwUnCSNwvvclSF1xZ
                           vhRXgWT7OuFXldoCG6TfVFMs9xE= )

;; Additional
ns1.b.example. 3600 IN A   192.0.2.7
ns2.b.example. 3600 IN A   192.0.2.8

B.6. Wildcard Expansion ⭐

Okay this one is so cute πŸ₯Ή. It's a successful query answered via wildcard expansion. The label count in the answer's RRSIG RR tells you a wildcard RRset got expanded to make this response, and the NSEC RR proves no closer match exists in the zone. Wildcard energy, periodt πŸ’…πŸ”₯

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

;; Answer
a.z.w.example. 3600 IN MX  1 ai.example.
a.z.w.example. 3600 RRSIG  MX 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                           OMK8rAZlepfzLWW75Dxd63jy2wswESzxDKG2
                           f9AMN1CytCd10cYISAxfAdvXSZ7xujKAtPbc
                           tvOQ2ofO7AZJ+d01EeeQTVBPq4/6KCWhqe2X
                           TjnkVLNvvhnc0u28aoSsG0+4InvkkOHknKxw
                           4kX18MMR34i8lC36SR5xBni8vHI= )

;; Authority
example.       3600 NS     ns1.example.
example.       3600 NS     ns2.example.
example.       3600 RRSIG  NS 5 1 3600 20040509183619 (
                           20040409183619 38519 example.
                           gl13F00f2U0R+SWiXXLHwsMY+qStYy5k6zfd
                           EuivWc+wd1fmbNCyql0Tk7lHTX6UOxc8AgNf
                           4ISFve8XqF4q+o9qlnqIzmppU3LiNeKT4FZ8
                           RO5urFOvoMRTbQxW3U0hXWuggE4g3ZpsHv48
                           0HjMeRaZB/FRPGfJPajngcq6Kwg= )
x.y.w.example. 3600 NSEC   xx.example. MX RRSIG NSEC
x.y.w.example. 3600 RRSIG  NSEC 5 4 3600 20040509183619 (
                           20040409183619 38519 example.
                           OvE6WUzN2ziieJcvKPWbCAyXyP6ef8cr6Csp
                           ArVSTzKSquNwbezZmkU7E34o5lmb6CWSSSpg
                           xw098kNUFnHcQf/LzY2zqRomubrNQhJTiDTX
                           a0ArunJQCzPjOYq5t0SLjm6qp6McJI1AP5Vr
                           QoKqJDCLnoAlcPOPKAm/jJkn3jk= )

;; Additional
ai.example.    3600 IN A   192.0.2.9
ai.example.    3600 RRSIG  A 5 2 3600 20040509183619 (

                           20040409183619 38519 example.
                           pAOtzLP2MU0tDJUwHOKE5FPIIHmdYsCgTb5B
                           ERGgpnJluA9ixOyf6xxVCgrEJW0WNZSsJicd
                           hBHXfDmAGKUajUUlYSAH8tS4ZnrhyymIvk3u
                           ArDu2wfT130e9UHnumaHHMpUTosKe22PblOy
                           6zrTpg9FkS0XGVmYRvOTNYx2HvQ= )
ai.example.    3600 AAAA   2001:db8::f00:baa9
ai.example.    3600 RRSIG  AAAA 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                           nLcpFuXdT35AcE+EoafOUkl69KB+/e56XmFK
                           kewXG2IadYLKAOBIoR5+VoQV3XgTcofTJNsh
                           1rnF6Eav2zpZB3byI6yo2bwY8MNkr4A7cL9T
                           cMmDwV/hWFKsbGBsj8xSCN/caEL2CWY/5XP2
                           sZM6QjBBLmukH30+w1z3h8PUP2o= )

B.7. Wildcard No Data Error ✨

okay so this one is a "no data" response for a name that gets covered by a wildcard πŸ¦‹ the NSEC RRs are doing the heavy lifting here: they prove the matching wildcard name has no 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.       3600 IN SOA ns1.example. bugs.x.w.example. (
                           1081539377
                           3600
                           300
                           3600000
                           3600
                           )
example.       3600 RRSIG  SOA 5 1 3600 20040509183619 (
                           20040409183619 38519 example.
                           ONx0k36rcjaxYtcNgq6iQnpNV5+drqYAsC9h
                           7TSJaHCqbhE67Sr6aH2xDUGcqQWu/n0UVzrF
                           vkgO9ebarZ0GWDKcuwlM6eNB5SiX2K74l5LW
                           DA7S/Un/IbtDq4Ay8NMNLQI7Dw7n4p8/rjkB
                           jV7j86HyQgM5e7+miRAz8V01b0I= )
x.y.w.example. 3600 NSEC   xx.example. MX RRSIG NSEC
x.y.w.example. 3600 RRSIG  NSEC 5 4 3600 20040509183619 (
                           20040409183619 38519 example.
                           OvE6WUzN2ziieJcvKPWbCAyXyP6ef8cr6Csp
                           ArVSTzKSquNwbezZmkU7E34o5lmb6CWSSSpg
                           xw098kNUFnHcQf/LzY2zqRomubrNQhJTiDTX
                           a0ArunJQCzPjOYq5t0SLjm6qp6McJI1AP5Vr
                           QoKqJDCLnoAlcPOPKAm/jJkn3jk= )
*.w.example.   3600 NSEC   x.w.example. MX RRSIG NSEC
*.w.example.   3600 RRSIG  NSEC 5 2 3600 20040509183619 (
                           20040409183619 38519 example.
                           r/mZnRC3I/VIcrelgIcteSxDhtsdlTDt8ng9
                           HSBlABOlzLxQtfgTnn8f+aOwJIAFe1Ee5RvU
                           5cVhQJNP5XpXMJHfyps8tVvfxSAXfahpYqtx
                           91gsmcV/1V9/bZAG55CefP9cM4Z9Y9NT9XQ8
                           s1InQ2UoIv6tJEaaKkP701j8OLA= )

;; Additional
;; (empty)

B.8. DS Child Zone No Data Error πŸŽ€

this one is a "no data" response for a QTYPE=DS query that got mistakenly sent to a name server for the child zone πŸ™ˆ oops, wrong door bestie

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

;; Answer
;; (empty)

;; Authority
example.       3600 IN SOA ns1.example. bugs.x.w.example. (
                           1081539377
                           3600
                           300
                           3600000
                           3600
                           )
example.       3600 RRSIG  SOA 5 1 3600 20040509183619 (
                           20040409183619 38519 example.
                           ONx0k36rcjaxYtcNgq6iQnpNV5+drqYAsC9h
                           7TSJaHCqbhE67Sr6aH2xDUGcqQWu/n0UVzrF
                           vkgO9ebarZ0GWDKcuwlM6eNB5SiX2K74l5LW
                           DA7S/Un/IbtDq4Ay8NMNLQI7Dw7n4p8/rjkB
                           jV7j86HyQgM5e7+miRAz8V01b0I= )
example.       3600 NSEC   a.example. NS SOA MX RRSIG NSEC DNSKEY
example.       3600 RRSIG  NSEC 5 1 3600 20040509183619 (
                           20040409183619 38519 example.
                           O0k558jHhyrC97ISHnislm4kLMW48C7U7cBm
                           FTfhke5iVqNRVTB1STLMpgpbDIC9hcryoO0V
                           Z9ME5xPzUEhbvGnHd5sfzgFVeGxr5Nyyq4tW
                           SDBgIBiLQUv1ivy29vhXy7WgR62dPrZ0PWvm
                           jfFJ5arXf4nPxp/kEowGgBRzY/U= )

;; Additional
;; (empty)

Appendix C. Authentication Examples 🧚

the examples in this section show how the response messages in Appendix B get authenticated πŸ”₯ this is the part where we actually check the receipts πŸ§ΎπŸ’…

C.1. Authenticating an Answer πŸ’–

the query in Appendix B.1 returned an MX RRset for "x.w.example.com" πŸ“ the matching RRSIG tells us the MX RRset was signed by an "example" DNSKEY with algorithm 5 and key tag 38519 ✨ the resolver needs that DNSKEY RR to authenticate the answer, and the discussion below walks through how a resolver might go grab it πŸ¦‹

the RRSIG says the original TTL of the MX RRset was 3600 ⏰ and for authentication purposes, the current TTL gets swapped out for 3600 πŸ’œ a labels field value of 3 means the answer was not the result of wildcard expansion πŸ™…β€β™€οΈ so we put the "x.w.example.com" MX RRset in canonical form and, as long as the current time sits between the signature inception and expiration dates, the signature checks out πŸŽ€βœ…

C.1.1. Authenticating the Example DNSKEY RR 🌈

this is the logical authentication process that starts from a configured root DNSKEY (or DS RR) and walks down the tree to authenticate the "example" DNSKEY RR 🌸 the logical order is presented for clarity, so don't read it as a rigid recipe. An implementation may choose to construct the authentication as referrals come in, or to construct the authentication chain only after all RRsets have been obtained, or any other combo it sees fit 🫢 this example only shows the logical process and does not dictate any implementation rules, so chill 😌

we assume the resolver starts with a configured DNSKEY RR for the root zone (or a configured DS RR for the root zone) 🌍 the resolver checks whether this configured DNSKEY RR is present in the root DNSKEY RRset (or whether the DS RR matches some DNSKEY in the root DNSKEY RRset), whether this DNSKEY RR has signed the root DNSKEY RRset, and whether the signature lifetime is valid πŸ•°οΈ if all those conditions are met, all keys in the DNSKEY RRset are considered authenticated πŸ” then the resolver uses one (or more) of the root DNSKEY RRs to authenticate the "example" DS RRset πŸ‘‘ heads up, the resolver may have to query the root zone to get the root DNSKEY RRset or "example" DS RRset, which is totally normal πŸ’…

once the DS RRset has been authenticated using the root DNSKEY, the resolver checks the "example" DNSKEY RRset for some "example" DNSKEY RR that matches one of the authenticated "example" DS RRs πŸ’œ if a matching "example" DNSKEY is found, the resolver checks whether this DNSKEY RR has signed the "example" DNSKEY RRset and whether the signature lifetime is valid ⭐ if those conditions are met, all keys in the "example" DNSKEY RRset are considered authenticated πŸ¦‹

finally, the resolver checks that some DNSKEY RR in the "example" DNSKEY RRset uses algorithm 5 and has a key tag of 38519 🎯 this DNSKEY is what gets used to authenticate the RRSIG included in the response 🫢 if multiple "example" DNSKEY RRs match that algorithm and key tag, then each DNSKEY RR is tried, and the answer is authenticated if any of the matching DNSKEY RRs validate the signature as described above πŸ” main character energy for the DNSKEY lineup πŸ‘‘

C.2. Name Error πŸ™ˆ

the query in Appendix B.2 returned NSEC RRs that prove the requested data does not exist and no wildcard applies 🚫 the negative reply is authenticated by verifying both NSEC RRs 🧾 and yes, the NSEC RRs get authenticated the same way as the MX RRset we just did πŸ’…

C.3. No Data Error 🌸

the query in Appendix B.3 returned an NSEC RR that proves the requested name exists, but the requested RR type does not πŸ₯² the negative reply is authenticated by verifying that NSEC RR, and it gets authenticated in a manner identical to the MX RRset discussed above ✨

C.4. Referral to Signed Zone πŸŽ€

the query in Appendix B.4 returned a referral to the signed "a.example." zone πŸ“ the DS RR is authenticated in the same way as the MX RRset above, and then this DS RR is used to authenticate the "a.example" DNSKEY RRset πŸ”‘

once the "a.example" DS RRset has been authenticated using the "example" DNSKEY, the resolver checks the "a.example" DNSKEY RRset for some "a.example" DNSKEY RR that matches the DS RR πŸ’– if a matching "a.example" DNSKEY is found, the resolver checks whether this DNSKEY RR has signed the "a.example" DNSKEY RRset and whether the signature lifetime is valid πŸ•°οΈ if all these conditions are met, all keys in the "a.example" DNSKEY RRset are considered authenticated 🌈

C.5. Referral to Unsigned Zone πŸ¦‹

the query in Appendix B.5 returned a referral to an unsigned "b.example." zone πŸ«₯ the NSEC proves that no authentication leads from "example" to "b.example", and the NSEC RR is authenticated in a manner identical to the MX RRset discussed above πŸ”

C.6. Wildcard Expansion ✨

the query in Appendix B.6 returned an answer that was produced as a result of wildcard expansion 🌟 the answer section contains a wildcard RRset expanded the way it would be in a traditional DNS response, and the corresponding RRSIG says the expanded wildcard MX RRset was signed by an "example" DNSKEY with algorithm 5 and key tag 38519 πŸ”‘ the RRSIG indicates the original TTL of the MX RRset was 3600, and for authentication purposes, the current TTL is replaced by 3600 ⏰

the RRSIG labels field value of 2 means the answer is the result of wildcard expansion, since the "a.z.w.example" name contains 4 labels πŸ™Œ the name "a.z.w.w.example" gets replaced by "*.w.example", the MX RRset goes into canonical form, and, assuming the current time falls between the signature inception and expiration dates, the signature is authenticated πŸŽ€βœ…

the NSEC proves that no closer match (exact or closer wildcard) could have been used to answer this query πŸ•΅οΈβ€β™€οΈ and the NSEC RR must also be authenticated before the answer is considered valid, so don't skip it bestie πŸ’…

C.7. Wildcard No Data Error πŸŒ™

the query in Appendix B.7 returned NSEC RRs that prove the requested data does not exist and no wildcard applies 🫧 the negative reply is authenticated by verifying both NSEC RRs, no cap 🧒

C.8. DS Child Zone No Data Error πŸ’œ

the query in Appendix B.8 returned NSEC RRs that shows the requested was answered by a child server ("example" server) 🫠 the NSEC RR indicates the presence of an SOA RR, which shows that the answer is from the child . 🌷 queries for the "example" DS RRset should be sent to the parent servers ("root" servers), so the DS question goes up the tree, not down 🌳 remember the DS lives at the parent 🧚


Authors' Addresses πŸ’Œ

Roy Arends
Telematica Instituut
Brouwerijstraat 1
7523 XC  Enschede
NL

EMail: roy.arends@telin.nl


Rob Austein
Internet Systems Consortium
950 Charter Street
Redwood City, CA  94063
USA

EMail: sra@isc.org


Matt Larson
VeriSign, Inc.
21345 Ridgetop Circle
Dulles, VA  20166-6503
USA

EMail: mlarson@verisign.com


Dan Massey
Colorado State University
Department of Computer Science
Fort Collins, CO 80523-1873

EMail: massey@cs.colostate.edu


Scott Rose
National Institute for Standards and Technology
100 Bureau Drive
Gaithersburg, MD  20899-8920
USA

EMail: scott.rose@nist.gov

Copyright (C) The Internet Society (2005).

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 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 πŸŽ€

okay so bestie, the IETF is not going to say whether any patent or other rights floating around might apply to the tech in this doc, or whether you can get a license for it. they also haven't gone looking for any of that stuff themselves 🫠 if you want the rules on RFC rights, check out BCP 78 and BCP 79 ✨

any IPR disclosures that got sent to the IETF Secretariat, plus any promises to license, or the results of anyone trying to get a general license for implementers or users, can be found in the IETF online IPR repository at http://www.ietf.org/ipr πŸ’–

the IETF also wants you to tell it about any copyrights, patents, patent applications, or other proprietary rights that might cover tech you'd need to implement this standard. send that info to the IETF at ietf-ipr@ietf.org πŸ“¨ it's giving "please help us out" energy and honestly that's so reasonable πŸ₯Ί

Acknowledgement 🌸

the RFC Editor function is funded right now by the Internet Society. thank u ISOC 🫢

πŸ“¦ where this page comes from