Commit e0bdff7e authored by Matthijs Mekking's avatar Matthijs Mekking 🏡
Browse files

Fix race condition dnssec-policy with views

When configuring the same dnssec-policy for two zones with the same
name but in different views, there is a race condition for who will
run the keymgr first. If running sequential only one set of keys will
be created, if running parallel two set of keys will be created.

Lock the kasp when running looking for keys and running the key
manager. This way, for the same zone in different views only one
keyset will be created.

The dnssec-policy does not implement sharing keys between different
zones.
parent 59790325
; 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"
; 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"
......@@ -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";
};
};
......@@ -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
......@@ -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=""
......
......@@ -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));
}
......
......@@ -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,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment