From 1d45ad8f39dcd66f7e664e5d05d4ac553fdcbc0b Mon Sep 17 00:00:00 2001 From: Matthijs Mekking Date: Tue, 15 Jan 2019 11:32:53 +0100 Subject: [PATCH] Ignore trust anchors using disabled algorithm More specifically: ignore configured trusted and managed keys that match a disabled algorithm. The behavioral change is that associated responses no longer SERVFAIL, but return insecure. --- bin/named/server.c | 19 ++- bin/tests/system/dnssec/README | 3 + bin/tests/system/dnssec/clean.sh | 4 +- bin/tests/system/dnssec/ns1/root.db.in | 18 +- bin/tests/system/dnssec/ns1/sign.sh | 2 + bin/tests/system/dnssec/ns2/key.db.in | 40 +++++ bin/tests/system/dnssec/ns2/named.conf.in | 10 ++ bin/tests/system/dnssec/ns2/sign.sh | 45 ++++- bin/tests/system/dnssec/ns3/key.db.in | 24 +++ bin/tests/system/dnssec/ns3/named.conf.in | 40 +++++ bin/tests/system/dnssec/ns3/sign.sh | 67 +++++++- bin/tests/system/dnssec/ns5/sign.sh | 2 + bin/tests/system/dnssec/ns6/sign.sh | 2 + bin/tests/system/dnssec/ns7/sign.sh | 2 + bin/tests/system/dnssec/ns8/named.conf.in | 46 +++++ bin/tests/system/dnssec/setup.sh | 1 + bin/tests/system/dnssec/tests.sh | 197 ++++++++++++++++++++-- doc/arm/Bv9ARM-book.xml | 6 + 18 files changed, 495 insertions(+), 33 deletions(-) create mode 100644 bin/tests/system/dnssec/ns2/key.db.in create mode 100644 bin/tests/system/dnssec/ns3/key.db.in create mode 100644 bin/tests/system/dnssec/ns8/named.conf.in diff --git a/bin/named/server.c b/bin/named/server.c index 6857416a4d..5c46598bc4 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -700,8 +700,9 @@ configure_view_nametable(const cfg_obj_t *vconfig, const cfg_obj_t *config, } static isc_result_t -dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key, - bool managed, dst_key_t **target, isc_mem_t *mctx) +dstkey_fromconfig(dns_view_t *view, const cfg_obj_t *vconfig, + const cfg_obj_t *key, bool managed, dst_key_t **target, + isc_mem_t *mctx) { dns_rdataclass_t viewclass; dns_rdata_dnskey_t keystruct; @@ -793,6 +794,14 @@ dstkey_fromconfig(const cfg_obj_t *vconfig, const cfg_obj_t *key, CHECK(dst_key_fromdns(keyname, viewclass, &rrdatabuf, mctx, &dstkey)); + if (!dns_resolver_algorithm_supported(view->resolver, keyname, alg)) { + cfg_obj_log(key, named_g_lctx, ISC_LOG_WARNING, + "%s key for '%s': algorithm is disabled", + managed ? "managed" : "trusted", keynamestr); + result = DST_R_UNSUPPORTEDALG; + goto cleanup; + } + *target = dstkey; return (ISC_R_SUCCESS); @@ -850,9 +859,9 @@ load_view_keys(const cfg_obj_t *keys, const cfg_obj_t *vconfig, elt2 = cfg_list_next(elt2)) { key = cfg_listelt_value(elt2); - result = dstkey_fromconfig(vconfig, key, managed, + result = dstkey_fromconfig(view, vconfig, key, managed, &dstkey, mctx); - if (result == DST_R_UNSUPPORTEDALG) { + if (result == DST_R_UNSUPPORTEDALG) { result = ISC_R_SUCCESS; continue; } @@ -10584,7 +10593,7 @@ add_zone_tolist(dns_zone_t *zone, void *uap) { struct zonelistentry *zle; zle = isc_mem_get(dctx->mctx, sizeof *zle); - if (zle == NULL) + if (zle == NULL) return (ISC_R_NOMEMORY); zle->zone = NULL; dns_zone_attach(zone, &zle->zone); diff --git a/bin/tests/system/dnssec/README b/bin/tests/system/dnssec/README index c45bd71f23..df83eb14e2 100644 --- a/bin/tests/system/dnssec/README +++ b/bin/tests/system/dnssec/README @@ -17,3 +17,6 @@ key for the root. It is used for testing failure cases. ns6 is a caching-only server configured to use DLV. ns7 is used for checking non-cacheable answers. + +ns8 is a caching-only server, configured with unsupported and disabled +algorithms. It is used for testing failure cases. diff --git a/bin/tests/system/dnssec/clean.sh b/bin/tests/system/dnssec/clean.sh index b561b0c2cd..2010bada16 100644 --- a/bin/tests/system/dnssec/clean.sh +++ b/bin/tests/system/dnssec/clean.sh @@ -33,7 +33,7 @@ rm -f ./ns*/*.nta rm -f ./ns*/managed-keys.bind* ./ns*/*.mkeys* rm -f ./ns*/named.lock rm -f ./ns1/managed.key.id -rm -f ./ns1/root.db ./ns2/example.db ./ns3/secure.example.db +rm -f ./ns1/root.db ./ns2/example.db ./ns2/managed.db ./ns2/trusted.db rm -f ./ns2/algroll.db rm -f ./ns2/badparam.db ./ns2/badparam.db.bad rm -f ./ns2/cdnskey-kskonly.secure.db @@ -49,6 +49,8 @@ rm -f ./ns2/in-addr.arpa.db rm -f ./ns2/nsec3chain-test.db rm -f ./ns2/private.secure.example.db rm -f ./ns2/single-nsec3.db +rm -f ./ns3/secure.example.db ./ns3/*.managed.db ./ns3/*.trusted.db +rm -f ./ns3/unsupported.managed.db.tmp ./ns3/unsupported.trusted.db.tmp rm -f ./ns3/auto-nsec.example.db ./ns3/auto-nsec3.example.db rm -f ./ns3/badds.example.db rm -f ./ns3/dname-at-apex-nsec3.example.db diff --git a/bin/tests/system/dnssec/ns1/root.db.in b/bin/tests/system/dnssec/ns1/root.db.in index 5ad5d9ef1d..7fdbab9c4e 100644 --- a/bin/tests/system/dnssec/ns1/root.db.in +++ b/bin/tests/system/dnssec/ns1/root.db.in @@ -8,12 +8,12 @@ ; information regarding copyright ownership. $TTL 300 -. IN SOA gson.nominum.com. a.root.servers.nil. ( - 2000042100 ; serial - 600 ; refresh - 600 ; retry - 1200 ; expire - 600 ; minimum +. IN SOA gson.nominum.com. a.root.servers.nil. ( + 2000042100 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum ) . NS a.root-servers.nil. a.root-servers.nil. A 10.53.0.1 @@ -22,8 +22,12 @@ example. NS ns2.example. ns2.example. A 10.53.0.2 dlv. NS ns2.dlv. ns2.dlv. A 10.53.0.2 -algroll NS ns2.algroll +algroll. NS ns2.algroll. ns2.algroll. A 10.53.0.2 +managed. NS ns2.managed. +ns2.managed. A 10.53.0.2 +trusted. NS ns2.trusted. +ns2.trusted. A 10.53.0.2 optout-tld NS ns6.optout-tld. ns6.optout-tld. A 10.53.0.6 in-addr.arpa. NS ns2.example. diff --git a/bin/tests/system/dnssec/ns1/sign.sh b/bin/tests/system/dnssec/ns1/sign.sh index 313b03c1de..4df96bf1e0 100644 --- a/bin/tests/system/dnssec/ns1/sign.sh +++ b/bin/tests/system/dnssec/ns1/sign.sh @@ -22,6 +22,8 @@ zonefile=root.db (cd ../ns6 && $SHELL sign.sh ) (cd ../ns7 && $SHELL sign.sh ) +echo_i "ns1/sign.sh" + cp "../ns2/dsset-example$TP" . cp "../ns2/dsset-dlv$TP" . cp "../ns2/dsset-in-addr.arpa$TP" . diff --git a/bin/tests/system/dnssec/ns2/key.db.in b/bin/tests/system/dnssec/ns2/key.db.in new file mode 100644 index 0000000000..60be0cf4c1 --- /dev/null +++ b/bin/tests/system/dnssec/ns2/key.db.in @@ -0,0 +1,40 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; 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 http://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 300 ; 5 minutes +@ IN SOA mname1. . ( + 2000042407 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + NS ns2 +ns2 A 10.53.0.2 + +a A 10.0.0.1 +b A 10.0.0.2 +d A 10.0.0.4 + +; A secure subdomain +secure NS ns3.secure +ns3.secure A 10.53.0.3 + +; A subdomain that is signed with an unsupported algorithm +unsupported NS ns3.unsupported +ns3.unsupported A 10.53.0.3 + +; A secure subdomain with a disabled algorithm +disabled NS ns3.disabled +ns3.disabled A 10.53.0.3 + +; A secure subdomain with a disabled algorithm, but not in bailiwick +enabled NS ns3.enabled +ns3.enabled A 10.53.0.3 + diff --git a/bin/tests/system/dnssec/ns2/named.conf.in b/bin/tests/system/dnssec/ns2/named.conf.in index 558eaecf49..189e275014 100644 --- a/bin/tests/system/dnssec/ns2/named.conf.in +++ b/bin/tests/system/dnssec/ns2/named.conf.in @@ -36,6 +36,16 @@ zone "dlv" { file "dlv.db.signed"; }; +zone "trusted" { + type master; + file "trusted.db.signed"; +}; + +zone "managed" { + type master; + file "managed.db.signed"; +}; + zone "example" { type master; file "example.db.signed"; diff --git a/bin/tests/system/dnssec/ns2/sign.sh b/bin/tests/system/dnssec/ns2/sign.sh index 8b9b20af0a..d0a978b61c 100644 --- a/bin/tests/system/dnssec/ns2/sign.sh +++ b/bin/tests/system/dnssec/ns2/sign.sh @@ -14,24 +14,59 @@ set -e +# Sign child zones (served by ns3). +( cd ../ns3 && $SHELL sign.sh ) + +echo_i "ns2/sign.sh" + +# Get the DS records for the "trusted." and "managed." zones. +for subdomain in secure unsupported disabled enabled +do + cp "../ns3/dsset-$subdomain.managed$TP" . + cp "../ns3/dsset-$subdomain.trusted$TP" . +done + +# Sign the "trusted." and "managed." zones. +zone=managed. +infile=key.db.in +zonefile=managed.db + +keyname1=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone -f KSK "$zone") +keyname2=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone "$zone") + +cat "$infile" "$keyname1.key" "$keyname2.key" > "$zonefile" + +"$SIGNER" -P -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 + +zone=trusted. +infile=key.db.in +zonefile=trusted.db + +keyname1=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone -f KSK "$zone") +keyname2=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone "$zone") + +cat "$infile" "$keyname1.key" "$keyname2.key" > "$zonefile" + +"$SIGNER" -P -g -o "$zone" -k "$keyname1" "$zonefile" "$keyname2" > /dev/null 2>&1 + +# The "example." zone. zone=example. infile=example.db.in zonefile=example.db -# Have the child generate a zone key and pass it to us. - -( cd ../ns3 && $SHELL sign.sh ) - +# Get the DS records for the "example." zone. for subdomain in secure badds bogus dynamic keyless nsec3 optout \ nsec3-unknown optout-unknown multiple rsasha256 rsasha512 \ kskonly update-nsec3 auto-nsec auto-nsec3 secure.below-cname \ ttlpatch split-dnssec split-smart expired expiring upper lower \ - dnskey-unknown dnskey-nsec3-unknown managed-future revkey \ + dnskey-unknown dnskey-unsupported dnskey-unsupported-2 \ + dnskey-nsec3-unknown managed-future revkey \ dname-at-apex-nsec3 occluded do cp "../ns3/dsset-$subdomain.example$TP" . done +# Sign the "example." zone. keyname1=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone -f KSK "$zone") keyname2=$("$KEYGEN" -q -a "$ALTERNATIVE_ALGORITHM" -b "$ALTERNATIVE_BITS" -n zone "$zone") diff --git a/bin/tests/system/dnssec/ns3/key.db.in b/bin/tests/system/dnssec/ns3/key.db.in new file mode 100644 index 0000000000..3847e2ea10 --- /dev/null +++ b/bin/tests/system/dnssec/ns3/key.db.in @@ -0,0 +1,24 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; 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 http://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 300 ; 5 minutes +@ IN SOA mname1. . ( + 2000042407 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + NS ns3 +ns3 A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff --git a/bin/tests/system/dnssec/ns3/named.conf.in b/bin/tests/system/dnssec/ns3/named.conf.in index 18268d7975..e33ee52146 100644 --- a/bin/tests/system/dnssec/ns3/named.conf.in +++ b/bin/tests/system/dnssec/ns3/named.conf.in @@ -313,6 +313,46 @@ zone "occluded.example" { file "occluded.example.db.signed"; }; +zone "secure.managed" { + type master; + file "secure.managed.db.signed"; +}; + +zone "disabled.managed" { + type master; + file "disabled.managed.db.signed"; +}; + +zone "enabled.managed" { + type master; + file "enabled.managed.db.signed"; +}; + +zone "unsupported.managed" { + type master; + file "unsupported.managed.db.signed"; +}; + +zone "secure.trusted" { + type master; + file "secure.trusted.db.signed"; +}; + +zone "disabled.trusted" { + type master; + file "disabled.trusted.db.signed"; +}; + +zone "enabled.trusted" { + type master; + file "enabled.trusted.db.signed"; +}; + +zone "unsupported.trusted" { + type master; + file "unsupported.trusted.db.signed"; +}; + include "siginterval.conf"; include "trusted.conf"; diff --git a/bin/tests/system/dnssec/ns3/sign.sh b/bin/tests/system/dnssec/ns3/sign.sh index 055cd9444d..a9a063e0ef 100644 --- a/bin/tests/system/dnssec/ns3/sign.sh +++ b/bin/tests/system/dnssec/ns3/sign.sh @@ -14,6 +14,68 @@ set -e +echo_i "ns3/sign.sh" + +infile=key.db.in +for tld in managed trusted +do + # A secure zone to test. + zone=secure.${tld} + zonefile=${zone}.db + + keyname1=$("$KEYGEN" -f KSK -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") + cat "$infile" "$keyname1.key" > "$zonefile" + "$SIGNER" -z -P -3 - -o "$zone" -O full -f ${zonefile}.signed "$zonefile" > /dev/null 2>&1 + + # Zone to test trust anchor that matches disabled algorithm. + zone=disabled.${tld} + zonefile=${zone}.db + + keyname2=$("$KEYGEN" -f KSK -q -a "$DISABLED_ALGORITHM" -b "$DISABLED_BITS" -n zone "$zone") + cat "$infile" "$keyname2.key" > "$zonefile" + "$SIGNER" -z -P -3 - -o "$zone" -O full -f ${zonefile}.signed "$zonefile" > /dev/null 2>&1 + + # Zone to test trust anchor that has disabled algorithm for other domain. + zone=enabled.${tld} + zonefile=${zone}.db + + keyname3=$("$KEYGEN" -f KSK -q -a "$DISABLED_ALGORITHM" -b "$DISABLED_BITS" -n zone "$zone") + cat "$infile" "$keyname3.key" > "$zonefile" + "$SIGNER" -z -P -3 - -o "$zone" -O full -f ${zonefile}.signed "$zonefile" > /dev/null 2>&1 + + # Zone to test trust anchor with unsupported algorithm. + zone=unsupported.${tld} + zonefile=${zone}.db + + keyname4=$("$KEYGEN" -f KSK -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") + cat "$infile" "$keyname4.key" > "$zonefile" + "$SIGNER" -z -P -3 - -o "$zone" -O full -f ${zonefile}.tmp "$zonefile" > /dev/null 2>&1 + awk '$4 == "DNSKEY" { $7 = 255 } $4 == "RRSIG" { $6 = 255 } { print }' ${zonefile}.tmp > ${zonefile}.signed + + # Make trusted-keys and managed keys conf sections for ns8. + mv ${keyname4}.key ${keyname4}.tmp + awk '$1 == "unsupported.'"${tld}"'." { $6 = 255 } { print }' ${keyname4}.tmp > ${keyname4}.key + + # Zone to test trust anchor that is revoked. + zone=revoked.${tld} + zonefile=${zone}.db + + keyname5=$("$KEYGEN" -f KSK -f REVOKE -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") + cat "$infile" "$keyname5.key" > "$zonefile" + "$SIGNER" -z -P -3 - -o "$zone" -O full -f ${zonefile}.signed "$zonefile" > /dev/null 2>&1 + + case $tld in + "managed") + keyfile_to_managed_keys $keyname1 $keyname2 $keyname3 $keyname4 $keyname5 > ../ns8/managed.conf + ;; + "trusted") + keyfile_to_trusted_keys $keyname1 $keyname2 $keyname3 $keyname4 $keyname5 > ../ns8/trusted.conf + ;; + esac +done + +echo_i "ns3/sign.sh: example zones" + zone=secure.example. infile=secure.example.db.in zonefile=secure.example.db @@ -209,7 +271,7 @@ cat "$infile" "$keyname.key" > "$zonefile" "$SIGNER" -P -3 - -o "$zone" -O full -f ${zonefile}.tmp "$zonefile" > /dev/null 2>&1 -awk '$4 == "DNSKEY" { $7 = 100; print } $4 == "RRSIG" { $6 = 100; print } { print }' ${zonefile}.tmp > ${zonefile}.signed +awk '$4 == "DNSKEY" { $7 = 100 } $4 == "RRSIG" { $6 = 100 } { print }' ${zonefile}.tmp > ${zonefile}.signed DSFILE="dsset-$(echo ${zone} |sed -e "s/\\.$//g")$TP" $DSFROMKEY -A -f ${zonefile}.signed "$zone" > "$DSFILE" @@ -228,7 +290,7 @@ cat "$infile" "$keyname.key" > "$zonefile" "$SIGNER" -P -3 - -o "$zone" -O full -f ${zonefile}.tmp "$zonefile" > /dev/null 2>&1 -awk '$4 == "DNSKEY" { $7 = 255; print } $4 == "RRSIG" { $6 = 255; print } { print }' ${zonefile}.tmp > ${zonefile}.signed +awk '$4 == "DNSKEY" { $7 = 255 } $4 == "RRSIG" { $6 = 255 } { print }' ${zonefile}.tmp > ${zonefile}.signed DSFILE="dsset-$(echo ${zone} |sed -e "s/\\.$//g")$TP" $DSFROMKEY -A -f ${zonefile}.signed "$zone" > "$DSFILE" @@ -246,7 +308,6 @@ zsk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") cat "$infile" "$ksk.key" "$zsk.key" unsupported-algorithm.key > "$zonefile" -# "$SIGNER" -P -3 - -o "$zone" -f ${zonefile}.signed "$zonefile" > /dev/null 2>&1 "$SIGNER" -P -3 - -o "$zone" -f ${zonefile}.signed "$zonefile" > /dev/null 2>&1 # diff --git a/bin/tests/system/dnssec/ns5/sign.sh b/bin/tests/system/dnssec/ns5/sign.sh index 9f9c39fb73..83f08769c0 100644 --- a/bin/tests/system/dnssec/ns5/sign.sh +++ b/bin/tests/system/dnssec/ns5/sign.sh @@ -14,6 +14,8 @@ set -e +echo_i "ns5/sign.sh" + zone=. infile=../ns1/root.db.in zonefile=root.db.signed diff --git a/bin/tests/system/dnssec/ns6/sign.sh b/bin/tests/system/dnssec/ns6/sign.sh index 54a21548bc..80d8881c15 100644 --- a/bin/tests/system/dnssec/ns6/sign.sh +++ b/bin/tests/system/dnssec/ns6/sign.sh @@ -14,6 +14,8 @@ set -e +echo_i "ns6/sign.sh" + zone=optout-tld infile=optout-tld.db.in zonefile=optout-tld.db diff --git a/bin/tests/system/dnssec/ns7/sign.sh b/bin/tests/system/dnssec/ns7/sign.sh index a5d8dc0bd2..625300339c 100644 --- a/bin/tests/system/dnssec/ns7/sign.sh +++ b/bin/tests/system/dnssec/ns7/sign.sh @@ -14,6 +14,8 @@ set -e +echo_i "ns7/sign.sh" + zone=split-rrsig infile=split-rrsig.db.in zonefile=split-rrsig.db diff --git a/bin/tests/system/dnssec/ns8/named.conf.in b/bin/tests/system/dnssec/ns8/named.conf.in new file mode 100644 index 0000000000..de95e26301 --- /dev/null +++ b/bin/tests/system/dnssec/ns8/named.conf.in @@ -0,0 +1,46 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * 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 http://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +// NS8 + +options { + query-source address 10.53.0.8; + notify-source 10.53.0.8; + transfer-source 10.53.0.8; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.8; }; + listen-on-v6 { none; }; + recursion yes; + dnssec-enable yes; + dnssec-validation yes; + minimal-responses no; + disable-algorithms "disabled.managed." { @DISABLED_ALGORITHM@; }; + disable-algorithms "disabled.trusted." { @DISABLED_ALGORITHM@; }; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.8 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../common/root.hint"; +}; + +include "managed.conf"; +include "trusted.conf"; + diff --git a/bin/tests/system/dnssec/setup.sh b/bin/tests/system/dnssec/setup.sh index 62cf46cff0..2238153204 100644 --- a/bin/tests/system/dnssec/setup.sh +++ b/bin/tests/system/dnssec/setup.sh @@ -25,6 +25,7 @@ copy_setports ns5/named1.conf.in ns5/named.conf copy_setports ns6/named.conf.in ns6/named.conf copy_setports ns7/named.conf.in ns7/named.conf +copy_setports ns8/named.conf.in ns8/named.conf ( cd ns1 diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index b07f540c5e..458ecacf7f 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -1402,8 +1402,11 @@ status=$((status+ret)) echo_i "checking that a key using an unsupported algorithm cannot be generated ($n)" ret=0 zone=example -$KEYGEN -a 255 example > dnssectools.out.test$n 2>&1 && ret=0 -grep "unsupported algorithm: 255" dnssectools.out.test$n || ret=1 +# If dnssec-keygen fails, the test script will exit immediately. Prevent that +# from happening, and also trigger a test failure if dnssec-keygen unexpectedly +# succeeds, by using "&& ret=1". +$KEYGEN -a 255 $zone > dnssectools.out.test$n 2>&1 && ret=1 +grep -q "unsupported algorithm: 255" dnssectools.out.test$n || ret=1 n=$((n+1)) test "$ret" -eq 0 || echo_i "failed" status=$((status+ret)) @@ -1413,23 +1416,26 @@ ret=0 zone=example # Fake an unsupported algorithm key unsupportedkey=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") -awk '$3 == "DNSKEY" { $6 = 255; print } { print }' ${unsupportedkey}.key > ${unsupportedkey}.tmp +awk '$3 == "DNSKEY" { $6 = 255 } { print }' ${unsupportedkey}.key > ${unsupportedkey}.tmp mv ${unsupportedkey}.tmp ${unsupportedkey}.key -$DSFROMKEY ${unsupportedkey} > dnssectools.out.test$n 2>&1 && ret=0 -grep "algorithm is unsupported" dnssectools.out.test$n || ret=1 +# If dnssec-dsfromkey fails, the test script will exit immediately. Prevent +# that from happening, and also trigger a test failure if dnssec-dsfromkey +# unexpectedly succeeds, by using "&& ret=1". +$DSFROMKEY ${unsupportedkey} > dnssectools.out.test$n 2>&1 && ret=1 +grep -q "algorithm is unsupported" dnssectools.out.test$n || ret=1 n=$((n+1)) test "$ret" -eq 0 || echo_i "failed" status=$((status+ret)) echo_i "checking that a zone cannot be signed with a key using an unsupported algorithm ($n)" ret=0 -cp ${unsupportedkey}.* signer/ -( -cd signer || exit 1 -cat example.db.in "${unsupportedkey}.key" > example.db -$SIGNER -o example example.db ${unsupportedkey} > ../dnssectools.out.test$n 2>&1 && ret=0 -) && ret=0 -grep "algorithm is unsupported" dnssectools.out.test$n || ret=1 +ret=0 +cat signer/example.db.in "${unsupportedkey}.key" > signer/example.db +# If dnssec-signzone fails, the test script will exit immediately. Prevent that +# from happening, and also trigger a test failure if dnssec-signzone +# unexpectedly succeeds, by using "&& ret=1". +$SIGNER -o example signer/example.db ${unsupportedkey} > dnssectools.out.test$n 2>&1 && ret=1 +grep -q "algorithm is unsupported" dnssectools.out.test$n || ret=1 n=$((n+1)) test "$ret" -eq 0 || echo_i "failed" status=$((status+ret)) @@ -3683,5 +3689,172 @@ n=$((n+1)) test "$ret" -eq 0 || echo_i "failed" status=$((status+ret)) +# +# DNSSEC tests related to unsupported, disabled and revoked trust anchors. +# + +# This nameserver (ns8) is loaded with a bunch of trust anchors. Some of them +# are good (enabled.managed, enabled.trusted, secure.managed, secure.trusted), +# and some of them are bad (disabled.managed, revoked.managed, unsupported.managed, +# disabled.trusted, revoked.trusted, unsupported.trusted). Make sure that the bad +# trust anchors are ignored. This is tested by looking for the corresponding +# lines in the logfile. +echo_i "checking that keys with unsupported algorithms and disabled algorithms are ignored ($n)" +ret=0 +grep -q "ignoring trusted key for 'disabled\.trusted\.': algorithm is disabled" ns8/named.run || ret=1 +grep -q "ignoring trusted key for 'unsupported\.trusted\.': algorithm is unsupported" ns8/named.run || ret=1 +grep -q "ignoring managed key for 'disabled\.managed\.': algorithm is disabled" ns8/named.run || ret=1 +grep -q "ignoring managed key for 'unsupported\.managed\.': algorithm is unsupported" ns8/named.run || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +# The next two tests are fairly normal DNSSEC queries to signed zones with a +# default algorithm. First, a query is made against the server that is +# authoritative for the given zone (ns3). Second, a query is made against a +# resolver with trust anchors for the given zone (ns8). Both are expected to +# return an authentic data positive response. +echo_i "checking that a trusted key using a supported algorithm validates as secure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.secure.trusted A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.secure.trusted A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +echo_i "checking that a managed key using a supported algorithm validates as secure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.secure.managed A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.secure.managed A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +# The next two queries ensure that a zone signed with a DNSKEY with an unsupported +# algorithm will yield insecure positive responses. These trust anchors in ns8 are +# ignored and so this domain is treated as insecure. The AD bit should not be set +# in the response. +echo_i "checking that a trusted key using an unsupported algorithm validates as insecure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.unsupported.trusted A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.unsupported.trusted A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +echo_i "checking that a managed key using an unsupported algorithm validates as insecure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.unsupported.managed A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.unsupported.managed A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +# The next two queries ensure that a zone signed with a DNSKEY that the nameserver +# has a disabled algorithm match for will yield insecure positive responses. +# These trust anchors in ns8 are ignored and so this domain is treated as insecure. +# The AD bit should not be set in the response. +echo_i "checking that a trusted key using a disabled algorithm validates as insecure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.disabled.trusted A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.disabled.trusted A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +echo_i "checking that a managed key using a disabled algorithm validates as insecure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.disabled.managed A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.disabled.managed A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +# The next two queries ensure that a zone signed with a DNSKEY that the +# nameserver has a disabled algorithm for, but for a different domain, will +# yield secure positive responses. Since "enabled.trusted." and +# "enabled.managed." do not match the "disable-algorithms" option, no +# special rules apply and these zones should validate as secure, with the AD +# bit set. +echo_i "checking that a trusted key using an algorithm disabled for another domain validates as secure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.enabled.trusted A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.enabled.trusted A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +echo_i "checking that a managed key using an algorithm disabled for another domain validates as secure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.enabled.managed A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.enabled.managed A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +# A configured revoked trust anchor is ignored and thus the two queries below +# should result in insecure responses, since no trust points for the +# "revoked.trusted." and "revoked.managed." zones are created. +echo_i "checking that a trusted key that is revoked validates as insecure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.revoked.trusted A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.revoked.trusted A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +echo_i "checking that a managed key that is revoked validates as insecure ($n)" +ret=0 +dig_with_opts @10.53.0.3 a.revoked.managed A > dig.out.ns3.test$n +dig_with_opts @10.53.0.8 a.revoked.managed A > dig.out.ns8.test$n +grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 +grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + +# Note: after this check, ns4 will not be validating any more; do not add any +# further validation tests employing ns4 below this check. +echo_i "check that validation defaults to off when dnssec-enable is off ($n)" +ret=0 +# Sanity check - validation should be enabled. +rndccmd 10.53.0.4 validation status | grep "enabled" > /dev/null || ret=1 +# Set "dnssec-enable" to "no" and reconfigure. +copy_setports ns4/named5.conf.in ns4/named.conf +rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i +# Check validation status again. +rndccmd 10.53.0.4 validation status | grep "disabled" > /dev/null || ret=1 +n=$((n+1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status+ret)) + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index f69d5dcc75..a97a4d3acf 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -5033,6 +5033,12 @@ options { by the disable-algorithms will be treated as insecure. + + Configured trust anchors in trusted-keys + or managed-keys that match a disabled + algorithm will be ignored and treated as if they were not + configured at all. +