DNSSEC09 (dnssec09)

Status: Final

Purpose

  • Verify that SOA responses are signed and that SOA RRSIG records are time-valid, algorithm-supported, and cryptographically matched by DNSKEY records from the same nameserver.

Preconditions And Inputs

  • Preconditions:
    • A zone.Zone object is available.
  • Required inputs:
    • Child nameserver sets from methods.Method4 and methods.Method5.
    • DNSKEY and SOA responses with DNSSEC enabled from child nameservers.
  • Profile/config knobs that affect behavior:
    • net.ipv4 and net.ipv6: disabled transports are skipped with transport debug tags.
    • resolver.defaults.parallel: parallel nameserver execution fanout.

Algorithm And Decision Flow

  1. Emit TEST_CASE_START.
  2. Build nameserver set from Method4+Method5 and deduplicate by IP.
  3. For each unique nameserver IP (parallelized):
    • If transport is disabled, emit IPV4_DISABLED or IPV6_DISABLED for rrtype DNSKEY and skip.
    • Query DNSKEY at child apex with DNSSEC enabled.
    • Skip nameserver if response is absent, non-NOERROR, non-AA, or has no apex DNSKEY records.
    • Query SOA at child apex with DNSSEC enabled over UDP (UseVC=false).
    • Skip nameserver if response is absent, non-NOERROR, non-AA, or has no apex SOA records.
    • If answer section has no RRSIG, mark nameserver for DS09_MISSING_RRSIG_IN_RESPONSE.
    • Else, for each answer-section RRSIG:
      • If inception is after test time, mark DS09_SOA_RRSIG_NOT_YET_VALID by keytag.
      • Else if expiration is before test time, mark DS09_SOA_RRSIG_EXPIRED by keytag.
      • Else if algorithm is unsupported, mark DS09_ALGO_NOT_SUPPORTED_BY_ZM by keytag+algo.
      • Else find matching DNSKEY records by keytag:
        • If none found, mark DS09_NO_MATCHING_DNSKEY.
        • Else verify signature over SOA RRset; if no candidate validates, mark DS09_RRSIG_NOT_VALID_BY_DNSKEY.
  4. Emit accumulated DS09 findings grouped by keytag/algo as applicable.
  5. Collect nameserver IPs that had RRSIGs and emitted no DS09 failure; if non-empty emit DS09_SOA_RRSIG_VALID.
  6. Emit TEST_CASE_END.

Emitted Tags (Possible Set)

TagEmitted when
DS09_ALGO_NOT_SUPPORTED_BY_ZMRRSIG verification requires an unsupported algorithm.
DS09_SOA_RRSIG_VALIDAt least one nameserver returned SOA with RRSIG and all RRSIG checks passed.
DS09_MISSING_RRSIG_IN_RESPONSESOA response has no answer-section RRSIG records.
DS09_NO_MATCHING_DNSKEYRRSIG keytag has no matching DNSKEY keytag.
DS09_RRSIG_NOT_VALID_BY_DNSKEYMatching DNSKEY candidates exist but none verify the SOA signature.
DS09_SOA_RRSIG_EXPIREDSOA-related RRSIG expiration is before test time.
DS09_SOA_RRSIG_NOT_YET_VALIDSOA-related RRSIG inception is after test time.
IPV4_DISABLEDIPv4 transport is disabled for a queried nameserver (DNSKEY).
IPV6_DISABLEDIPv6 transport is disabled for a queried nameserver (DNSKEY).
TEST_CASE_ENDTestcase completion marker is emitted.
TEST_CASE_STARTTestcase start marker is emitted.

Tag Arguments

TagArgument keyTypeMeaning
DS09_ALGO_NOT_SUPPORTED_BY_ZMkeytagintRRSIG keytag associated with unsupported algorithm.
DS09_ALGO_NOT_SUPPORTED_BY_ZMalgo_numintUnsupported DNSSEC algorithm number.
DS09_ALGO_NOT_SUPPORTED_BY_ZMalgo_mnemostringUnsupported DNSSEC algorithm mnemonic.
DS09_ALGO_NOT_SUPPORTED_BY_ZMaddressesarray<string>Structured child nameserver IP list.
DS09_MISSING_RRSIG_IN_RESPONSEaddressesarray<string>Structured child nameserver IP list lacking SOA RRSIG.
DS09_NO_MATCHING_DNSKEYkeytagintRRSIG keytag with no matching DNSKEY keytag.
DS09_NO_MATCHING_DNSKEYaddressesarray<string>Structured child nameserver IP list.
DS09_RRSIG_NOT_VALID_BY_DNSKEYkeytagintRRSIG keytag that failed DNSKEY verification.
DS09_RRSIG_NOT_VALID_BY_DNSKEYaddressesarray<string>Structured child nameserver IP list.
DS09_SOA_RRSIG_EXPIREDkeytagintRRSIG keytag with expired validity window.
DS09_SOA_RRSIG_EXPIREDaddressesarray<string>Structured child nameserver IP list.
DS09_SOA_RRSIG_NOT_YET_VALIDkeytagintRRSIG keytag with not-yet-valid validity window.
DS09_SOA_RRSIG_NOT_YET_VALIDaddressesarray<string>Structured child nameserver IP list.
DS09_SOA_RRSIG_VALIDaddressesarray<string>Structured child nameserver IP list where all SOA RRSIG checks passed.
IPV4_DISABLEDnsstringNameserver identity (ns name only; use address for IP) skipped on IPv4.
IPV4_DISABLEDaddressstringNameserver IP address for the same endpoint.
IPV4_DISABLEDrrtypestringrrtype skipped (DNSKEY).
IPV6_DISABLEDnsstringNameserver identity (ns name only; use address for IP) skipped on IPv6.
IPV6_DISABLEDaddressstringNameserver IP address for the same endpoint.
IPV6_DISABLEDrrtypestringrrtype skipped (DNSKEY).
TEST_CASE_ENDtestcasestringTestcase display name (DNSSEC09).
TEST_CASE_STARTtestcasestringTestcase display name (DNSSEC09).

Severity Levels Per Tag

TagLevelNotes
DS09_ALGO_NOT_SUPPORTED_BY_ZMNOTICEDefault from share/profile.json (test_levels.DNSSEC).
DS09_MISSING_RRSIG_IN_RESPONSEERRORDefault from share/profile.json (test_levels.DNSSEC).
DS09_NO_MATCHING_DNSKEYERRORDefault from share/profile.json (test_levels.DNSSEC).
DS09_RRSIG_NOT_VALID_BY_DNSKEYERRORDefault from share/profile.json (test_levels.DNSSEC).
DS09_SOA_RRSIG_EXPIREDERRORDefault from share/profile.json (test_levels.DNSSEC).
DS09_SOA_RRSIG_NOT_YET_VALIDERRORDefault from share/profile.json (test_levels.DNSSEC).
DS09_SOA_RRSIG_VALIDINFODefault from share/profile.json (test_levels.DNSSEC).
IPV4_DISABLEDDEBUGDefault from share/profile.json (test_levels.DNSSEC).
IPV6_DISABLEDDEBUGDefault from share/profile.json (test_levels.DNSSEC).
TEST_CASE_ENDDEBUGDefault from share/profile.json (test_levels.DNSSEC).
TEST_CASE_STARTDEBUGDefault from share/profile.json (test_levels.DNSSEC).

Differences From Upstream

  • Upstream reference: dnssec09.md
  • Differences (Upstream vs Gonemaster):
    • Upstream: procedure text describes evaluating SOA RRSIG records. Gonemaster: iterates all answer-section RRSIG records and does not explicitly filter by TypeCovered == SOA before DS09 classification.
    • Upstream: describes validity checks against test execution time. Gonemaster: uses the DNSKEY response packet timestamp (packetTime(dnskeyResp)) as the reference time.
    • 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, and IPV6_DISABLED.
  • Potential upstream report:
    • no

Edge Cases And Limitations

  • Nameserver evaluation is deduplicated by IP; repeated names on one IP share one DS09 outcome.
  • Nameservers failing response-shape checks (Msg, NOERROR, AA, apex owner match) are skipped for DS09 findings.
  • If no usable DNSKEY records are found for a nameserver, SOA signing checks are skipped for that nameserver.