DNSSEC20 (dnssec20)

Status: Draft

Purpose

  • Verify that the NSEC or NSEC3 type bitmap at the zone apex accurately reflects the RR types actually present in the zone. An incomplete (subset) bitmap enables cache poisoning via RFC 8198 aggressive negative caching and replay attacks (see Petr Špaček, ISC, 2021-11-30, “Type Bitmap: Subset - Broken”).

Preconditions And Inputs

  • Preconditions:
    • A zone.Zone object is available.
  • Required inputs:
    • Child nameserver name/IP items from methodsv2.GetDelNSNamesAndIPs and methodsv2.GetZoneNSNamesAndIPs.
    • DNSKEY query response (DNSSEC enabled) to confirm zone is signed. In a full test run, this response is cached from earlier test cases (e.g., DNSSEC10); when running standalone, the query is made directly.
    • NSEC or NSEC3PARAM query response to obtain the apex type bitmap. Also typically cached from DNSSEC10.
    • Query responses for probed RR types: A, AAAA, MX, TXT. Typically cached from earlier test cases (Basic, Zone, Connectivity).
  • Profile/config knobs that affect behavior:
    • net.ipv4 and net.ipv6: disabled transports are skipped with transport debug tags.
    • resolver.defaults.parallel: per-nameserver parallel execution fanout.

Algorithm And Decision Flow

  1. Emit TEST_CASE_START.
  2. Build nameserver set from delegation+zone NS items, grouped 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 child apex DNSKEY with DNSSEC enabled.
    • If response is absent, non-NOERROR, or non-AA, classify nameserver as no_dnssec and skip.
    • If no apex DNSKEY records are present, classify nameserver as no_dnssec and skip.
    • Query NSEC (DNSSEC enabled) to obtain the apex type bitmap:
      • If NSEC record for the apex is present in the answer section, extract its type bitmap (NSEC zone).
      • Else if NSEC3 record matching the apex hash is present in the authority section, extract its type bitmap (NSEC3 zone).
    • If no bitmap obtained from the NSEC query, try NSEC3PARAM query and look for an NSEC record in the authority section (NODATA response).
    • If no bitmap could be obtained, classify nameserver as no_bitmap and skip.
    • For each probed type (A, AAAA, MX, TXT):
      • Query the apex for that type with DNSSEC enabled.
      • If the response is NOERROR with at least one matching RR for the apex name in the answer section, the type exists.
      • If the type exists but is NOT present in the type bitmap, record a bitmap mismatch for that type.
  4. Aggregate results across nameservers:
    • For each probed type with mismatches, emit DS20_NSEC_BITMAP_MISMATCHES_RRTYPE (NSEC zones) or DS20_NSEC3_BITMAP_MISMATCHES_RRTYPE (NSEC3 zones) with merged servers.
    • If all nameservers with DNSSEC show correct bitmaps, emit DS20_BITMAP_OK.
    • If nameservers had DNSSEC but no bitmap could be obtained, emit DS20_NO_BITMAP.
    • If no nameserver had DNSSEC (and no other findings), emit DS20_NO_DNSSEC.
  5. Emit TEST_CASE_END.

Emitted Tags (Possible Set)

TagEmitted when
DS20_BITMAP_OKAll probed types present in the zone are correctly represented in the NSEC/NSEC3 type bitmap on all responding nameservers.
DS20_NO_BITMAPNameserver has DNSKEY but no NSEC/NSEC3 bitmap could be obtained for the apex.
DS20_NO_DNSSECNo nameserver returned a usable DNSKEY; bitmap check skipped.
DS20_NSEC3_BITMAP_MISMATCHES_RRTYPEAn existing RR type at the apex is missing from the NSEC3 type bitmap. Enables cache poisoning via RFC 8198.
DS20_NSEC_BITMAP_MISMATCHES_RRTYPEAn existing RR type at the apex is missing from the NSEC type bitmap. Enables cache poisoning via RFC 8198.
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
DS20_BITMAP_OKserversarray<object>Structured nameserver identities ({ns,address} object) with correct bitmaps.
DS20_NO_BITMAPserversarray<object>Structured nameserver identities ({ns,address} object) where no bitmap was obtained.
DS20_NO_DNSSECserversarray<object>Structured nameserver identities ({ns,address} object) without DNSKEY.
DS20_NSEC3_BITMAP_MISMATCHES_RRTYPEquery_typestringRR type name missing from the NSEC3 bitmap (e.g., A, AAAA).
DS20_NSEC3_BITMAP_MISMATCHES_RRTYPEserversarray<object>Structured nameserver identities ({ns,address} object) exhibiting the mismatch.
DS20_NSEC_BITMAP_MISMATCHES_RRTYPEquery_typestringRR type name missing from the NSEC bitmap (e.g., A, AAAA).
DS20_NSEC_BITMAP_MISMATCHES_RRTYPEserversarray<object>Structured nameserver identities ({ns,address} object) exhibiting the mismatch.
IPV4_DISABLEDnsstringNameserver identity (ns name only; use address for IP) skipped on IPv4.
IPV4_DISABLEDaddressstringNameserver IP address for the same endpoint.
IPV4_DISABLEDquery_typestringrrtype skipped (DNSKEY).
IPV6_DISABLEDnsstringNameserver identity (ns name only; use address for IP) skipped on IPv6.
IPV6_DISABLEDaddressstringNameserver IP address for the same endpoint.
IPV6_DISABLEDquery_typestringrrtype skipped (DNSKEY).
TEST_CASE_ENDtestcasestringTestcase display name (DNSSEC20).
TEST_CASE_STARTtestcasestringTestcase display name (DNSSEC20).

Severity Levels Per Tag

TagLevelNotes
DS20_BITMAP_OKINFODefault from share/profile.json (test_levels.DNSSEC).
DS20_NO_BITMAPWARNINGDefault from share/profile.json (test_levels.DNSSEC).
DS20_NO_DNSSECNOTICEDefault from share/profile.json (test_levels.DNSSEC).
DS20_NSEC3_BITMAP_MISMATCHES_RRTYPEERRORDefault from share/profile.json (test_levels.DNSSEC).
DS20_NSEC_BITMAP_MISMATCHES_RRTYPEERRORDefault 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: No upstream Zonemaster equivalent. DNSSEC20 is a new testcase unique to Gonemaster.
  • Differences (Upstream vs Gonemaster):
    • Upstream: no testcase verifies NSEC/NSEC3 type bitmap accuracy against actual RR types present. DNSSEC10 checks structural correctness of the bitmap (mandatory/forbidden types) but not completeness against observed data. Gonemaster: implements dynamic bitmap accuracy verification by probing common apex RR types and comparing against the bitmap.
  • Potential upstream report:
    • no

Edge Cases And Limitations

  • Nameserver evaluation is deduplicated by IP; multiple names mapped to one IP are merged into one query outcome and expanded in servers.
  • Nameservers with non-NOERROR or non-AA DNSKEY responses are treated as no_dnssec and can only contribute to DS20_NO_DNSSEC.
  • The set of probed types (A, AAAA, MX, TXT) is intentionally limited to common apex types. DNSKEY, SOA, NS, RRSIG, and NSEC/NSEC3 are already validated structurally by DNSSEC10 and are not re-checked here.
  • Super-set bitmaps (types listed in the bitmap but not actually present) are not flagged - only subset bitmaps (existing types missing from the bitmap) are checked, as these are the security-relevant case per the ISC presentation.
  • For NSEC3 zones, the NSEC3 record must have an owner hash matching the apex for the bitmap to be used; non-matching NSEC3 records are ignored.
  • All queries in DNSSEC20 benefit from the per-nameserver query cache. In a full test run (after DNSSEC10, Basic, Zone, etc.), most queries are cache hits with zero network overhead.

Evidence In Gonemaster

  • Code paths:
    • engine/test/dnssec/dnssec.go (DNSSEC20 testcase function)
  • Related tests:
    • engine/test/dnssec/dnssec_test.go (TestDNSSEC20BitmapOK, TestDNSSEC20NSECSubsetBitmap, TestDNSSEC20NSEC3SubsetBitmap, TestDNSSEC20NoDNSSEC)
  • References:
    • RFC 4034 (NSEC type bitmap format)
    • RFC 5155 (NSEC3 type bitmap format)
    • RFC 8198 (Aggressive Use of DNSSEC-Validated Cache)
    • Petr Špaček, “NSEC* type bitmap discrepancies”, OARC 35, 2021-11-30