DNSSEC07
Status: Final
Purpose
- Determine whether the child zone is signed (based on DNSKEY + covering RRSIG observations) and, for signed zones, whether parent-side DS data is present and consistent.
- Distinguish the two readings of a signed zone with no parent DS: a parent that is silent about the zone, which is an island of security, and a parent that proves under signature that no delegation exists at the name, which every validating resolver rejects.
Preconditions And Inputs
- Preconditions:
- A
zone.Zoneobject is available.
- A
- Required inputs:
- Child nameserver name/IP items from
DelegationNameserversandZoneNameservers. - Parent nameservers from
ParentNameservers(or undelegated fake-DS data path). - SOA, DNSKEY, and DS query responses.
- For the no-delegation verdict only: the
DSRRset of the parent zone at a grandparent nameserver, and the apexDNSKEYRRset of the parent zone.
- 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: parallel child and parent query execution fanout.
Algorithm And Decision Flow
- Emit
TEST_CASE_START. - Build child nameserver set from delegation+zone NS items (grouped by IP).
- For each unique child nameserver IP (parallelized):
- If transport is disabled, emit
IPV4_DISABLEDorIPV6_DISABLEDfor rrtypesSOA,DNSKEY, andDS, then skip. - Query
SOA:- If no response, non-
NOERROR, non-AA, or no SOA answer, classify nameserver as ignored child NS.
- If no response, non-
- Query
DNSKEYwith DNSSEC enabled:- No response ->
No Response DNSKEY. - Non-
AA->No Auth DNSKEY. RCODE != NOERROR->Error RCODE DNSKEY.- Else inspect answer for an
RRSIGcoveringDNSKEY:- If found -> nameserver classified as signed response.
- Else -> nameserver classified as no DNSKEY-signature response.
- No response ->
- If transport is disabled, emit
- Build parent nameserver set.
- Undelegated DS shortcut:
- If parent-zone fake DS records exist for child, set DS-in-response set to
"-"and skip parent DS querying.
- If parent-zone fake DS records exist for child, set DS-in-response set to
- If no signed child response exists, clear parent evaluation sets and skip DS parent checks.
- Otherwise, for each unique parent nameserver IP (parallelized):
- If transport is disabled, emit
IPV4_DISABLEDorIPV6_DISABLEDfor rrtypeDS, then skip. - Query
DSwith DNSSEC enabled. - If response fails required shape (
NOERROR,OPT,DO,AA), classify parent nameserver as ignored. - Else, if answer contains
RRSIGcoveringDSat child owner name, classify as DS present. - Else classify as no DS, and record the parent’s statement about the name
as a delegation, read from the response already in hand:
- The NSEC record whose owner is the zone name, or the NSEC3 record whose
owner matches the hash of the zone name computed with the salt and
iteration count of that record:
- Type bitmap with the NS bit:
delegated. The parent delegates the name and the delegation is insecure. - Type bitmap without the NS bit:
denied. The parent proves no delegation exists at the name.
- Type bitmap with the NS bit:
- No NSEC and no NSEC3 record:
unproven. The parent zone is unsigned, or its denial is incomplete, and states nothing about the name.
- The NSEC record whose owner is the zone name, or the NSEC3 record whose
owner matches the hash of the zone name computed with the salt and
iteration count of that record:
- If transport is disabled, emit
- Emit child-side signing-state tags:
- If the union of ignored/no-response/non-auth/unexpected-rcode child sets equals all child nameservers, emit
DS07_NOT_SIGNED. - Emit detail tags for non-response, non-auth, unexpected-rcode groups.
- Emit
DS07_SIGNED_ON_SERVERfor signed-response set. - Emit
DS07_NOT_SIGNED_ON_SERVERfor no-DNSKEY-signature set. - Emit
DS07_INCONSISTENT_SIGNEDif both signed and not-signed-on-server sets are non-empty. - Emit
DS07_SIGNEDif signed set non-empty and no-DNSKEY-signature set empty. - Emit
DS07_NOT_SIGNEDif signed set empty and no-DNSKEY-signature set non-empty.
- If the union of ignored/no-response/non-auth/unexpected-rcode child sets equals all child nameservers, emit
- Emit parent DS tags:
- Emit
DS07_NO_DS_ON_PARENT_SERVERfor no-DS set, but only when DS-present set is also non-empty (per-server tag fires only for the inconsistent case; when every parent fails to return DS, the aggregateDS07_NO_DS_FOR_SIGNED_ZONEcovers it). - Emit
DS07_DS_ON_PARENT_SERVERfor DS-present set. - Emit
DS07_INCONSISTENT_DSif both no-DS and DS-present sets are non-empty. - If zone is considered signed (
signed responsenon-empty andno DNSKEY-signatureempty):- Emit
DS07_NO_DS_FOR_SIGNED_ZONEwhen no-DS set non-empty and DS-present set empty. - Emit
DS07_DS_FOR_SIGNED_ZONEwhen no-DS set empty and DS-present set non-empty.
- Emit
- Emit
- No-delegation verdict. It is reached only when every condition below holds,
in this order. The first three are read from responses already made, so the
two queries of the fourth are issued only for a zone that is already
inconsistent.
DS07_NO_DS_FOR_SIGNED_ZONEwas emitted: the child is signed and no parent nameserver returned a DS.- At least one parent nameserver recorded
deniedin step 7. - No parent nameserver recorded
delegated. Parent nameservers that disagree are reported byDS07_INCONSISTENT_DSand reach no verdict here. - The parent zone is anchored: query the parent zone’s
DSat a grandparent nameserver and the parent zone’s apexDNSKEYat a parent nameserver, both with DNSSEC enabled. The DS RRset MUST carry an RRSIG, a DNSKEY of the parent MUST match a DS by keytag, algorithm and digest, and the RRSIG covering the NSEC or NSEC3 of step 7 MUST verify under a DNSKEY of the parent. A signature whose algorithm the local verifier cannot process yields no verdict.
- All conditions hold: emit
DS07_PARENT_PROVES_NO_DELEGATIONwithparentand theserversthat proved it.
- Emit
TEST_CASE_END.
Child Signing-State Classification (steps 2-3, 8)
Parent DS and Final Aggregation (steps 4-9)
Emitted Tags (Possible Set)
| Tag | Emitted when |
|---|---|
DS07_DS_FOR_SIGNED_ZONE | Zone is considered signed and parent DS-present set is non-empty while no-DS set is empty. |
DS07_DS_ON_PARENT_SERVER | At least one parent nameserver is classified as DS-present. |
DS07_INCONSISTENT_DS | Both parent DS-present and parent no-DS sets are non-empty. |
DS07_INCONSISTENT_SIGNED | Both child signed-response and child no-DNSKEY-signature sets are non-empty. |
DS07_NON_AUTH_RESPONSE_DNSKEY | Child nameservers returned DNSKEY responses without AA. |
DS07_NOT_SIGNED | Zone is determined not signed by child-evaluation logic. |
DS07_NOT_SIGNED_ON_SERVER | Child nameservers whose DNSKEY response carries no RRSIG covering DNSKEY, either because the DNSKEY RRset is absent or because it is unsigned. |
DS07_NO_DS_ON_PARENT_SERVER | At least one parent nameserver returned no DS-signature evidence and at least one other parent nameserver did - i.e., the parent is inconsistent. Suppressed when every parent fails. |
DS07_NO_DS_FOR_SIGNED_ZONE | Zone is considered signed but no parent DS-present evidence exists. |
DS07_NO_RESPONSE_DNSKEY | Child nameservers did not respond to DNSKEY query. |
DS07_PARENT_PROVES_NO_DELEGATION | The child zone is signed, no parent nameserver has a DS, the NSEC or NSEC3 record matching the zone name in the parent carries no NS bit, and the parent zone is anchored by a DS at its own parent. |
DS07_SIGNED | Zone is determined signed by child-evaluation logic. |
DS07_SIGNED_ON_SERVER | Child nameservers returned DNSKEY-covering RRSIG evidence. |
DS07_UNEXP_RCODE_RESP_DNSKEY | Child nameservers returned unexpected DNSKEY query RCODE. |
IPV4_DISABLED | IPv4 transport is disabled for child/parent queries in this testcase. |
IPV6_DISABLED | IPv6 transport is disabled for child/parent queries in this testcase. |
TEST_CASE_END | Testcase completion marker is emitted. |
TEST_CASE_START | Testcase start marker is emitted. |
Tag Arguments
| Tag | Argument key | Type | Meaning |
|---|---|---|---|
DS07_DS_FOR_SIGNED_ZONE | - | - | No arguments. |
DS07_DS_ON_PARENT_SERVER | servers | array<object> | Structured parent nameserver identities ({ns,address} object) with DS-signature evidence, or - in undelegated fake-DS path. |
DS07_INCONSISTENT_DS | - | - | No arguments. |
DS07_INCONSISTENT_SIGNED | - | - | No arguments. |
DS07_NON_AUTH_RESPONSE_DNSKEY | servers | array<object> | Structured child nameserver identities ({ns,address} object) returning non-AA DNSKEY responses. |
DS07_NOT_SIGNED | - | - | No arguments. |
DS07_NOT_SIGNED_ON_SERVER | servers | array<object> | Structured child nameserver identities ({ns,address} object) whose DNSKEY response carries no RRSIG covering DNSKEY, either because the DNSKEY RRset is absent or because it is unsigned. |
DS07_NO_DS_ON_PARENT_SERVER | servers | array<object> | Structured parent nameserver identities ({ns,address} object) with no DS-signature evidence. |
DS07_NO_DS_FOR_SIGNED_ZONE | - | - | No arguments. |
DS07_NO_RESPONSE_DNSKEY | servers | array<object> | Structured child nameserver identities ({ns,address} object) with no DNSKEY response. |
DS07_PARENT_PROVES_NO_DELEGATION | parent | string | Parent zone whose signed denial proves no delegation exists at the zone name. |
DS07_PARENT_PROVES_NO_DELEGATION | servers | array<object> | Structured parent nameserver identities ({ns,address} object) that returned the denial. |
DS07_SIGNED | - | - | No arguments. |
DS07_SIGNED_ON_SERVER | servers | array<object> | Structured child nameserver identities ({ns,address} object) with DNSKEY-signature evidence. |
DS07_UNEXP_RCODE_RESP_DNSKEY | servers | array<object> | Structured child nameserver identities ({ns,address} object) returning this unexpected RCODE. |
DS07_UNEXP_RCODE_RESP_DNSKEY | rcode | string | DNSKEY response RCODE mnemonic. |
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 | rrtype | string | rrtype skipped (SOA, DNSKEY, or DS). |
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 | rrtype | string | rrtype skipped (SOA, DNSKEY, or DS). |
TEST_CASE_END | testcase | string | Testcase display name (DNSSEC07). |
TEST_CASE_START | testcase | string | Testcase display name (DNSSEC07). |
Severity Levels Per Tag
| Tag | Level | Notes |
|---|---|---|
DS07_DS_FOR_SIGNED_ZONE | INFO | Default from share/profile.json (test_levels.DNSSEC). |
DS07_DS_ON_PARENT_SERVER | INFO | Default from share/profile.json (test_levels.DNSSEC). |
DS07_INCONSISTENT_DS | ERROR | Default from share/profile.json (test_levels.DNSSEC). |
DS07_INCONSISTENT_SIGNED | ERROR | Default from share/profile.json (test_levels.DNSSEC). |
DS07_NON_AUTH_RESPONSE_DNSKEY | WARNING | Default from share/profile.json (test_levels.DNSSEC). |
DS07_NOT_SIGNED | WARNING | Default from share/profile.json (test_levels.DNSSEC). |
DS07_NOT_SIGNED_ON_SERVER | WARNING | Default from share/profile.json (test_levels.DNSSEC). |
DS07_NO_DS_ON_PARENT_SERVER | WARNING | Default from share/profile.json (test_levels.DNSSEC). |
DS07_NO_DS_FOR_SIGNED_ZONE | WARNING | Default from share/profile.json (test_levels.DNSSEC). |
DS07_NO_RESPONSE_DNSKEY | WARNING | Default from share/profile.json (test_levels.DNSSEC). |
DS07_PARENT_PROVES_NO_DELEGATION | ERROR | The zone and every name in it are rejected by validating resolvers. DS07_NO_DS_FOR_SIGNED_ZONE keeps its WARNING and is emitted alongside. |
DS07_SIGNED | INFO | Default from share/profile.json (test_levels.DNSSEC). |
DS07_SIGNED_ON_SERVER | INFO | Default from share/profile.json (test_levels.DNSSEC). |
DS07_UNEXP_RCODE_RESP_DNSKEY | WARNING | 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). |
Differences From Upstream
- Differences (Upstream vs Gonemaster):
- Upstream: summary text states that if no DNSKEY records are found then no messages are output. Gonemaster: emits not-signed findings (
DS07_NOT_SIGNED_ON_SERVER,DS07_NOT_SIGNED) in that case when child responses are otherwise usable. - Upstream: parent DS-positive condition is described as requiring DS plus RRSIG covering DS. Gonemaster: parent DS-positive check is driven by presence of an
RRSIGcoveringDSfor child owner and does not explicitly assert DS RR presence in the same branch. - Upstream: the
DS07_NOT_SIGNED_ON_SERVERmessage states that the servers respond with no DNSKEY. Gonemaster: the message states that the DNSKEY RRset is not signed, because the classification is RRSIG-based and also fires for zones that publish DNSKEYs (DIV-DS11-UNSIGNED-DNSKEY, reported together with dnssec11). - Upstream: does not explicitly specify testcase boundary and per-query transport debug emissions in this testcase summary. Gonemaster: emits
TEST_CASE_START,TEST_CASE_END,IPV4_DISABLED, andIPV6_DISABLED.
- Upstream: summary text states that if no DNSKEY records are found then no messages are output. Gonemaster: emits not-signed findings (
- Potential upstream report:
no
Edge Cases And Limitations
- Ignored parent nameserver outcomes are tracked internally but have no dedicated DS07 output tag.
- Child transport-disabled path logs rrtypes
SOA,DNSKEY, andDS, even though DS is only queried against parent nameservers in this testcase. - Parent DS evaluation is fully skipped when no signed child response is observed.
- A DNSKEY RRset without a covering RRSIG is classified exactly like an absent DNSKEY RRset. The parent-DS consequence of that state is reported by DNSSEC11, which runs before the module short-circuit.
- The anchoring check of step 10 is one level. It proves that the parent zone is anchored by a DS at the grandparent; it does not walk to the root. A grandparent that is itself insecure would make the whole subtree insecure, and no resolver would reject the zone. The verdict is not reached when the grandparent cannot be resolved or its DS query yields no RRSIG.
- A parent that answers
AANXDOMAINfor theDSquery also proves no delegation, but the response shape check of step 7 classifies it as ignored, so no verdict is reached. Basic01 owns a zone name that does not exist at the parent. - An unsigned parent proves nothing about the name. Its
DSNODATA carries no NSEC and no NSEC3, so step 7 recordsunprovenand no verdict is reached. DS07_NO_DS_FOR_SIGNED_ZONEcontinues to fire whenever no parent nameserver has a DS. It says the zone is not anchored; the new tag says why.