DNSSEC22
Status: Final
Purpose
- Verify that the address records (
AandAAAA) of every in-domain nameserver name of the zone validate under the chain of trust of the zone. - An in-domain nameserver name (RFC 9499 section 7) is an
NStarget at or below the apex of the zone under test. Its address records are served by the zone itself or by a zone delegated below it, so they are inside the authentication chain the zone owns. - A validating resolver that refreshes such an address authoritatively receives SERVFAIL when the records are bogus and stops using that nameserver. No other testcase reads a signature below the apex: the address records of in-domain names are resolved with DO=0 and glue is accepted, so a bogus name is reported as resolvable.
- A name a nameserver of the zone refers to a delegated zone whose DS validates is evaluated on the nameservers of that zone. The zone under test signs the DS, so the chain into the delegated zone is its own.
Preconditions And Inputs
- Preconditions:
- A
zone.Zoneobject is available. - At least one in-domain nameserver name exists. The root zone has an empty name set by rule, see Edge Cases And Limitations.
- The zone is secure: at least one child nameserver returns an apex DNSKEY RRset and at least one parent nameserver returns a DS RRset for the zone name.
- A
- Required inputs:
- Child nameserver name/IP items from
DelegationNameserversandZoneNameservers, deduplicated by IP. - The parent-side delegation
NSnames and the child apexNSnames. - Apex DNSKEY RRset of the zone from a child nameserver, DS RRset of the zone from a parent nameserver. In a full run both are served from the per-nameserver query cache (DNSSEC10 for DNSKEY, DNSSEC07 and DNSSEC21 for DS).
- Per child nameserver IP:
Aresponses (andAAAAwhere required) for each in-domain name, andDSandDNSKEYresponses for each probed zone cut, all with DNSSEC enabled. - Per referred zone cut whose DS validates: the
NSnames in the authority section of the referral and their glue in its additional section. No other source of address for the delegated zone is used. - Per nameserver IP of such a cut: a
DNSKEYresponse for the cut, andAresponses (andAAAAwhere required) for each in-domain name at or below it, all with DNSSEC enabled.
- Child nameserver name/IP items from
- Profile/config knobs that affect behavior:
net.ipv4andnet.ipv6: disabled transports are skipped with transport debug tags.resolver.defaults.parallel: per-nameserver parallel execution fanout.dnssec.signature_validity_skew: clock-skew tolerance used byverifyRRSIG.
Algorithm And Decision Flow
- Emit
TEST_CASE_START. - Build the name set: the union of the parent-side delegation
NSnames and the child apexNSnames, keeping every name N for whichz.Name.IsInBailiwick(N)holds, deduplicated case-insensitively. The apex itself is kept when it appears as anNStarget. For the root zone the name set is empty by rule.- Empty name set: emit
DS22_NO_IN_DOMAIN_NSandTEST_CASE_END, then stop. No query is made.
- Empty name set: emit
- Gate on zone security:
- If no child nameserver returns an apex DNSKEY RRset, or no parent
nameserver returns a DS RRset for the zone name, emit
DS22_ZONE_NOT_SECUREandTEST_CASE_END, then stop. Nothing below an unsigned zone or an island of security can be bogus.
- If no child nameserver returns an apex DNSKEY RRset, or no parent
nameserver returns a DS RRset for the zone name, emit
- For each unique child nameserver IP X (parallelized):
- If the transport is disabled, emit
IPV4_DISABLEDorIPV6_DISABLEDwithquery_typeA, and skip X. - Initialise the per-server state: an empty referral set and an empty zone cut memo.
- Process the names of the name set in order. For each name N:
- If N is at or below a cut C in the referral set, classify N by
referredCutStatus(X, C)as step 3 does. No query is made. - Query
N Aat X with DNSSEC enabled (UDP, retry over TCP onTC). - Classify the response and select the covering RRSIG records:
- No response, or a response whose RCODE is neither
NOERRORnorNXDOMAIN: no finding for N. - Referral (not
AA, empty answer section,NSRRset in the authority section): C is the owner name of thatNSRRset. Add C to the referral set and retain theNSnames of the RRset with their glue from the additional section. Classify N byreferredCutStatus(X, C). Steps 3.4 onward are not reached for N.insecure:DS22_NS_ADDRESS_INSECURE.broken:DS22_NS_ADDRESS_CHAIN_BROKENwithsignerC.secure delegation: N is deferred to C. Step 5 decides it.indeterminate: no finding for N.
AANXDOMAIN: no finding for N. Delegation and nameserver testcases own a nameserver name that does not exist.CNAMEin the answer section: no finding for N. RFC 2181 section 10.3 forbids an alias at a nameserver name and Delegation05 reports it.AANOERRORwith anARRset for N: the covering records are the answer-section RRSIG records covering typeAat N.AANOERRORwithout anARRset (NODATA): queryN AAAAat X with DNSSEC enabled. On anAANOERRORanswer with anAAAARRset, the covering records are the answer-section RRSIG records covering typeAAAAat N. On any other outcome, the covering records are the authority-section RRSIG records coveringNSECorNSEC3in theAresponse.- The signer S is the Signer’s Name of the covering RRSIG records. With no covering RRSIG record, S is undefined.
- No response, or a response whose RCODE is neither
- Determine the expected signer E. The walk order is N, then each proper
ancestor of N strictly below the zone apex, upward, then the apex:
- If S equals the zone name, E is the zone and no query is made. X holds no zone cut at or below N.
- Otherwise the walk starts at S when S is a member of the walk order, and at N otherwise. X answers from its most specific matching zone, so a zone cut between N and S would have answered instead and is not probed.
- E is the first name M in the walk, from the start position upward,
whose
cutStatus(X, M)issecure,insecureorbroken. If no such M exists, E is the zone.
- Classify N on X, in this order:
cutStatus(X, E)isinsecure:DS22_NS_ADDRESS_INSECURE. Validators accept the data unsigned.cutStatus(X, E)isbroken:DS22_NS_ADDRESS_CHAIN_BROKENwithsignerE.- S undefined:
DS22_NS_ADDRESS_UNSIGNED. - S equals E: verify each covering RRSIG against the DNSKEY RRset of E,
which is the apex DNSKEY RRset when E is the zone and the DNSKEY
RRset retained by
cutStatusotherwise, withpacketTimeof the response as the reference time.- A signature whose algorithm the local verifier cannot process
(
dnssecutil.AlgorithmSupportedfalse, orRSAExponentBeyondLocalVerifiertrue) is indeterminate and yields no finding. - Expiration in the past:
DS22_NS_ADDRESS_RRSIG_EXPIREDwithkeytag. - Inception in the future, no DNSKEY with that keytag, or
verification failure:
DS22_NS_ADDRESS_RRSIG_NOT_VALID_BY_DNSKEYwithsigner, and thekeytagandreasonof the first failing RRSIG. - At least one covering RRSIG verifies: N validates on X, no finding.
- A signature whose algorithm the local verifier cannot process
(
- S is a member of the walk order strictly below E and
cutStatus(X, S)isnot a cut:DS22_NS_ADDRESS_ORPHAN_ZONEwithsignerS. X serves S as a zone apex while the enclosing zone proves no delegation there. - S is a member of the walk order strictly below E and
cutStatus(X, S)isindeterminate: no finding. X stated nothing about S as a zone cut, so neither the orphan nor the signer conclusion is available. - Otherwise:
DS22_NS_ADDRESS_RRSIG_NOT_VALID_BY_DNSKEYwithsignerS, thekeytagof the first covering RRSIG andreasonsignature. The signature cannot verify under the chain of trust of the zone.
- If N is at or below a cut C in the referral set, classify N by
- If the transport is disabled, emit
- For each zone cut C with a name deferred in step 4, once per run. The
nameservers of C are the
NSnames of its retained referrals that have glue, deduplicated by IP across every nameserver that referred to C. AnNSname without glue is not resolved. For each unique nameserver IP Y of C (parallelized as step 4 is):- If the transport is disabled, emit
IPV4_DISABLEDorIPV6_DISABLEDwithquery_typeA, and skip Y. - Take the DNSKEY RRset of C at Y from
childKeys(Y, C, DS), DS being the RRsetreferredCutStatusvalidated.indeterminate: no result on Y.broken:DS22_NS_ADDRESS_CHAIN_BROKENwithsignerC for every name deferred to C.secure: continue at step 5.3.
- Process every name of the name set at or below C by step 4, with Y as the nameserver, C as the zone and that DNSKEY RRset as the zone keys. The referral set and the zone cut memo are Y’s own. A referral Y answers is classified and MUST NOT be followed: the follow is one level deep.
- If the transport is disabled, emit
- A name deferred to C that no nameserver settled, by a finding or by a
validated address RRset, yields
DS22_NS_ADDRESS_REFERREDwithnsN,zoneC andserversthe nameservers that referred it. - Aggregate across nameservers: one emission per tag and per distinct
combination of its arguments other than
servers, with the matchingserversmerged and sorted. - If no ERROR-level
DS22_*tag was emitted and at least one address RRset validated, emitDS22_NS_ADDRESS_VALIDATESwith the nameservers that validated at least one address RRset. - Emit
TEST_CASE_END.
Zone Cut Status
cutStatus(X, M) is the statement of nameserver X about the name M as a zone
cut, for a cut X itself serves. It queries M DS at X with DNSSEC enabled
(UDP, retry over TCP on TC) and returns one of secure, insecure,
broken, not a cut or indeterminate:
- No response, a response that is not
AA, or a referral:indeterminate. X does not serve the parent side of M. AANOERRORwith a DS RRset at M:- The signer P of the DS-covering RRSIG MUST be a proper ancestor of M at or
below the zone apex, otherwise
broken. - The DNSKEY RRset of P is the apex DNSKEY RRset when P is the zone;
otherwise
cutStatus(X, P)MUST besecureand supplies it, and any other status yieldsbroken. The recursion is bounded by the labels between M and the zone apex. - The DS RRSIG MUST verify against a DNSKEY of P, otherwise
broken. childKeys(X, M, DS)MUST besecure, otherwise its status is the status of M.- All conditions hold:
secure, retaining the DNSKEY RRset of M. - A signature whose algorithm the local verifier cannot process is
indeterminate, notbroken.
- The signer P of the DS-covering RRSIG MUST be a proper ancestor of M at or
below the zone apex, otherwise
AANOERRORwithout a DS RRset (NODATA):- NSEC3 records with a hash algorithm other than SHA-1 are ignored
(RFC 5155 section 8.1). Without an NSEC record whose owner is M, NSEC3 records that
carry more than one parameter set (RFC 5155 section 7.2), or an iteration
count above 50 (RFC 9276 section 3.2), are not evaluated:
indeterminate. - Locate the NSEC record whose owner is M, or the NSEC3 record whose owner matches the hash of M computed with the salt and iteration count of that record.
- Type bitmap with the NS bit and without the DS bit:
insecure(RFC 4035 section 5.2, RFC 5155 section 8.6). - Type bitmap with both the NS bit and the DS bit: the bitmap contradicts the
NODATA,
indeterminate. - Type bitmap without the NS bit:
not a cut. RFC 5155 section 8.9 and RFC 6840 section 4.4 make the NS bit the statement of the parent zone that a zone cut exists at the name. - No record matching M: the closest encloser CE is the longest proper
ancestor of M whose hash matches an NSEC3 record of the response, and the
next closer name is the ancestor of M, or M itself, one label below CE
(RFC 5155 section 1.3). An NSEC3 record with the Opt-Out flag set that
covers the hash of the next closer name yields
insecure: RFC 5155 sections 8.3 and 8.6 accept this proof for an unsigned delegation the parent omits from its NSEC3 chain. - An
insecureresult MUST rest on authenticated records (RFC 4035 section 5.4): the matching record, or the closest encloser record and the covering Opt-Out record. Each record MUST carry an RRSIG whose signer P is a proper ancestor of M at or below the zone apex and which verifies against the DNSKEY RRset of P, obtained as in the DS branch. Otherwise the result isbroken, orindeterminatefor a signature whose algorithm the local verifier cannot process. - Otherwise:
not a cut. With no NSEC and no NSEC3 record the enclosing zone is unsigned, which is valid only below an insecure delegation, and the walk decides from an ancestor.
- NSEC3 records with a hash algorithm other than SHA-1 are ignored
(RFC 5155 section 8.1). Without an NSEC record whose owner is M, NSEC3 records that
carry more than one parameter set (RFC 5155 section 7.2), or an iteration
count above 50 (RFC 9276 section 3.2), are not evaluated:
AANXDOMAIN:not a cut.
Every result is memoized per (X, M), indeterminate included, and reused by
every name below M on X.
childKeys(Y, M, DS) is the statement of nameserver Y about the keys of M
against an already validated DS RRset. It queries M DNSKEY at Y with DNSSEC
enabled and returns secure, broken or indeterminate:
- No response, or a response that is not
AANOERROR:indeterminate. Y does not serve M as a zone apex. - No DNSKEY matching a DS by keytag, algorithm and digest:
broken. - No RRSIG covering the DNSKEY RRset verifies under a matched key:
broken. - A signature whose algorithm the local verifier cannot process:
indeterminate. - All conditions hold:
secure, retaining the DNSKEY RRset of M.
referredCutStatus(X, C) is the statement of nameserver X about a name C it
referred to. It is cutStatus(X, C) up to and including the validation of the
DS RRset, and MUST NOT query C DNSKEY, which X does not serve. It returns
insecure, broken, indeterminate or secure delegation, the last
retaining the validated DS RRset of C. It shares the memo of cutStatus: a cut
X refers for is never a cut X serves.
Per-NS Name Validation And Aggregation (steps 2-9)
Emitted Tags (Possible Set)
| Tag | Emitted when |
|---|---|
DS22_NO_IN_DOMAIN_NS | No nameserver name of the zone is in-domain, the root zone included. |
DS22_NS_ADDRESS_CHAIN_BROKEN | The expected signer is a zone cut below the zone apex on the same nameserver, and its DS matches no DNSKEY, or its DNSKEY or DS RRSIG does not verify (RFC 4035 section 5.2), or the NSEC or NSEC3 record proving it insecure does not verify (RFC 4035 section 5.4). |
DS22_NS_ADDRESS_INSECURE | The name lies below an insecure delegation served by the same nameserver. |
DS22_NS_ADDRESS_ORPHAN_ZONE | The address records are signed by a name the nameserver serves as a zone apex, while the NSEC or NSEC3 record matching that name in the enclosing zone carries no NS bit, so no zone cut is proven. |
DS22_NS_ADDRESS_RRSIG_EXPIRED | The expiration of the RRSIG covering the address records is in the past (RFC 4035 section 5.3.1). |
DS22_NS_ADDRESS_REFERRED | The name lies below a delegation whose DS validates, and no nameserver of the delegated zone was reachable for it: no NS name of the referral carries glue, no such nameserver answered the DNSKEY question authoritatively, or the referral came from a nameserver of the delegated zone itself. |
DS22_NS_ADDRESS_RRSIG_NOT_VALID_BY_DNSKEY | The RRSIG covering the address records does not verify against the DNSKEY RRset of the zone that must sign the name: bad signature, a Labels field that does not fit the owner and signer, inception in the future, no DNSKEY with the keytag, or a signer that is neither the expected zone nor an orphan apex (RFC 4035 sections 5.3.1 and 5.3.3). |
DS22_NS_ADDRESS_UNSIGNED | The address records, or the NODATA proof standing for them, carry no RRSIG and no insecure delegation lies between the name and the zone apex (RFC 4035 sections 2.2 and 3.1.1). |
DS22_NS_ADDRESS_VALIDATES | At least one in-domain address RRset validated and no ERROR-level DS22_* tag was emitted. |
DS22_ZONE_NOT_SECURE | No child nameserver returned an apex DNSKEY RRset, or no parent nameserver returned a DS RRset for the zone. |
IPV4_DISABLED | IPv4 transport is disabled for a queried nameserver (A). |
IPV6_DISABLED | IPv6 transport is disabled for a queried nameserver (A). |
TEST_CASE_END | Testcase completion marker is emitted. |
TEST_CASE_START | Testcase start marker is emitted. |
Tag Arguments
| Tag | Argument key | Type | Meaning |
|---|---|---|---|
DS22_NS_ADDRESS_CHAIN_BROKEN | ns | string | In-domain nameserver name whose address records were evaluated. |
DS22_NS_ADDRESS_CHAIN_BROKEN | signer | string | Zone cut below the apex whose chain of trust is broken. |
DS22_NS_ADDRESS_CHAIN_BROKEN | servers | array<object> | Structured nameserver identities ({ns,address} object) that showed the broken chain. |
DS22_NS_ADDRESS_INSECURE | ns | string | In-domain nameserver name whose address records were evaluated. |
DS22_NS_ADDRESS_INSECURE | servers | array<object> | Structured nameserver identities ({ns,address} object) serving the name below an insecure delegation. |
DS22_NS_ADDRESS_ORPHAN_ZONE | ns | string | In-domain nameserver name whose address records were evaluated. |
DS22_NS_ADDRESS_ORPHAN_ZONE | signer | string | Signer’s Name of the RRSIG covering the address records, served as a zone apex without a proven delegation. |
DS22_NS_ADDRESS_ORPHAN_ZONE | servers | array<object> | Structured nameserver identities ({ns,address} object) exhibiting the orphan zone. |
DS22_NS_ADDRESS_REFERRED | ns | string | In-domain nameserver name whose address records were evaluated. |
DS22_NS_ADDRESS_REFERRED | zone | string | Zone cut the name lies below, whose DS validates. |
DS22_NS_ADDRESS_REFERRED | servers | array<object> | Structured nameserver identities ({ns,address} object) that referred the name to that zone. |
DS22_NS_ADDRESS_RRSIG_EXPIRED | ns | string | In-domain nameserver name whose address records were evaluated. |
DS22_NS_ADDRESS_RRSIG_EXPIRED | keytag | int | Keytag of the expired RRSIG. |
DS22_NS_ADDRESS_RRSIG_EXPIRED | servers | array<object> | Structured nameserver identities ({ns,address} object) that returned the expired RRSIG. |
DS22_NS_ADDRESS_RRSIG_NOT_VALID_BY_DNSKEY | ns | string | In-domain nameserver name whose address records were evaluated. |
DS22_NS_ADDRESS_RRSIG_NOT_VALID_BY_DNSKEY | signer | string | Signer’s Name of the failing RRSIG. |
DS22_NS_ADDRESS_RRSIG_NOT_VALID_BY_DNSKEY | keytag | int | Keytag of the failing RRSIG. |
DS22_NS_ADDRESS_RRSIG_NOT_VALID_BY_DNSKEY | reason | string | labels when the Labels field does not fit the owner and Signer’s Name, signature otherwise (Implementation Notes). |
DS22_NS_ADDRESS_RRSIG_NOT_VALID_BY_DNSKEY | servers | array<object> | Structured nameserver identities ({ns,address} object) that returned the failing RRSIG. |
DS22_NS_ADDRESS_UNSIGNED | ns | string | In-domain nameserver name whose address records were evaluated. |
DS22_NS_ADDRESS_UNSIGNED | servers | array<object> | Structured nameserver identities ({ns,address} object) that returned the unsigned records. |
DS22_NS_ADDRESS_VALIDATES | servers | array<object> | Structured nameserver identities ({ns,address} object) that validated at least one in-domain address RRset. |
IPV4_DISABLED | ns | string | Nameserver identity (ns name only; use address for IP) skipped on IPv4. |
IPV4_DISABLED | address | string | Nameserver IP address for the same endpoint. |
IPV4_DISABLED | query_type | string | Query type skipped (A). |
IPV6_DISABLED | ns | string | Nameserver identity (ns name only; use address for IP) skipped on IPv6. |
IPV6_DISABLED | address | string | Nameserver IP address for the same endpoint. |
IPV6_DISABLED | query_type | string | Query type skipped (A). |
TEST_CASE_END | testcase | string | Testcase display name (DNSSEC22). |
TEST_CASE_START | testcase | string | Testcase display name (DNSSEC22). |
DS22_NO_IN_DOMAIN_NS and DS22_ZONE_NOT_SECURE carry no arguments.
A servers value names the nameservers that showed the status, of the zone
under test or of a zone delegated below its apex.
Severity Levels Per Tag
The five failure tags describe a name that validating resolvers answer with
SERVFAIL, the outcome CAN_NOT_BE_RESOLVED (ERROR) describes for a name with
no address at all. The level follows the fault, not the residual reachability
that glue gives the zone under test.
| Tag | Level | Notes |
|---|---|---|
DS22_NO_IN_DOMAIN_NS | INFO | Default from share/profile.json (test_levels.DNSSEC). |
DS22_NS_ADDRESS_CHAIN_BROKEN | ERROR | Default from share/profile.json (test_levels.DNSSEC). |
DS22_NS_ADDRESS_INSECURE | INFO | Data below an insecure delegation is accepted by validators. |
DS22_NS_ADDRESS_ORPHAN_ZONE | ERROR | Default from share/profile.json (test_levels.DNSSEC). |
DS22_NS_ADDRESS_REFERRED | INFO | The run reached no verdict for the name; it states what was not checked. |
DS22_NS_ADDRESS_RRSIG_EXPIRED | ERROR | Default from share/profile.json (test_levels.DNSSEC). |
DS22_NS_ADDRESS_RRSIG_NOT_VALID_BY_DNSKEY | ERROR | Default from share/profile.json (test_levels.DNSSEC). |
DS22_NS_ADDRESS_UNSIGNED | ERROR | Default from share/profile.json (test_levels.DNSSEC). |
DS22_NS_ADDRESS_VALIDATES | INFO | Default from share/profile.json (test_levels.DNSSEC). |
DS22_ZONE_NOT_SECURE | INFO | Default from share/profile.json (test_levels.DNSSEC). |
IPV4_DISABLED | DEBUG2 | Default from share/profile.json (test_levels.DNSSEC). |
IPV6_DISABLED | DEBUG2 | Default from share/profile.json (test_levels.DNSSEC). |
TEST_CASE_END | DEBUG | Default from share/profile.json (test_levels.DNSSEC). |
TEST_CASE_START | DEBUG | Default from share/profile.json (test_levels.DNSSEC). |
Scoring takes the severity default in the dnssec dimension. No
TagPenalties override is defined.
Differences From Upstream
- Upstream reference: no upstream Zonemaster equivalent. DNSSEC22 is a new testcase unique to gonemaster, and no upstream testcase validates a signature below the apex of the zone under test.
- Potential upstream report:
yes- Upstream expected behavior: an in-domain nameserver name whose address records are bogus under the chain of trust of the zone under test is reported.
- Gonemaster observed behavior: DNSSEC22 reports it; the address records of in-domain nameserver names are otherwise resolved with DO=0 and glue is accepted, in gonemaster as upstream.
- evidence:
engine/test/dnssec/dnssec22_test.go. - report status:
not filed.
Edge Cases And Limitations
- The root zone has an empty name set and emits
DS22_NO_IN_DOMAIN_NSwithout a query. Every name is subordinate to the root, so the in-domain rule alone admits all thirteen root server names. They live inroot-servers.net, an unsigned zone undernet: a root server serves that zone authoritatively but answersroot-servers.net DSwith a referral, so every zone cut walk from a root server endsindeterminateand no finding is possible. - A nameserver that answers a referral serves the parent side of the cut. One
DSquestion there settles every name in the subtree. This is the shape ofde, whose nameserver names live in the delegated zonenic.de, and ofdj, whose names live in the insecurely delegateddjibtelecom.dj. - A nameserver that serves both sides of an insecure delegation answers the
name inside the child and
M DSfrom the parent. Under NSEC3 Opt-Out the parent holds no NSEC3 record for M, and the covering span is the proof. This is the shape ofuk, whose names live innic.ukon the same nameservers. - An
NSname of a referral without glue is not resolved. A cut whoseNSnames all lack glue yieldsDS22_NS_ADDRESS_REFERREDfor every name below it. - The follow is one level deep. A further referral on a nameserver of the
delegated zone is classified by the parent-side status of that cut; a secure
delegation there yields
DS22_NS_ADDRESS_REFERRED. - A nameserver of a delegated zone is asked only for the
DNSKEYof that zone and for the names of the name set at or below it. - An undelegated zone and a correctly delegated zone whose signer omitted the
NS bit from the matching NSEC or NSEC3 record are indistinguishable from the
parent side when one nameserver holds both zones: an
NSquery for the name is answered from the child, never with a parent-side delegation, so the type bitmap is the only statement available about what the parent holds. Both land inDS22_NS_ADDRESS_ORPHAN_ZONE, whose message names the missing NS bit as the evidence. Validators reject the name in both cases. Aclassifies a name andAAAAis queried only when there is noA, so a signature fault confined to theAAAARRset of a name whoseARRset is healthy is not detected. Signers re-sign a zone as a unit, so the failure classes this testcase covers all show onA.AAAAis never queried for a name already at fault: noDS22_*tag carries a per-type argument, so a second observation could reach no emission.- Several nameserver names sharing one IP are evaluated once per name; the
serversargument carries the{ns,address}endpoints. - A NODATA response is evaluated for the signer and the signature validity of the NSEC or NSEC3 records it carries, not for the logical completeness of the denial. DNSSEC23 owns denial completeness.
- Wildcard-synthesised address records need no special handling:
dnssecutil.VerifyRRSIGderives the wildcard owner from the RRSIG label count. - An insecure delegation claimed by an NSEC or NSEC3 record whose RRSIG is
missing or does not verify yields
DS22_NS_ADDRESS_CHAIN_BROKENfor the names below it. Validators treat the unproven denial as bogus. - A
CNAMEat a nameserver name is skipped. RFC 2181 section 10.3 forbids an alias there and Delegation05 reports it; following the alias would validate a name in another zone. - Undelegated runs (
hasFakeAddressesis true) use the fake addresses. The zone cut walk still works, since DS and DNSKEY come from the same fake nameservers. - A signature whose algorithm the local verifier cannot process is indeterminate and yields no finding, at the leaf and in the zone cut walk alike.
- A zone cut whose
DSquestion draws no answer on a nameserver staysindeterminatefor every name below it on that nameserver and yields no finding there. Other nameservers are unaffected. - Running
--testcase dnssec22alone makes the DNSKEY and DS queries of the gate itself; nothing is assumed cached. - A zone whose NSEC3 chain uses more than 50 iterations yields no zone cut
status from its denials: a name that rests on such a denial is
indeterminateand yields no finding. DNSSEC03 reports the iteration count. - An RRSIG past the first 8 over its RRset is not considered, and a DNSKEY past
the first 4 with the key tag and algorithm of an RRSIG is not tried. A zone
whose only valid signature or only verifying key lies past a cut is reported
from what was considered: an RRSIG that no considered key verifies is
brokenin the zone cut walk and yieldsDS22_NS_ADDRESS_RRSIG_NOT_VALID_BY_DNSKEYat a name.
Implementation Notes
Implementation-defined choices, none of them mandated by the protocol:
- Only an
insecurezone cut status verifies the NSEC or NSEC3 records it rests on. The records behindnot a cutandindeterminateare read unverified:not a cutmoves the walk toward the apex keys, and a nameserver that withholds the answer reachesindeterminateas well. DNSSEC10 owns the other NSEC and NSEC3 signature checks. - A denial signed by the zone costs no query to authenticate. One signed by a cut between M and the apex costs the memoized probe of that cut.
- Child nameservers are deduplicated by IP, and one task runs per unique IP.
Ais queried first and settles the name;AAAAfollows only an authoritative NODATA onA.- The referral set and the zone cut memo are per nameserver. The names of one
nameserver are processed in sequence, so no two names share a partial memo
entry.
indeterminateis memoized like every other status. A name below an already referred cut is classified from that memo and costs no query. - The follow runs once per zone cut per run. Its results join the aggregation of step 7 as any nameserver’s do. A delegated zone’s nameservers are built from glue as the zone’s own are built from discovery, so their responses share the per-run query cache.
- No recursion is used. Every address comes from discovery or from glue.
- The zone cut walk is bounded by the labels between the name and the zone apex; no ancestor of the zone under test is derived.
- NSEC3 hashing is bounded at 50 iterations, below the insecure limit
RFC 9276 Appendix A measured, as section 3.2 recommends limits fall over
time. A larger count is not hashed and the testcase logs
LIMIT_REACHEDwithboundnsec3_iterations, once per testcase (DNSSEC Limits ). Hashes are memoized per name, salt and iteration count for one run of the testcase. DS22_NS_ADDRESS_VALIDATESis OK-tag gated: it is emitted only when no ERROR-levelDS22_*tag was emitted.- The reference time for signature validity is
packetTime(resp), the timestamp of the response carrying the signature, as in the other verifying DNSSEC testcases. - The name set is the delegation. The SOA MNAME is not evaluated, although an in-domain MNAME carries the same failure.
- RRSIG verification is bounded: at most 8 RRSIGs over one RRset are considered,
and at most 4 DNSKEYs with the key tag and algorithm of an RRSIG are tried for
it, each in response order. RFC 4035 section 5.3.1 requires trying every
DNSKEY that matches an RRSIG; a key tag is not a unique identifier (RFC 4034
Appendix B), so a zone chooses how many keys match, and the caps depart from
that requirement. A cut logs
LIMIT_REACHEDwithboundrrsigs_per_rrsetorkeys_per_tag, once per testcase (DNSSEC Limits ). Each RRSIG is verified over one copy of the RRset. An RRSIG does not verify when its Labels field exceeds the label count of the RRset owner (RFC 4035 section 5.3.1). It also fails when the owner name rebuilt from that field (RFC 4035 section 5.3.2) is not at or below the Signer’s Name, or is the Signer’s Name but differs from the RRset owner.DS22_NS_ADDRESS_RRSIG_NOT_VALID_BY_DNSKEYcarriesreasonlabelsfor such an RRSIG andsignaturefor any other failure.
Evidence In Gonemaster
- Code paths:
engine/test/dnssec/dnssec.go(DNSSEC22 testcase function and zone cut walker).
- Related tests:
engine/test/dnssec/dnssec22_test.go.
- References:
- RFC 1034 section 4.2 (zone cuts, delegation).
- RFC 2181 section 10.3 (no alias at a nameserver name).
- RFC 4033 section 2 (DNSSEC terms, island of security), RFC 4034 section 4.1.2 (NSEC type bitmap), RFC 4035 sections 5.2 and 5.4 (authenticating a referral and a negative response).
- RFC 5155 (NSEC3, opt-out, proving the absence of a DS).
- RFC 6840 section 4.4 (insecure delegation proofs).
- RFC 9471 section 3.1 (glue for in-domain nameserver names).
- RFC 9499 section 7 (in-domain, sibling domain, zone cut), section 10 (signed zone, insecure delegation) and section 11 (the secure, insecure, bogus and indeterminate validation states).