2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 10:10:06 +00:00

[master] allow CDS/CDNSKEY records to be signed with only KSK

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]
This commit is contained in:
Evan Hunt 2017-09-12 23:09:48 -07:00
parent e930487ce7
commit 20502f35dd
15 changed files with 183 additions and 31 deletions

View File

@ -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 4720. [func] Added a statistics counter to track prefetch
queries. [RT #45847] queries. [RT #45847]

View File

@ -659,7 +659,9 @@ signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
if (!issigningkey(key)) if (!issigningkey(key))
continue; 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)) { dns_name_equal(name, gorigin)) {
isc_boolean_t have_ksk; isc_boolean_t have_ksk;
dns_dnsseckey_t *tmpkey; 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)) (iszsk(key) && !keyset_kskonly))
signwithkey(name, set, key->key, ttl, add, signwithkey(name, set, key->key, ttl, add,
"signing with dnskey"); "signing with dnskey");
} else if (set->type == dns_rdatatype_cds || } else if (iszsk(key)) {
set->type == dns_rdatatype_cdnskey ||
iszsk(key)) {
signwithkey(name, set, key->key, ttl, add, signwithkey(name, set, key->key, ttl, add,
"signing with dnskey"); "signing with dnskey");
} }

View File

@ -705,8 +705,9 @@
<term>-x</term> <term>-x</term>
<listitem> <listitem>
<para> <para>
Only sign the DNSKEY RRset with key-signing keys, and omit Only sign the DNSKEY, CDNSKEY, and CDS RRsets with
signatures from zone-signing keys. (This is similar to the key-signing keys, and omit signatures from zone-signing
keys. (This is similar to the
<command>dnssec-dnskey-kskonly yes;</command> zone option in <command>dnssec-dnskey-kskonly yes;</command> zone option in
<command>named</command>.) <command>named</command>.)
</para> </para>

View File

@ -7,27 +7,29 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
rm -f */K* */dsset-* */*.signed */tmp* */*.jnl */*.bk rm -f */K* */dsset-* */*.signed */tmp* */*.jnl */*.bk
rm -f */trusted.conf */private.conf
rm -f */core rm -f */core
rm -f */example.bk rm -f */example.bk
rm -f */named.memstats rm -f */named.memstats
rm -f */named.run rm -f */named.run
rm -f */trusted.conf */private.conf
rm -f activate-now-publish-1day.key rm -f activate-now-publish-1day.key
rm -f active.key inact.key del.key unpub.key standby.key rev.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 delayksk.key delayzsk.key autoksk.key autozsk.key
rm -f dig.out.* rm -f dig.out.*
rm -f digcomp.out.test* rm -f digcomp.out.test*
rm -f digcomp.out.test*
rm -f missingzsk.key inactivezsk.key rm -f missingzsk.key inactivezsk.key
rm -f nopriv.key vanishing.key del1.key del2.key rm -f nopriv.key vanishing.key del1.key del2.key
rm -f ns*/named.lock rm -f ns*/named.lock
rm -f ns*/named.lock
rm -f ns1/root.db rm -f ns1/root.db
rm -f ns2/example.db rm -f ns2/example.db
rm -f ns2/private.secure.example.db ns2/bar.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/*.nzf
rm -f ns3/autonsec3.example.db 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/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/nozsk.example.db ns3/inaczsk.example.db
rm -f ns3/nsec.example.db rm -f ns3/nsec.example.db
rm -f ns3/nsec3-to-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.example.db
rm -f ns3/secure.nsec3.example.db rm -f ns3/secure.nsec3.example.db
rm -f ns3/secure.optout.example.db rm -f ns3/secure.optout.example.db
rm -f ns3/sync.example.db
rm -f ns3/ttl*.db rm -f ns3/ttl*.db
rm -f nsupdate.out rm -f nsupdate.out
rm -f signing.out.*
rm -f settime.out.* rm -f settime.out.*
rm -f ns3/*.nzd ns3/*.nzd-lock ns3/*.nzf rm -f signing.out.*
rm -f digcomp.out.test* rm -f sync.key
rm -f ns*/named.lock

View File

@ -248,7 +248,7 @@ echo $zsk > ../inactivezsk.key
$SETTIME -I now $zsk > st.out 2>&1 || dumpit st.out $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 setup reconf.example
cp secure.example.db.in $zonefile 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 $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 setup sync.example
cp $infile $zonefile 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 $KEYGEN -a RSASHA1 -3 -q -r $RANDFILE $zone > kg.out 2>&1 || dumpit kg.out
$DSFROMKEY $ksk.key > dsset-${zone}$TP $DSFROMKEY $ksk.key > dsset-${zone}$TP
echo ns3/$ksk > ../sync.key 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

View File

@ -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

View File

@ -6,8 +6,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * 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 // NS3
controls { /* empty */ }; controls { /* empty */ };
@ -243,4 +241,12 @@ zone "sync.example" {
auto-dnssec maintain; 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"; include "trusted.conf";

View File

@ -1166,8 +1166,38 @@ if [ "$lret" != 0 ]; then ret=$lret; fi
if [ $ret != 0 ]; then echo "I:failed"; fi if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret` 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'" 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 $RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 loadkeys sync.example
echo "I:waiting for deletion to occur" echo "I:waiting for deletion to occur"
sleep 3 sleep 3

View File

@ -30,9 +30,10 @@ rm -f ns2/algroll.db
rm -f ns2/badparam.db ns2/badparam.db.bad rm -f ns2/badparam.db ns2/badparam.db.bad
rm -f ns2/cdnskey-update.secure.db rm -f ns2/cdnskey-update.secure.db
rm -f ns2/cdnskey.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-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-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/dlv.db
rm -f ns2/in-addr.arpa.db rm -f ns2/in-addr.arpa.db
rm -f ns2/nsec3chain-test.db rm -f ns2/nsec3chain-test.db

View File

@ -102,6 +102,11 @@ zone "cds.secure" {
file "cds.secure.db.signed"; file "cds.secure.db.signed";
}; };
zone "cds-x.secure" {
type master;
file "cds-x.secure.db.signed";
};
zone "cds-update.secure" { zone "cds-update.secure" {
type master; type master;
file "cds-update.secure.db.signed"; file "cds-update.secure.db.signed";
@ -120,6 +125,11 @@ zone "cdnskey.secure" {
file "cdnskey.secure.db.signed"; file "cdnskey.secure.db.signed";
}; };
zone "cdnskey-x.secure" {
type master;
file "cdnskey-x.secure.db.signed";
};
zone "cdnskey-update.secure" { zone "cdnskey-update.secure" {
type master; type master;
file "cdnskey-update.secure.db.signed"; file "cdnskey-update.secure.db.signed";

View File

@ -194,6 +194,16 @@ $DSFROMKEY -C $key1.key > $key1.cds
cat $infile $key1.key $key2.key $key1.cds >$zonefile cat $infile $key1.key $key2.key $key1.cds >$zonefile
$SIGNER -P -g -r $RANDFILE -o $zone $zonefile > /dev/null $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 zone=cds-update.secure
infile=cds-update.secure.db.in infile=cds-update.secure.db.in
zonefile=cds-update.secure.db 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 cat $infile $key1.key $key2.key $key1.cds >$zonefile
$SIGNER -P -g -r $RANDFILE -o $zone $zonefile > /dev/null $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 zone=cdnskey-update.secure
infile=cdnskey-update.secure.db.in infile=cdnskey-update.secure.db.in
zonefile=cdnskey-update.secure.db zonefile=cdnskey-update.secure.db

View File

@ -3002,6 +3002,15 @@ n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret` 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)" echo "I:checking that positive unknown NSEC3 hash algorithm does validate ($n)"
ret=0 ret=0
$DIG $DIGOPTS +noauth +noadd +nodnssec +adflag -p 5300 @10.53.0.3 nsec3-unknown.example SOA > dig.out.ns3.test$n $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 if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret` 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)" echo "I:checking that negative unknown NSEC3 hash algorithm with OPTOUT does not validate ($n)"
ret=0 ret=0
$DIG $DIGOPTS +noauth +noadd +nodnssec +adflag -p 5300 @10.53.0.3 optout-unknown.example A > dig.out.ns3.test$n $DIG $DIGOPTS +noauth +noadd +nodnssec +adflag -p 5300 @10.53.0.3 optout-unknown.example A > dig.out.ns3.test$n

View File

@ -7139,9 +7139,9 @@ options {
When this option and <command>update-check-ksk</command> When this option and <command>update-check-ksk</command>
are both set to <literal>yes</literal>, only key-signing are both set to <literal>yes</literal>, only key-signing
keys (that is, keys with the KSK bit set) will be used keys (that is, keys with the KSK bit set) will be used
to sign the DNSKEY RRset at the zone apex. Zone-signing to sign the DNSKEY, CDNSKEY, and CDS RRsets at the zone apex.
keys (keys without the KSK bit set) will be used to sign Zone-signing keys (keys without the KSK bit set) will be used
the remainder of the zone, but not the DNSKEY RRset. to sign the remainder of the zone, but not the DNSKEY RRset.
This is similar to the This is similar to the
<command>dnssec-signzone -x</command> command line option. <command>dnssec-signzone -x</command> command line option.
</para> </para>

View File

@ -482,6 +482,16 @@
queries. [RT #45847] queries. [RT #45847]
</para> </para>
</listitem> </listitem>
<listitem>
<para>
The <command>dnssec-signzone -x</command> flag and the
<command>dnssec-dnskey-kskonly</command> option in
<command>named.conf</command>, 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]
</para>
</listitem>
</itemizedlist> </itemizedlist>
</section> </section>

View File

@ -6234,7 +6234,10 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
} }
} }
if (both) { 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) if (!KSK(keys[i]) && keyset_kskonly)
continue; continue;
} else if (KSK(keys[i])) } 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); dns_rdatasetiter_current(iterator, &rdataset);
if (rdataset.type == dns_rdatatype_soa || if (rdataset.type == dns_rdatatype_soa ||
rdataset.type == dns_rdatatype_rrsig) rdataset.type == dns_rdatatype_rrsig)
{
goto next_rdataset; goto next_rdataset;
if (rdataset.type == dns_rdatatype_dnskey) { }
if (!is_ksk && keyset_kskonly) if (rdataset.type == dns_rdatatype_dnskey ||
goto next_rdataset; rdataset.type == dns_rdatatype_cdnskey ||
} else if (is_ksk) { 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 && if (!is_ksk && keyset_kskonly) {
rdataset.type != dns_rdatatype_cdnskey)
goto next_rdataset; goto next_rdataset;
}
} else if (is_ksk) {
goto next_rdataset;
} }
if (*delegation && if (*delegation &&
rdataset.type != dns_rdatatype_ds && rdataset.type != dns_rdatatype_ds &&
rdataset.type != dns_rdatatype_nsec) rdataset.type != dns_rdatatype_nsec)
{
goto next_rdataset; 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; goto next_rdataset;
}
/* Calculate the signature, creating a RRSIG RDATA. */ /* Calculate the signature, creating a RRSIG RDATA. */
isc_buffer_clear(&buffer); isc_buffer_clear(&buffer);
CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,