diff --git a/CHANGES b/CHANGES index a27f2fab3a..b00baff4d9 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +4721. [func] 'dnssec-signzone -x' and 'dnssec-dnskey-kskonly' + options now apply to CDNSKEY and DS records as well + as DNSKEY. Thanks to Tony Finch. [RT #45689] + 4720. [func] Added a statistics counter to track prefetch queries. [RT #45847] diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c index 47759558e5..5d278a18a8 100644 --- a/bin/dnssec/dnssec-signzone.c +++ b/bin/dnssec/dnssec-signzone.c @@ -659,7 +659,9 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, if (!issigningkey(key)) continue; - if (set->type == dns_rdatatype_dnskey && + if ((set->type == dns_rdatatype_cds || + set->type == dns_rdatatype_cdnskey || + set->type == dns_rdatatype_dnskey) && dns_name_equal(name, gorigin)) { isc_boolean_t have_ksk; dns_dnsseckey_t *tmpkey; @@ -680,9 +682,7 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name, (iszsk(key) && !keyset_kskonly)) signwithkey(name, set, key->key, ttl, add, "signing with dnskey"); - } else if (set->type == dns_rdatatype_cds || - set->type == dns_rdatatype_cdnskey || - iszsk(key)) { + } else if (iszsk(key)) { signwithkey(name, set, key->key, ttl, add, "signing with dnskey"); } diff --git a/bin/dnssec/dnssec-signzone.docbook b/bin/dnssec/dnssec-signzone.docbook index 82089a9613..79e5d25fab 100644 --- a/bin/dnssec/dnssec-signzone.docbook +++ b/bin/dnssec/dnssec-signzone.docbook @@ -705,8 +705,9 @@ -x - Only sign the DNSKEY RRset with key-signing keys, and omit - signatures from zone-signing keys. (This is similar to the + Only sign the DNSKEY, CDNSKEY, and CDS RRsets with + key-signing keys, and omit signatures from zone-signing + keys. (This is similar to the dnssec-dnskey-kskonly yes; zone option in named.) diff --git a/bin/tests/system/autosign/clean.sh b/bin/tests/system/autosign/clean.sh index 1033cbdbc2..ac393db64d 100644 --- a/bin/tests/system/autosign/clean.sh +++ b/bin/tests/system/autosign/clean.sh @@ -7,27 +7,29 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. rm -f */K* */dsset-* */*.signed */tmp* */*.jnl */*.bk -rm -f */trusted.conf */private.conf rm -f */core rm -f */example.bk rm -f */named.memstats rm -f */named.run +rm -f */trusted.conf */private.conf rm -f activate-now-publish-1day.key rm -f active.key inact.key del.key unpub.key standby.key rev.key -rm -f sync.key rm -f delayksk.key delayzsk.key autoksk.key autozsk.key rm -f dig.out.* rm -f digcomp.out.test* +rm -f digcomp.out.test* rm -f missingzsk.key inactivezsk.key rm -f nopriv.key vanishing.key del1.key del2.key rm -f ns*/named.lock +rm -f ns*/named.lock rm -f ns1/root.db rm -f ns2/example.db rm -f ns2/private.secure.example.db ns2/bar.db +rm -f ns3/*.nzd ns3/*.nzd-lock ns3/*.nzf rm -f ns3/*.nzf rm -f ns3/autonsec3.example.db -rm -f ns3/sync.example.db rm -f ns3/kg.out ns3/s.out ns3/st.out +rm -f ns3/kskonly.example.db rm -f ns3/nozsk.example.db ns3/inaczsk.example.db rm -f ns3/nsec.example.db rm -f ns3/nsec3-to-nsec.example.db @@ -47,10 +49,9 @@ rm -f ns3/secure-to-insecure2.example.db rm -f ns3/secure.example.db rm -f ns3/secure.nsec3.example.db rm -f ns3/secure.optout.example.db +rm -f ns3/sync.example.db rm -f ns3/ttl*.db rm -f nsupdate.out -rm -f signing.out.* rm -f settime.out.* -rm -f ns3/*.nzd ns3/*.nzd-lock ns3/*.nzf -rm -f digcomp.out.test* -rm -f ns*/named.lock +rm -f signing.out.* +rm -f sync.key diff --git a/bin/tests/system/autosign/ns3/keygen.sh b/bin/tests/system/autosign/ns3/keygen.sh index 769171e645..b3ded65eb6 100644 --- a/bin/tests/system/autosign/ns3/keygen.sh +++ b/bin/tests/system/autosign/ns3/keygen.sh @@ -248,7 +248,7 @@ echo $zsk > ../inactivezsk.key $SETTIME -I now $zsk > st.out 2>&1 || dumpit st.out # -# A zone that is set to 'auto-dnssec maintain' during a recofnig +# A zone that is set to 'auto-dnssec maintain' during a reconfig # setup reconf.example cp secure.example.db.in $zonefile @@ -256,7 +256,7 @@ $KEYGEN -q -a RSASHA1 -3 -r $RANDFILE -fk $zone > kg.out 2>&1 || dumpit kg.out $KEYGEN -q -a RSASHA1 -3 -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out # -# A zone which generates a CDS and CDNSEY RRsets automatically +# A zone which generates CDS and CDNSEY RRsets automatically # setup sync.example cp $infile $zonefile @@ -264,3 +264,12 @@ ksk=`$KEYGEN -a RSASHA1 -3 -q -r $RANDFILE -fk -P sync now $zone 2> kg.out` || d $KEYGEN -a RSASHA1 -3 -q -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out $DSFROMKEY $ksk.key > dsset-${zone}$TP echo ns3/$ksk > ../sync.key + +# +# A zone that generates CDS and CDNSKEY and uses dnssec-dnskey-kskonly +# +setup kskonly.example +cp $infile $zonefile +ksk=`$KEYGEN -a RSASHA1 -3 -q -r $RANDFILE -fk -P sync now $zone 2> kg.out` || dumpit kg.out +$KEYGEN -a RSASHA1 -3 -q -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out +$DSFROMKEY $ksk.key > dsset-${zone}$TP diff --git a/bin/tests/system/autosign/ns3/kskonly.example.db.in b/bin/tests/system/autosign/ns3/kskonly.example.db.in new file mode 100644 index 0000000000..b8e46a6599 --- /dev/null +++ b/bin/tests/system/autosign/ns3/kskonly.example.db.in @@ -0,0 +1,29 @@ +; Copyright (C) 2015, 2016 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/. + +$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 ns +ns A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +d A 10.0.0.4 +z A 10.0.0.26 +a.a.a.a.a.a.a.a.a.a.e A 10.0.0.27 +x CNAME a + +private NS ns.private +ns.private A 10.53.0.2 + +insecure NS ns.insecure +ns.insecure A 10.53.0.2 diff --git a/bin/tests/system/autosign/ns3/named.conf b/bin/tests/system/autosign/ns3/named.conf index b45de3d7f6..add46e5d06 100644 --- a/bin/tests/system/autosign/ns3/named.conf +++ b/bin/tests/system/autosign/ns3/named.conf @@ -6,8 +6,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -/* $Id: named.conf,v 1.15 2012/02/06 23:46:47 tbox Exp $ */ - // NS3 controls { /* empty */ }; @@ -243,4 +241,12 @@ zone "sync.example" { auto-dnssec maintain; }; +zone "kskonly.example" { + type master; + file "kskonly.example.db"; + allow-update { any; }; + dnssec-dnskey-kskonly yes; + auto-dnssec maintain; +}; + include "trusted.conf"; diff --git a/bin/tests/system/autosign/tests.sh b/bin/tests/system/autosign/tests.sh index 7cd19084e6..e30d06306b 100644 --- a/bin/tests/system/autosign/tests.sh +++ b/bin/tests/system/autosign/tests.sh @@ -1166,8 +1166,38 @@ if [ "$lret" != 0 ]; then ret=$lret; fi if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I:test 'dnssec-dnskey-kskonly no' affects DNSKEY/CDS/CDNSKEY ($n)" +ret=0 +$DIG $DIGOPTS @10.53.0.3 sync.example dnskey > dig.out.ns3.dnskeytest$n +$DIG $DIGOPTS @10.53.0.3 sync.example cdnskey > dig.out.ns3.cdnskeytest$n +$DIG $DIGOPTS @10.53.0.3 sync.example cds > dig.out.ns3.cdstest$n +lines=`awk '$4 == "RRSIG" && $5 == "DNSKEY" {print}' dig.out.ns3.dnskeytest$n | wc -l` +test ${lines:-0} -eq 2 || ret=1 +lines=`awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.ns3.cdnskeytest$n | wc -l` +test ${lines:-0} -eq 2 || ret=1 +lines=`awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.ns3.cdstest$n | wc -l` +test ${lines:-0} -eq 2 || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:test 'dnssec-dnskey-kskonly yes' affects DNSKEY/CDS/CDNSKEY ($n)" +ret=0 +$DIG $DIGOPTS @10.53.0.3 kskonly.example dnskey > dig.out.ns3.dnskeytest$n +$DIG $DIGOPTS @10.53.0.3 kskonly.example cdnskey > dig.out.ns3.cdnskeytest$n +$DIG $DIGOPTS @10.53.0.3 kskonly.example cds > dig.out.ns3.cdstest$n +lines=`awk '$4 == "RRSIG" && $5 == "DNSKEY" {print}' dig.out.ns3.dnskeytest$n | wc -l` +test ${lines:-0} -eq 1 || ret=1 +lines=`awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.ns3.cdnskeytest$n | wc -l` +test ${lines:-0} -eq 1 || ret=1 +lines=`awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.ns3.cdstest$n | wc -l` +test ${lines:-0} -eq 1 || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:setting CDS and CDNSKEY deletion times and calling 'rndc loadkeys'" -$SETTIME -D sync now+2 `cat sync.key` +$SETTIME -D sync now+2 `cat sync.key` > /dev/null $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 loadkeys sync.example echo "I:waiting for deletion to occur" sleep 3 diff --git a/bin/tests/system/dnssec/clean.sh b/bin/tests/system/dnssec/clean.sh index acb139904f..d4549dc266 100644 --- a/bin/tests/system/dnssec/clean.sh +++ b/bin/tests/system/dnssec/clean.sh @@ -30,9 +30,10 @@ rm -f ns2/algroll.db rm -f ns2/badparam.db ns2/badparam.db.bad rm -f ns2/cdnskey-update.secure.db rm -f ns2/cdnskey.secure.db +rm -f ns2/cdnskey-x.secure.db rm -f ns2/cds-auto.secure.db ns2/cds-auto.secure.db.jnl rm -f ns2/cds-update.secure.db ns2/cds-update.secure.db.jnl -rm -f ns2/cds.secure.db +rm -f ns2/cds.secure.db ns2/cds-x.secure.db rm -f ns2/dlv.db rm -f ns2/in-addr.arpa.db rm -f ns2/nsec3chain-test.db diff --git a/bin/tests/system/dnssec/ns2/named.conf b/bin/tests/system/dnssec/ns2/named.conf index 5233f1ec69..b76f7f3777 100644 --- a/bin/tests/system/dnssec/ns2/named.conf +++ b/bin/tests/system/dnssec/ns2/named.conf @@ -102,6 +102,11 @@ zone "cds.secure" { file "cds.secure.db.signed"; }; +zone "cds-x.secure" { + type master; + file "cds-x.secure.db.signed"; +}; + zone "cds-update.secure" { type master; file "cds-update.secure.db.signed"; @@ -120,6 +125,11 @@ zone "cdnskey.secure" { file "cdnskey.secure.db.signed"; }; +zone "cdnskey-x.secure" { + type master; + file "cdnskey-x.secure.db.signed"; +}; + zone "cdnskey-update.secure" { type master; file "cdnskey-update.secure.db.signed"; diff --git a/bin/tests/system/dnssec/ns2/sign.sh b/bin/tests/system/dnssec/ns2/sign.sh index b7264f6d8c..fb4744d3e4 100644 --- a/bin/tests/system/dnssec/ns2/sign.sh +++ b/bin/tests/system/dnssec/ns2/sign.sh @@ -194,6 +194,16 @@ $DSFROMKEY -C $key1.key > $key1.cds cat $infile $key1.key $key2.key $key1.cds >$zonefile $SIGNER -P -g -r $RANDFILE -o $zone $zonefile > /dev/null +zone=cds-x.secure +infile=cds.secure.db.in +zonefile=cds-x.secure.db +key1=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -fk $zone` +key2=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -fk $zone` +key3=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone $zone` +$DSFROMKEY -C $key2.key > $key2.cds +cat $infile $key1.key $key3.key $key2.cds >$zonefile +$SIGNER -P -g -x -r $RANDFILE -o $zone $zonefile > /dev/null + zone=cds-update.secure infile=cds-update.secure.db.in zonefile=cds-update.secure.db @@ -219,6 +229,16 @@ sed 's/DNSKEY/CDNSKEY/' $key1.key > $key1.cds cat $infile $key1.key $key2.key $key1.cds >$zonefile $SIGNER -P -g -r $RANDFILE -o $zone $zonefile > /dev/null +zone=cdnskey-x.secure +infile=cdnskey.secure.db.in +zonefile=cdnskey-x.secure.db +key1=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -fk $zone` +key2=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone -fk $zone` +key3=`$KEYGEN -q -r $RANDFILE -a RSASHA1 -b 1024 -n zone $zone` +sed 's/DNSKEY/CDNSKEY/' $key1.key > $key1.cds +cat $infile $key2.key $key3.key $key1.cds >$zonefile +$SIGNER -P -g -x -r $RANDFILE -o $zone $zonefile > /dev/null + zone=cdnskey-update.secure infile=cdnskey-update.secure.db.in zonefile=cdnskey-update.secure.db diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index 3a1cd1027e..e02b44cf45 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -3002,6 +3002,15 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I:check that CDS records are not signed using ZSK by dnssec-signzone -x ($n)" +ret=0 +$DIG $DIGOPTS +noall +answer @10.53.0.2 cds cds-x.secure > dig.out.test$n +lines=`awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l` +test ${lines:-0} -eq 1 || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:checking that positive unknown NSEC3 hash algorithm does validate ($n)" ret=0 $DIG $DIGOPTS +noauth +noadd +nodnssec +adflag -p 5300 @10.53.0.3 nsec3-unknown.example SOA > dig.out.ns3.test$n @@ -3122,6 +3131,15 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I:check that CDNSKEY records are not signed using ZSK by dnssec-signzone -x ($n)" +ret=0 +$DIG $DIGOPTS +noall +answer @10.53.0.2 cdnskey cdnskey-x.secure > dig.out.test$n +lines=`awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l` +test ${lines:-0} -eq 1 || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:checking that negative unknown NSEC3 hash algorithm with OPTOUT does not validate ($n)" ret=0 $DIG $DIGOPTS +noauth +noadd +nodnssec +adflag -p 5300 @10.53.0.3 optout-unknown.example A > dig.out.ns3.test$n diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index d0afb11fda..2058484908 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -7139,9 +7139,9 @@ options { When this option and update-check-ksk are both set to yes, only key-signing keys (that is, keys with the KSK bit set) will be used - to sign the DNSKEY RRset at the zone apex. Zone-signing - keys (keys without the KSK bit set) will be used to sign - the remainder of the zone, but not the DNSKEY RRset. + to sign the DNSKEY, CDNSKEY, and CDS RRsets at the zone apex. + Zone-signing keys (keys without the KSK bit set) will be used + to sign the remainder of the zone, but not the DNSKEY RRset. This is similar to the dnssec-signzone -x command line option. diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index 22be2e53b2..645ac46cff 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -482,6 +482,16 @@ queries. [RT #45847] + + + The dnssec-signzone -x flag and the + dnssec-dnskey-kskonly option in + named.conf, which suppress the use of + the ZSK when signing DNSKEY records, now also apply to + CDNSKEY and CDS records. Thanks to Tony Finch for the + contribution. [RT #45689] + + diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 85a171f40a..c15d31540d 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -6234,7 +6234,10 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, } } if (both) { - if (type == dns_rdatatype_dnskey) { + if (type == dns_rdatatype_dnskey || + type == dns_rdatatype_cdnskey || + type == dns_rdatatype_cds) + { if (!KSK(keys[i]) && keyset_kskonly) continue; } else if (KSK(keys[i])) @@ -6652,24 +6655,34 @@ sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node, dns_rdatasetiter_current(iterator, &rdataset); if (rdataset.type == dns_rdatatype_soa || rdataset.type == dns_rdatatype_rrsig) + { goto next_rdataset; - if (rdataset.type == dns_rdatatype_dnskey) { - if (!is_ksk && keyset_kskonly) - goto next_rdataset; - } else if (is_ksk) { + } + if (rdataset.type == dns_rdatatype_dnskey || + rdataset.type == dns_rdatatype_cdnskey || + rdataset.type == dns_rdatatype_cds) + { /* - * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1). + * CDS and CDNSKEY are signed with KSK like DNSKEY. + * (RFC 7344, section 4.1 specifies that they must + * be signed with a key in the current DS RRset, + * which would only include KSK's.) */ - if (rdataset.type != dns_rdatatype_cds && - rdataset.type != dns_rdatatype_cdnskey) + if (!is_ksk && keyset_kskonly) { goto next_rdataset; + } + } else if (is_ksk) { + goto next_rdataset; } if (*delegation && rdataset.type != dns_rdatatype_ds && rdataset.type != dns_rdatatype_nsec) + { goto next_rdataset; - if (signed_with_key(db, node, version, rdataset.type, key)) + } + if (signed_with_key(db, node, version, rdataset.type, key)) { goto next_rdataset; + } /* Calculate the signature, creating a RRSIG RDATA. */ isc_buffer_clear(&buffer); CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,