add system tests covering EDE 9

The authoritative server on "missing-dnskey." zone is ns2, the zone is
initially signed normally, but then the DNSKEY are pulled out from the
signed generated zone file. As a consequence, a quering the resolver ns4
returns a SERVFAIL with EDE9 as the chain of trust is broken: the DS is
prsent in the parent zone (the root zone in ns1), but the DNSKEY is
missing from the zone.

A similar is "wrong-dnskey.", but here the zone is signed correctly,
but the DS points to a different DNSKEY. Hence no supported matching
DNSKEY record could be found for the child.
This commit is contained in:
Colin Vidal 2025-12-03 14:22:43 +01:00
parent a95a049963
commit e856afa3b5
8 changed files with 149 additions and 0 deletions

View file

@ -47,3 +47,9 @@ inconsistent. NS ns2.inconsistent.
ns2.inconsistent. A 10.53.0.2
nsec-rrsigs-stripped. NS ns10.nsec-rrsigs-stripped.
ns10.nsec-rrsigs-stripped. A 10.53.0.10
ns.missing-dnskey. A 10.53.0.2
missing-dnskey. NS ns.missing-dnskey.
ns.missing-ksk. A 10.53.0.2
missing-ksk. NS ns.missing-ksk.
ns.wrong-dnskey. A 10.53.0.2
wrong-dnskey. NS ns.wrong-dnskey.

View file

@ -33,6 +33,9 @@ cp "../ns2/dsset-peer-ns-spoof." .
cp "../ns2/dsset-dnskey-rrsigs-stripped." .
cp "../ns2/dsset-ds-rrsigs-stripped." .
cp "../ns2/dsset-inconsistent." .
cp "../ns2/dsset-missing-dnskey." .
cp "../ns2/dsset-wrong-dnskey." .
cp "../ns2/dsset-missing-ksk." .
grep "$DEFAULT_ALGORITHM_NUMBER [12] " "../ns2/dsset-algroll." >"dsset-algroll."
cp "../ns6/dsset-optout-tld." .

View file

@ -0,0 +1,24 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 300
@ IN SOA mname1. . (
2000042407 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
NS ns
MX 10 mx
ns A 10.53.0.2
a A 10.0.0.1
b A 10.0.0.2

View file

@ -0,0 +1,24 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 300
@ IN SOA mname1. . (
2000042407 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
NS ns
MX 10 mx
ns A 10.53.0.2
a A 10.0.0.1
b A 10.0.0.2

View file

@ -239,4 +239,19 @@ zone "child.ds-rrsigs-stripped" {
file "child.ds-rrsigs-stripped.db.signed";
};
zone "missing-dnskey" {
type primary;
file "missing-dnskey.db.signed";
};
zone "missing-ksk" {
type primary;
file "missing-ksk.db.signed";
};
zone "wrong-dnskey" {
type primary;
file "wrong-dnskey.db.signed";
};
include "trusted.conf";

View file

@ -469,3 +469,40 @@ key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK "$zone")
key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone")
cat "$infile" "$key1.key" "$key2.key" >"$zonefile"
"$SIGNER" -3 - -g -o "$zone" "$zonefile" >/dev/null 2>&1
#
# The DNSKEYs gets removed from the signed zone.
#
zone=missing-dnskey
infile=missing-dnskey.db.in
zonefile=missing-dnskey.db
key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone")
key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK "$zone")
cat "$infile" "$key1.key" "$key2.key" >"$zonefile"
"$SIGNER" -o "$zone" "$zonefile" >/dev/null 2>&1
"$CHECKZONE" -D -q -i local "$zone" "$zonefile.signed" | awk '$4 == "DNSKEY" { next } { print }' >"$zonefile.stripped"
mv "$zonefile.stripped" "$zonefile.signed"
#
# The KSK gets removed from the signed zone, but the ZSK is still there.
# 257 is the flag value indicating the key is the KSK
#
zone=missing-ksk
infile=missing-ksk.db.in
zonefile=missing-ksk.db
key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone")
key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK "$zone")
cat "$infile" "$key1.key" "$key2.key" >"$zonefile"
"$SIGNER" -o "$zone" "$zonefile" >/dev/null 2>&1
"$CHECKZONE" -D -q -i local "$zone" "$zonefile.signed" | awk '$4 == "DNSKEY" && $5 == "257" { next } { print }' >"$zonefile.stripped"
mv "$zonefile.stripped" "$zonefile.signed"
zone=wrong-dnskey
infile=wrong-dnskey.db.in
zonefile=wrong-dnskey.db
key1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone")
key2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK "$zone")
cat "$infile" "$key1.key" "$key2.key" >"$zonefile"
"$SIGNER" -o "$zone" "$zonefile" >/dev/null 2>&1
key3=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK "$zone")
$DSFROMKEY "$key3.key" >"dsset-$zone."

View file

@ -0,0 +1,24 @@
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
;
; SPDX-License-Identifier: MPL-2.0
;
; This Source Code Form is subject to the terms of the Mozilla Public
; License, v. 2.0. If a copy of the MPL was not distributed with this
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
;
; See the COPYRIGHT file distributed with this work for additional
; information regarding copyright ownership.
$TTL 300
@ IN SOA mname1. . (
2000042407 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
NS ns
MX 10 mx
ns A 10.53.0.2
a A 10.0.0.1
b A 10.0.0.2

View file

@ -1109,6 +1109,22 @@ def test_validating_forwarder(ns4, ns9):
watcher.wait_for_line("status: SERVFAIL")
@pytest.mark.parametrize(
"zone",
[
"missing-dnskey",
"wrong-dnskey",
"missing-ksk",
"a.extradsunknownoid.example",
],
)
def test_missing_dnskey(zone, ns4):
msg = isctest.query.create(f"a.{zone}", "A")
res = isctest.query.tcp(msg, ns4.ip)
isctest.check.servfail(res)
isctest.check.ede(res, EDECode.DNSKEY_MISSING)
def test_expired_signatures(ns4):
# check expired signatures do not validate
msg = isctest.query.create("expired.example", "SOA")