mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
[9.18] fix: usr: Update key lifetime and metadata after dnssec-policy reconfig
Adjust key state and timing metadata if dnssec-policy key lifetime configuration is updated, so that it also affects existing keys. Closes #4677 Backport of MR !9118 Merge branch 'backport-4677-dnssec-policy-key-lifetime-reconfigure-9.18' into 'bind-9.18' See merge request isc-projects/bind9!9192
This commit is contained in:
commit
2107a64ee6
6 changed files with 190 additions and 37 deletions
|
|
@ -89,15 +89,37 @@ zone "step1.csk-algorithm-roll.kasp" {
|
|||
dnssec-policy "csk-algoroll";
|
||||
};
|
||||
|
||||
dnssec-policy "modified" {
|
||||
keys {
|
||||
csk lifetime unlimited algorithm rsasha256 2048;
|
||||
};
|
||||
};
|
||||
|
||||
zone example {
|
||||
type primary;
|
||||
file "example.db";
|
||||
inline-signing yes;
|
||||
dnssec-policy modified;
|
||||
};
|
||||
|
||||
zone longer-lifetime {
|
||||
type primary;
|
||||
file "longer-lifetime.db";
|
||||
inline-signing yes;
|
||||
dnssec-policy short-lifetime;
|
||||
};
|
||||
|
||||
zone shorter-lifetime {
|
||||
type primary;
|
||||
file "shorter-lifetime.db";
|
||||
inline-signing yes;
|
||||
dnssec-policy long-lifetime;
|
||||
};
|
||||
|
||||
zone limit-lifetime {
|
||||
type primary;
|
||||
file "limit-lifetime.db";
|
||||
inline-signing yes;
|
||||
dnssec-policy unlimited-lifetime;
|
||||
};
|
||||
|
||||
zone unlimit-lifetime {
|
||||
type primary;
|
||||
file "unlimit-lifetime.db";
|
||||
inline-signing yes;
|
||||
dnssec-policy short-lifetime;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -177,15 +177,37 @@ zone "step6.csk-algorithm-roll.kasp" {
|
|||
dnssec-policy "csk-algoroll";
|
||||
};
|
||||
|
||||
dnssec-policy "modified" {
|
||||
keys {
|
||||
csk lifetime unlimited algorithm rsasha256 2048;
|
||||
};
|
||||
};
|
||||
|
||||
zone example {
|
||||
type primary;
|
||||
file "example.db";
|
||||
inline-signing yes;
|
||||
dnssec-policy modified;
|
||||
};
|
||||
|
||||
zone longer-lifetime {
|
||||
type primary;
|
||||
file "longer-lifetime.db";
|
||||
inline-signing yes;
|
||||
dnssec-policy long-lifetime;
|
||||
};
|
||||
|
||||
zone shorter-lifetime {
|
||||
type primary;
|
||||
file "shorter-lifetime.db";
|
||||
inline-signing yes;
|
||||
dnssec-policy short-lifetime;
|
||||
};
|
||||
|
||||
zone limit-lifetime {
|
||||
type primary;
|
||||
file "limit-lifetime.db";
|
||||
inline-signing yes;
|
||||
dnssec-policy short-lifetime;
|
||||
};
|
||||
|
||||
zone unlimit-lifetime {
|
||||
type primary;
|
||||
file "unlimit-lifetime.db";
|
||||
inline-signing yes;
|
||||
dnssec-policy unlimited-lifetime;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -24,6 +24,29 @@ dnssec-policy "nsec3" {
|
|||
nsec3param iterations 0 optout no salt-length 0;
|
||||
};
|
||||
|
||||
dnssec-policy "modified" {
|
||||
keys {
|
||||
csk lifetime unlimited algorithm rsasha256 2048;
|
||||
};
|
||||
};
|
||||
|
||||
dnssec-policy "unlimited-lifetime" {
|
||||
keys {
|
||||
csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
|
||||
};
|
||||
};
|
||||
dnssec-policy "short-lifetime" {
|
||||
keys {
|
||||
csk lifetime P6M algorithm @DEFAULT_ALGORITHM@;
|
||||
};
|
||||
};
|
||||
|
||||
dnssec-policy "long-lifetime" {
|
||||
keys {
|
||||
csk lifetime P1Y algorithm @DEFAULT_ALGORITHM@;
|
||||
};
|
||||
};
|
||||
|
||||
dnssec-policy "rsasha256" {
|
||||
signatures-refresh P5D;
|
||||
signatures-validity 30d;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ R="RUMOURED"
|
|||
O="OMNIPRESENT"
|
||||
U="UNRETENTIVE"
|
||||
|
||||
for zn in shorter-lifetime longer-lifetime limit-lifetime unlimit-lifetime; do
|
||||
setup $zn
|
||||
cp template.db.in $zonefile
|
||||
done
|
||||
|
||||
# The child zones (step1, step2) beneath these zones represent the various
|
||||
# steps of unsigning a zone.
|
||||
for zn in going-insecure.kasp going-insecure-dynamic.kasp; do
|
||||
|
|
|
|||
|
|
@ -2153,9 +2153,6 @@ active=$(key_get KEY1 ACTIVE)
|
|||
set_addkeytime "KEY1" "RETIRED" "${active}" 15552000
|
||||
retired=$(key_get KEY1 RETIRED)
|
||||
rndc_rollover "$SERVER" "$DIR" $(key_get KEY1 ID) "${retired}" "$ZONE"
|
||||
# Rollover starts in six months, but lifetime is set to six months plus
|
||||
# prepublication duration = 15552000 + 7500 = 15559500 seconds.
|
||||
set_keylifetime "KEY1" "15559500"
|
||||
set_addkeytime "KEY1" "RETIRED" "${active}" 15559500
|
||||
retired=$(key_get KEY1 RETIRED)
|
||||
# Retire interval of this policy is 26h (93600 seconds).
|
||||
|
|
@ -2171,9 +2168,6 @@ dnssec_verify
|
|||
# Schedule KSK rollover now.
|
||||
set_policy "manual-rollover" "3" "3600"
|
||||
set_keystate "KEY1" "GOAL" "hidden"
|
||||
# This key was activated one day ago, so lifetime is set to 1d plus
|
||||
# prepublication duration (7500 seconds) = 93900 seconds.
|
||||
set_keylifetime "KEY1" "93900"
|
||||
created=$(key_get KEY1 CREATED)
|
||||
set_keytime "KEY1" "RETIRED" "${created}"
|
||||
rndc_rollover "$SERVER" "$DIR" $(key_get KEY1 ID) "${created}" "$ZONE"
|
||||
|
|
@ -2198,9 +2192,6 @@ dnssec_verify
|
|||
# Schedule ZSK rollover now.
|
||||
set_policy "manual-rollover" "4" "3600"
|
||||
set_keystate "KEY2" "GOAL" "hidden"
|
||||
# This key was activated one day ago, so lifetime is set to 1d plus
|
||||
# prepublication duration (7500 seconds) = 93900 seconds.
|
||||
set_keylifetime "KEY2" "93900"
|
||||
created=$(key_get KEY2 CREATED)
|
||||
set_keytime "KEY2" "RETIRED" "${created}"
|
||||
rndc_rollover "$SERVER" "$DIR" $(key_get KEY2 ID) "${created}" "$ZONE"
|
||||
|
|
@ -3655,9 +3646,6 @@ check_apex
|
|||
check_subdomain
|
||||
dnssec_verify
|
||||
# Roll over KEY2.
|
||||
# Set expected key lifetime, which is DNSKEY TTL plus the zone propagation delay,
|
||||
# plus the publish-safety: 7200s + 1h + 1d = 97200 seconds.
|
||||
set_keylifetime "KEY2" "97200"
|
||||
created=$(key_get KEY2 CREATED)
|
||||
rndc_rollover "$SERVER" "$DIR" $(key_get KEY2 ID) "${created}" "$ZONE"
|
||||
# Update expected number of keys and key states.
|
||||
|
|
@ -3709,6 +3697,65 @@ check_apex
|
|||
check_subdomain
|
||||
dnssec_verify
|
||||
|
||||
# Test key lifetime changes
|
||||
set_keytimes_lifetime_update() {
|
||||
if [ $1 -eq 0 ]; then
|
||||
set_keytime "KEY1" "RETIRED" "none"
|
||||
set_keytime "KEY1" "REMOVED" "none"
|
||||
else
|
||||
active=$(key_get KEY1 ACTIVE)
|
||||
set_addkeytime "KEY1" "RETIRED" "${active}" $1
|
||||
# The key is removed after the retire time plus max-zone-ttl (1d),
|
||||
# sign delay (9d), zone propagation delay (5m), retire safety (1h) =
|
||||
# 777600 + 86400 + 300 + 3600 = 867900
|
||||
retired=$(key_get KEY1 RETIRED)
|
||||
set_addkeytime "KEY1" "REMOVED" "${retired}" 867900
|
||||
fi
|
||||
}
|
||||
|
||||
check_key_lifetime() {
|
||||
zone=$1
|
||||
policy=$2
|
||||
lifetime=$3
|
||||
|
||||
set_zone "$zone"
|
||||
set_policy "$policy" "1" "3600"
|
||||
set_server "ns6" "10.53.0.6"
|
||||
# Key properties.
|
||||
key_clear "KEY1"
|
||||
set_keyrole "KEY1" "csk"
|
||||
set_keylifetime "KEY1" "$lifetime"
|
||||
set_keyalgorithm "KEY1" "13" "ECDSAP256SHA256" "256"
|
||||
set_keysigning "KEY1" "yes"
|
||||
set_zonesigning "KEY1" "yes"
|
||||
key_clear "KEY2"
|
||||
key_clear "KEY3"
|
||||
key_clear "KEY4"
|
||||
|
||||
# The CSK is rumoured.
|
||||
set_keystate "KEY1" "GOAL" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_DNSKEY" "rumoured"
|
||||
set_keystate "KEY1" "STATE_KRRSIG" "rumoured"
|
||||
set_keystate "KEY1" "STATE_ZRRSIG" "rumoured"
|
||||
set_keystate "KEY1" "STATE_DS" "hidden"
|
||||
check_keys
|
||||
|
||||
# Key timings.
|
||||
set_keytimes_csk_policy
|
||||
set_keytimes_lifetime_update $lifetime
|
||||
|
||||
# Variuous checks.
|
||||
check_keytimes
|
||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
||||
check_apex
|
||||
check_subdomain
|
||||
dnssec_verify
|
||||
}
|
||||
check_key_lifetime "shorter-lifetime" "long-lifetime" "31536000"
|
||||
check_key_lifetime "longer-lifetime" "short-lifetime" "16070400"
|
||||
check_key_lifetime "limit-lifetime" "unlimited-lifetime" "0"
|
||||
check_key_lifetime "unlimit-lifetime" "short-lifetime" "16070400"
|
||||
|
||||
#
|
||||
# Testing algorithm rollover.
|
||||
#
|
||||
|
|
@ -4004,6 +4051,12 @@ check_apex
|
|||
check_subdomain
|
||||
dnssec_verify
|
||||
|
||||
# Test key lifetime updates.
|
||||
check_key_lifetime "shorter-lifetime" "short-lifetime" "16070400"
|
||||
check_key_lifetime "longer-lifetime" "long-lifetime" "31536000"
|
||||
check_key_lifetime "limit-lifetime" "short-lifetime" "16070400"
|
||||
check_key_lifetime "unlimit-lifetime" "unlimited-lifetime" "0"
|
||||
|
||||
#
|
||||
# Testing going insecure.
|
||||
#
|
||||
|
|
|
|||
|
|
@ -413,6 +413,41 @@ keymgr_dnsseckey_kaspkey_match(dns_dnsseckey_t *dkey, dns_kasp_key_t *kkey) {
|
|||
return (true);
|
||||
}
|
||||
|
||||
/* Update lifetime and retire and remove time accordingly. */
|
||||
static void
|
||||
keymgr_key_update_lifetime(dns_dnsseckey_t *key, dns_kasp_t *kasp,
|
||||
isc_stdtime_t now, uint32_t lifetime) {
|
||||
uint32_t l;
|
||||
dst_key_state_t g = HIDDEN;
|
||||
isc_result_t r;
|
||||
|
||||
(void)dst_key_getstate(key->key, DST_KEY_GOAL, &g);
|
||||
r = dst_key_getnum(key->key, DST_NUM_LIFETIME, &l);
|
||||
/* Initialize lifetime. */
|
||||
if (r != ISC_R_SUCCESS) {
|
||||
dst_key_setnum(key->key, DST_NUM_LIFETIME, lifetime);
|
||||
return;
|
||||
}
|
||||
/* Skip keys that are still hidden or already retiring. */
|
||||
if (g != OMNIPRESENT) {
|
||||
return;
|
||||
}
|
||||
/* Update lifetime and timing metadata. */
|
||||
if (l != lifetime) {
|
||||
dst_key_setnum(key->key, DST_NUM_LIFETIME, lifetime);
|
||||
if (lifetime > 0) {
|
||||
uint32_t a = now;
|
||||
(void)dst_key_gettime(key->key, DST_TIME_ACTIVATE, &a);
|
||||
dst_key_settime(key->key, DST_TIME_INACTIVE,
|
||||
(a + lifetime));
|
||||
keymgr_settime_remove(key, kasp);
|
||||
} else {
|
||||
dst_key_unsettime(key->key, DST_TIME_INACTIVE);
|
||||
dst_key_unsettime(key->key, DST_TIME_DELETE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
keymgr_keyid_conflict(dst_key_t *newkey, dns_dnsseckeylist_t *keys) {
|
||||
uint16_t id = dst_key_id(newkey);
|
||||
|
|
@ -2122,15 +2157,9 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass,
|
|||
keystr, keymgr_keyrole(dkey->key),
|
||||
dns_kasp_getname(kasp));
|
||||
|
||||
/* Initialize lifetime if not set. */
|
||||
uint32_t l;
|
||||
if (dst_key_getnum(dkey->key, DST_NUM_LIFETIME,
|
||||
&l) != ISC_R_SUCCESS)
|
||||
{
|
||||
dst_key_setnum(dkey->key,
|
||||
DST_NUM_LIFETIME,
|
||||
lifetime);
|
||||
}
|
||||
/* Update lifetime if changed. */
|
||||
keymgr_key_update_lifetime(dkey, kasp, now,
|
||||
lifetime);
|
||||
|
||||
if (active_key) {
|
||||
/* We already have an active key that
|
||||
|
|
@ -2448,8 +2477,6 @@ rollover_status(dns_dnsseckey_t *dkey, dns_kasp_t *kasp, isc_stdtime_t now,
|
|||
}
|
||||
} else {
|
||||
isc_stdtime_t retire_time = 0;
|
||||
uint32_t lifetime = 0;
|
||||
(void)dst_key_getnum(key, DST_NUM_LIFETIME, &lifetime);
|
||||
ret = dst_key_gettime(key, retire, &retire_time);
|
||||
if (ret == ISC_R_SUCCESS) {
|
||||
if (now < retire_time) {
|
||||
|
|
@ -2458,7 +2485,9 @@ rollover_status(dns_dnsseckey_t *dkey, dns_kasp_t *kasp, isc_stdtime_t now,
|
|||
" Next rollover "
|
||||
"scheduled on ");
|
||||
retire_time = keymgr_prepublication_time(
|
||||
dkey, kasp, lifetime, now);
|
||||
dkey, kasp,
|
||||
(retire_time - active_time),
|
||||
now);
|
||||
} else {
|
||||
isc_buffer_printf(
|
||||
buf, " Key will retire on ");
|
||||
|
|
@ -2636,7 +2665,6 @@ dns_keymgr_rollover(dns_kasp_t *kasp, dns_dnsseckeylist_t *keyring,
|
|||
retire = when + prepub;
|
||||
|
||||
dst_key_settime(key->key, DST_TIME_INACTIVE, retire);
|
||||
dst_key_setnum(key->key, DST_NUM_LIFETIME, (retire - active));
|
||||
|
||||
/* Store key state and update hints. */
|
||||
isc_dir_init(&dir);
|
||||
|
|
|
|||
Loading…
Reference in a new issue