Merge branch '1653-dnssec-policy-view-race' into 'master'

Resolve "Race condition with dnssec-policy, same zone in different views"

Closes #1653

See merge request isc-projects/bind9!3142
This commit is contained in:
Matthijs Mekking 2020-03-09 14:40:59 +00:00
commit fd18da8cac
9 changed files with 135 additions and 2 deletions

View file

@ -1,3 +1,7 @@
5366. [bug] Fix a race condition with the keymgr when the same
zone plus dnssec-policy is configured in multiple
views. [GL #1653]
5365. [bug] Algorithm rollover was stuck on submitting DS
because keymgr thought it would move to an invalid
state. Fixed by when checking the current key,

View file

@ -0,0 +1,22 @@
; 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
@ IN SOA mname1. . (
1 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
NS ns4
ns4 A 10.53.0.4
view TXT "view1"

View file

@ -0,0 +1,22 @@
; 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
@ IN SOA mname1. . (
1 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
NS ns4
ns4 A 10.53.0.4
view TXT "view2"

View file

@ -26,6 +26,16 @@ key "sha256" {
secret "R16NojROxtxH/xbDl//ehDsHm5DjWTQ2YXV+hGC2iBY=";
};
key "keyforview1" {
algorithm "hmac-sha1";
secret "YPfMoAk6h+3iN8MDRQC004iSNHY=";
};
key "keyforview2" {
algorithm "hmac-sha1";
secret "4xILSZQnuO1UKubXHkYUsvBRPu8=";
};
dnssec-policy "test" {
keys {
csk key-directory lifetime 0 algorithm 14;
@ -115,3 +125,21 @@ view "none" {
file "none.none.signed.db";
};
};
view "example1" {
match-clients { key "keyforview1"; };
zone "example.net" {
type master;
file "example1.db";
};
};
view "example2" {
match-clients { key "keyforview2"; };
zone "example.net" {
type master;
file "example2.db";
};
};

View file

@ -26,3 +26,6 @@ do
zonefile="${zone}.db"
cp template.db.in $zonefile
done
cp example1.db.in example1.db
cp example2.db.in example2.db

View file

@ -28,6 +28,8 @@ TSIG=""
SHA1="FrSt77yPTFx6hTs4i2tKLB9LmE0="
SHA224="hXfwwwiag2QGqblopofai9NuW28q/1rH4CaTnA=="
SHA256="R16NojROxtxH/xbDl//ehDsHm5DjWTQ2YXV+hGC2iBY="
VIEW1="YPfMoAk6h+3iN8MDRQC004iSNHY="
VIEW2="4xILSZQnuO1UKubXHkYUsvBRPu8="
###############################################################################
# Key properties #
@ -1799,6 +1801,7 @@ dnssec_verify
# ns4/override.none.signed
# ns5/override.override.unsigned
# ns5/override.none.unsigned
# ns4/example.net (both views)
set_keyrole "KEY1" "csk"
set_keylifetime "KEY1" "0"
set_keyalgorithm "KEY1" "14" "ECDSAP384SHA384" "384"
@ -1850,6 +1853,39 @@ check_apex
check_subdomain
dnssec_verify
set_keydir "ns4"
set_zone "example.net"
set_server "ns4" "10.53.0.4"
TSIG="hmac-sha1:keyforview1:$VIEW1"
check_keys
check_apex
dnssec_verify
n=$((n+1))
# check subdomain
echo_i "check TXT example.net (view example1) rrset is signed correctly ($n)"
ret=0
dig_with_opts "view.${ZONE}" "@${SERVER}" TXT > "dig.out.$DIR.test$n.txt" || log_error "dig view.${ZONE} TXT failed"
grep "status: NOERROR" "dig.out.$DIR.test$n.txt" > /dev/null || log_error "mismatch status in DNS response"
grep "view.${ZONE}\..*${DEFAULT_TTL}.*IN.*TXT.*view1" "dig.out.$DIR.test$n.txt" > /dev/null || log_error "missing view.${ZONE} TXT record in response"
check_signatures TXT "dig.out.$DIR.test$n.txt" "ZSK"
test "$ret" -eq 0 || echo_i "failed"
status=$((status+ret))
TSIG="hmac-sha1:keyforview2:$VIEW2"
check_keys
check_apex
dnssec_verify
n=$((n+1))
# check subdomain
echo_i "check TXT example.net (view example2) rrset is signed correctly ($n)"
ret=0
dig_with_opts "view.${ZONE}" "@${SERVER}" TXT > "dig.out.$DIR.test$n.txt" || log_error "dig view.${ZONE} TXT failed"
grep "status: NOERROR" "dig.out.$DIR.test$n.txt" > /dev/null || log_error "mismatch status in DNS response"
grep "view.${ZONE}\..*${DEFAULT_TTL}.*IN.*TXT.*view2" "dig.out.$DIR.test$n.txt" > /dev/null || log_error "missing view.${ZONE} TXT record in response"
check_signatures TXT "dig.out.$DIR.test$n.txt" "ZSK"
test "$ret" -eq 0 || echo_i "failed"
status=$((status+ret))
# Clear TSIG.
TSIG=""

View file

@ -11132,6 +11132,13 @@ example.com CNAME rpz-tcp-only.
roll, which cryptographic algorithms to use, and how often RRSIG
records need to be refreshed.
</para>
<para>
Keys are not shared among zones, which means that one set of keys
per zone will be generated even if they have the same policy.
If multiple views are configured with different versions of the
same zone, each separate version will use the same set of signing
keys.
</para>
<para>
Multiple key and signing policies can be configured. To
attach a policy to a zone, add a <command>dnssec-policy</command>

View file

@ -90,6 +90,7 @@ destroy(dns_kasp_t *kasp) {
}
INSIST(ISC_LIST_EMPTY(kasp->keys));
isc_mutex_destroy(&kasp->lock);
isc_mem_free(kasp->mctx, kasp->name);
isc_mem_putanddetach(&kasp->mctx, kasp, sizeof(*kasp));
}

View file

@ -7279,6 +7279,7 @@ signed_with_good_key(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
int zsk_count = 0;
bool approved;
LOCK(&kasp->lock);
for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL;
kkey = ISC_LIST_NEXT(kkey, link))
{
@ -7289,6 +7290,7 @@ signed_with_good_key(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
zsk_count++;
}
}
UNLOCK(&kasp->lock);
if (type == dns_rdatatype_dnskey ||
type == dns_rdatatype_cdnskey || type == dns_rdatatype_cds)
@ -19423,6 +19425,10 @@ zone_rekey(dns_zone_t *zone) {
kasp = dns_zone_getkasp(zone);
fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN);
if (kasp != NULL) {
LOCK(&kasp->lock);
}
result = dns_dnssec_findmatchingkeys(&zone->origin, dir, now, mctx,
&keys);
if (result != ISC_R_SUCCESS) {
@ -19431,9 +19437,9 @@ zone_rekey(dns_zone_t *zone) {
isc_result_totext(result));
}
if (kasp && (result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND)) {
if (kasp != NULL &&
(result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND)) {
ttl = dns_kasp_dnskeyttl(kasp);
result = dns_keymgr_run(&zone->origin, zone->rdclass, dir, mctx,
&keys, kasp, now, &nexttime);
if (result != ISC_R_SUCCESS) {
@ -19444,6 +19450,10 @@ zone_rekey(dns_zone_t *zone) {
}
}
if (kasp != NULL) {
UNLOCK(&kasp->lock);
}
if (result == ISC_R_SUCCESS) {
result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
&zone->origin, ttl, &diff, mctx,