mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-23 10:37:43 -04:00
new: usr: Add support for Extended DNS Error 9 (Missing DNSKEY)
Extended DNS Error 9 (Missing DNSKEY) is now sent when a validating resolver attempts to validate a response but can't get the DNSKEY from the authoritative server of the zone, while the DS record is present in the parent zone. See #2715 Merge branch '2715-missingdnskey' into 'main' See merge request isc-projects/bind9!10296
This commit is contained in:
commit
fe456b47f9
11 changed files with 163 additions and 1 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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." .
|
||||
|
|
|
|||
24
bin/tests/system/dnssec/ns2/missing-dnskey.db.in
Normal file
24
bin/tests/system/dnssec/ns2/missing-dnskey.db.in
Normal 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
|
||||
24
bin/tests/system/dnssec/ns2/missing-ksk.db.in
Normal file
24
bin/tests/system/dnssec/ns2/missing-ksk.db.in
Normal 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
|
||||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
|
|
|
|||
24
bin/tests/system/dnssec/ns2/wrong-dnskey.db.in
Normal file
24
bin/tests/system/dnssec/ns2/wrong-dnskey.db.in
Normal 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
|
||||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ zone=example.
|
|||
infile=example.db.in
|
||||
zonefile=example.db
|
||||
|
||||
# The zone is signed but it's broken: instead of having a ZSK and a KSK (which
|
||||
# is the DNSKEY pointed by the parent's DS), it has two ZSKs. As a result,
|
||||
# `example.` validations will always fail, resulting into a SERVFAIL on
|
||||
# validating resolvers.
|
||||
keyname1=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone")
|
||||
keyname2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone")
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,11 @@ def check_sfcache_ede(ns, ede):
|
|||
res = isctest.query.udp(msg, ns.ip)
|
||||
isctest.check.servfail(res)
|
||||
if ede:
|
||||
# The SERVFAIL is cached, so now it shows up the EDE CACHED_ERROR, but not the DNSKEY_MISSING.
|
||||
isctest.check.ede(res, EDECode.CACHED_ERROR)
|
||||
else:
|
||||
isctest.check.noede(res)
|
||||
# example. domain DNSSEC is misconfigured on ns2, as it have two ZSK but no KSK. As a result, the DNSKEY for example. can't be found.
|
||||
isctest.check.ede(res, EDECode.DNSKEY_MISSING)
|
||||
|
||||
|
||||
def test_sfcache_ede(ns5, templates):
|
||||
|
|
|
|||
|
|
@ -2112,6 +2112,8 @@ validate_dnskey_dsset(dns_validator_t *val) {
|
|||
&keyrdata);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
validator_log(val, ISC_LOG_DEBUG(3), "no DNSKEY matching DS");
|
||||
validator_addede(val, DNS_EDE_DNSKEYMISSING,
|
||||
"DNSKEY found but not matching DS");
|
||||
return DNS_R_NOKEYMATCH;
|
||||
}
|
||||
|
||||
|
|
@ -3522,6 +3524,11 @@ proveunsecure(dns_validator_t *val, bool have_ds, bool have_dnskey,
|
|||
/* Couldn't complete insecurity proof. */
|
||||
validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed: %s",
|
||||
isc_result_totext(result));
|
||||
|
||||
if (val->type == dns_rdatatype_dnskey && val->rdataset == NULL) {
|
||||
validator_addede(val, DNS_EDE_DNSKEYMISSING, "no DNSKEY found");
|
||||
}
|
||||
|
||||
return DNS_R_NOTINSECURE;
|
||||
|
||||
out:
|
||||
|
|
|
|||
Loading…
Reference in a new issue