mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-11 04:40:00 -04:00
Convert the 'three is a crowd' test case to pytest
This test shows similarities with the Double KSK rollover method, so put the test in there.
This commit is contained in:
parent
9ff7609614
commit
46800e407e
7 changed files with 117 additions and 154 deletions
|
|
@ -237,17 +237,6 @@ zone "max-zone-ttl.kasp" {
|
|||
dnssec-policy "ttl";
|
||||
};
|
||||
|
||||
/*
|
||||
* Zone for testing GL #2375: Three is a crowd.
|
||||
*/
|
||||
zone "three-is-a-crowd.kasp" {
|
||||
type primary;
|
||||
file "three-is-a-crowd.kasp.db";
|
||||
inline-signing yes;
|
||||
/* Use same policy as KSK rollover test zones. */
|
||||
dnssec-policy "ksk-doubleksk";
|
||||
};
|
||||
|
||||
/*
|
||||
* Zones in different signing states.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -25,30 +25,6 @@ dnssec-policy "autosign" {
|
|||
};
|
||||
};
|
||||
|
||||
dnssec-policy "ksk-doubleksk" {
|
||||
|
||||
signatures-refresh P1W;
|
||||
signatures-validity P2W;
|
||||
signatures-validity-dnskey P2W;
|
||||
|
||||
dnskey-ttl 2h;
|
||||
publish-safety P1D;
|
||||
retire-safety P2D;
|
||||
purge-keys PT1H;
|
||||
|
||||
cdnskey no;
|
||||
keys {
|
||||
ksk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@;
|
||||
zsk key-directory lifetime P1Y algorithm @DEFAULT_ALGORITHM@;
|
||||
};
|
||||
|
||||
zone-propagation-delay PT1H;
|
||||
max-zone-ttl 1d;
|
||||
|
||||
parent-ds-ttl 3600;
|
||||
parent-propagation-delay PT1H;
|
||||
};
|
||||
|
||||
dnssec-policy "csk-roll" {
|
||||
|
||||
signatures-refresh P5D;
|
||||
|
|
|
|||
|
|
@ -835,44 +835,3 @@ private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile"
|
|||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile"
|
||||
cp $infile $zonefile
|
||||
$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
|
||||
|
||||
# Test #2375, the "three is a crowd" bug, where a new key is introduced but the
|
||||
# previous rollover has not finished yet. In other words, we have a key KEY2
|
||||
# that is the successor of key KEY1, and we introduce a new key KEY3 that is
|
||||
# the successor of key KEY2:
|
||||
#
|
||||
# KEY1 < KEY2 < KEY3.
|
||||
#
|
||||
# The expected behavior is that all three keys remain in the zone, and not
|
||||
# the bug behavior where KEY2 is removed and immediately replaced with KEY3.
|
||||
#
|
||||
# Set up a zone that has a KSK (KEY1) and have the successor key (KEY2)
|
||||
# published as well.
|
||||
setup three-is-a-crowd.kasp
|
||||
# These times are the same as step3.ksk-doubleksk.autosign.
|
||||
TactN="now-60d"
|
||||
TretN="now"
|
||||
TremN="now+50h"
|
||||
TpubN1="now-27h"
|
||||
TsbmN1="now"
|
||||
TactN1="${TretN}"
|
||||
TretN1="now+60d"
|
||||
TremN1="now+1490h"
|
||||
ksktimes="-P ${TactN} -A ${TactN} -P sync ${TactN} -I ${TretN} -D ${TremN}"
|
||||
newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TsbmN1} -I ${TretN1} -D ${TremN1}"
|
||||
zsktimes="-P ${TactN} -A ${TactN}"
|
||||
KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
||||
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
|
||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
|
||||
$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.2 2>&1
|
||||
$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
|
||||
# Set key rollover relationship.
|
||||
key_successor $KSK1 $KSK2
|
||||
# Sign zone.
|
||||
cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
|
||||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
|
||||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
|
||||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
|
||||
cp $infile $zonefile
|
||||
$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
|
||||
|
|
|
|||
|
|
@ -939,82 +939,6 @@ check_apex
|
|||
check_subdomain
|
||||
dnssec_verify
|
||||
|
||||
#
|
||||
# Test #2375: Scheduled rollovers are happening faster than they can finish
|
||||
#
|
||||
set_zone "three-is-a-crowd.kasp"
|
||||
set_policy "ksk-doubleksk" "3" "7200"
|
||||
set_server "ns3" "10.53.0.3"
|
||||
CDNSKEY="no"
|
||||
# These are the same time values as calculated for ksk-doubleksk.
|
||||
Lksk=5184000
|
||||
Lzsk=31536000
|
||||
IretKSK=180000
|
||||
IretZSK=867600
|
||||
# KSK (KEY1) is outgoing.
|
||||
key_clear "KEY1"
|
||||
set_keyrole "KEY1" "ksk"
|
||||
set_keylifetime "KEY1" "${Lksk}"
|
||||
set_keyalgorithm "KEY1" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
||||
set_keysigning "KEY1" "yes"
|
||||
set_zonesigning "KEY1" "yes"
|
||||
set_keystate "KEY1" "GOAL" "hidden"
|
||||
set_keystate "KEY1" "STATE_DNSKEY" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_KRRSIG" "omnipresent"
|
||||
set_keystate "KEY1" "STATE_DS" "unretentive"
|
||||
# KSK (KEY2) is incoming.
|
||||
key_clear "KEY2"
|
||||
set_keyrole "KEY2" "ksk"
|
||||
set_keylifetime "KEY2" "${Lksk}"
|
||||
set_keyalgorithm "KEY2" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
||||
set_keysigning "KEY2" "yes"
|
||||
set_zonesigning "KEY2" "no"
|
||||
set_keystate "KEY2" "GOAL" "omnipresent"
|
||||
set_keystate "KEY2" "STATE_DNSKEY" "omnipresent"
|
||||
set_keystate "KEY2" "STATE_KRRSIG" "omnipresent"
|
||||
set_keystate "KEY2" "STATE_DS" "rumoured"
|
||||
# We will introduce the third KSK shortly.
|
||||
key_clear "KEY3"
|
||||
# ZSK (KEY4).
|
||||
key_clear "KEY4"
|
||||
set_keyrole "KEY4" "zsk"
|
||||
set_keylifetime "KEY4" "${Lzsk}"
|
||||
set_keyalgorithm "KEY4" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
||||
set_keysigning "KEY4" "no"
|
||||
set_zonesigning "KEY4" "yes"
|
||||
set_keystate "KEY4" "GOAL" "omnipresent"
|
||||
set_keystate "KEY4" "STATE_DNSKEY" "omnipresent"
|
||||
set_keystate "KEY4" "STATE_ZRRSIG" "omnipresent"
|
||||
# Run preliminary tests.
|
||||
check_keys
|
||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
||||
check_apex
|
||||
check_subdomain
|
||||
dnssec_verify
|
||||
# Roll over KEY2.
|
||||
created=$(key_get KEY2 CREATED)
|
||||
rndc_rollover "$SERVER" "$DIR" $(key_get KEY2 ID) "${created}" "$ZONE"
|
||||
# Update expected number of keys and key states.
|
||||
set_keystate "KEY2" "GOAL" "hidden"
|
||||
set_policy "ksk-doubleksk" "4" "7200"
|
||||
CDNSKEY="no"
|
||||
# New KSK (KEY3) is introduced.
|
||||
set_keyrole "KEY3" "ksk"
|
||||
set_keylifetime "KEY3" "${Lksk}"
|
||||
set_keyalgorithm "KEY3" "$DEFAULT_ALGORITHM_NUMBER" "$DEFAULT_ALGORITHM" "$DEFAULT_BITS"
|
||||
set_keysigning "KEY3" "yes"
|
||||
set_zonesigning "KEY3" "no"
|
||||
set_keystate "KEY3" "GOAL" "omnipresent"
|
||||
set_keystate "KEY3" "STATE_DNSKEY" "rumoured"
|
||||
set_keystate "KEY3" "STATE_KRRSIG" "rumoured"
|
||||
set_keystate "KEY3" "STATE_DS" "hidden"
|
||||
# Run tests again. We now expect four keys (3x KSK, 1x ZSK).
|
||||
check_keys
|
||||
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
|
||||
check_apex
|
||||
check_subdomain
|
||||
dnssec_verify
|
||||
|
||||
# Test dynamic zones that switch to inline-signing.
|
||||
set_zone "dynamic2inline.kasp"
|
||||
set_policy "default" "1" "3600"
|
||||
|
|
|
|||
|
|
@ -159,3 +159,14 @@ zone "step6.ksk-doubleksk.autosign" {
|
|||
file "step6.ksk-doubleksk.autosign.db";
|
||||
dnssec-policy "ksk-doubleksk";
|
||||
};
|
||||
|
||||
/*
|
||||
* Zone for testing GL #2375: Three is a crowd.
|
||||
*/
|
||||
zone "three-is-a-crowd.kasp" {
|
||||
type primary;
|
||||
file "three-is-a-crowd.kasp.db";
|
||||
inline-signing yes;
|
||||
/* Use same policy as KSK rollover test zones. */
|
||||
dnssec-policy "ksk-doubleksk";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -516,3 +516,45 @@ private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
|
|||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
|
||||
cp $infile $zonefile
|
||||
$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
|
||||
|
||||
# Test #2375, the "three is a crowd" bug, where a new key is introduced but the
|
||||
# previous rollover has not finished yet. In other words, we have a key KEY2
|
||||
# that is the successor of key KEY1, and we introduce a new key KEY3 that is
|
||||
# the successor of key KEY2:
|
||||
#
|
||||
# KEY1 < KEY2 < KEY3.
|
||||
#
|
||||
# The expected behavior is that all three keys remain in the zone, and not
|
||||
# the bug behavior where KEY2 is removed and immediately replaced with KEY3.
|
||||
#
|
||||
# Set up a zone that has a KSK (KEY1) and have the successor key (KEY2)
|
||||
# published as well.
|
||||
setup three-is-a-crowd.kasp
|
||||
# These times are the same as step3.ksk-doubleksk.autosign.
|
||||
TpubN="now-60d"
|
||||
TactN="now-1413h"
|
||||
TretN="now"
|
||||
TremN="now+50h"
|
||||
TpubN1="now-27h"
|
||||
TsbmN1="now"
|
||||
TactN1="${TretN}"
|
||||
TretN1="now+60d"
|
||||
TremN1="now+1490h"
|
||||
ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}"
|
||||
newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TsbmN1} -I ${TretN1} -D ${TremN1}"
|
||||
zsktimes="-P ${TpubN} -A ${TpubN}"
|
||||
KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1)
|
||||
KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2)
|
||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3)
|
||||
$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1
|
||||
$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.2 2>&1
|
||||
$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1
|
||||
# Set key rollover relationship.
|
||||
key_successor $KSK1 $KSK2
|
||||
# Sign zone.
|
||||
cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile"
|
||||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile"
|
||||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile"
|
||||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
|
||||
cp $infile $zonefile
|
||||
$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
|
||||
|
|
|
|||
|
|
@ -388,7 +388,7 @@ def check_rollover_step(server, config, policy, step):
|
|||
zone = step["zone"]
|
||||
keyprops = step["keyprops"]
|
||||
nextev = step["nextev"]
|
||||
cdss = []
|
||||
cdss = None
|
||||
if step.get("cdss"):
|
||||
cdss = step["cdss"]
|
||||
keyrelationships = None
|
||||
|
|
@ -445,7 +445,7 @@ def check_rollover_step(server, config, policy, step):
|
|||
|
||||
isctest.kasp.check_keytimes(keys, expected)
|
||||
isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy)
|
||||
isctest.kasp.check_apex(server, zone, ksks, zsks)
|
||||
isctest.kasp.check_apex(server, zone, ksks, zsks, cdss=cdss)
|
||||
isctest.kasp.check_subdomain(server, zone, ksks, zsks, smooth=smooth)
|
||||
isctest.kasp.check_dnssec_verify(server, zone)
|
||||
|
||||
|
|
@ -831,3 +831,65 @@ def test_rollover_ksk_doubleksk(servers):
|
|||
|
||||
for step in steps:
|
||||
check_rollover_step(server, config, policy, step)
|
||||
|
||||
# Test #2375: Scheduled rollovers are happening faster than they can finish.
|
||||
zone = "three-is-a-crowd.kasp"
|
||||
isctest.log.info(
|
||||
"check that fast rollovers do not remove dependent keys from zone (#2375)"
|
||||
)
|
||||
offset1 = -int(timedelta(days=60).total_seconds())
|
||||
offset2 = -int(timedelta(hours=27).total_seconds())
|
||||
keyprops = [
|
||||
f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offset1}",
|
||||
f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{offset2}",
|
||||
f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offset1}",
|
||||
]
|
||||
expected = isctest.kasp.policy_to_properties(ttl, keyprops)
|
||||
keys = isctest.kasp.keydir_to_keylist(zone, server.identifier)
|
||||
ksks = [k for k in keys if k.is_ksk()]
|
||||
zsks = [k for k in keys if not k.is_ksk()]
|
||||
isctest.kasp.check_keys(zone, keys, expected)
|
||||
expected[0].metadata["Successor"] = expected[1].key.tag
|
||||
expected[1].metadata["Predecessor"] = expected[0].key.tag
|
||||
isctest.kasp.check_keyrelationships(keys, expected)
|
||||
for kp in expected:
|
||||
kp.set_expected_keytimes(config, offset=None)
|
||||
isctest.kasp.check_keytimes(keys, expected)
|
||||
isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy)
|
||||
isctest.kasp.check_apex(server, zone, ksks, zsks, cdss=cdss)
|
||||
isctest.kasp.check_subdomain(server, zone, ksks, zsks)
|
||||
isctest.kasp.check_dnssec_verify(server, zone)
|
||||
# Rollover successor KSK (with DS in rumoured state).
|
||||
key = expected[1].key
|
||||
now = KeyTimingMetadata.now()
|
||||
with server.watch_log_from_here() as watcher:
|
||||
server.rndc(f"dnssec -rollover -key {key.tag} -when {now} {zone}")
|
||||
watcher.wait_for_line(f"keymgr: {zone} done")
|
||||
# We now expect four keys (3x KSK, 1x ZSK).
|
||||
keyprops = [
|
||||
f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offset1}",
|
||||
f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{offset2}",
|
||||
f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden offset:0",
|
||||
f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offset1}",
|
||||
]
|
||||
expected = isctest.kasp.policy_to_properties(ttl, keyprops)
|
||||
keys = isctest.kasp.keydir_to_keylist(zone, server.identifier)
|
||||
ksks = [k for k in keys if k.is_ksk()]
|
||||
zsks = [k for k in keys if not k.is_ksk()]
|
||||
isctest.kasp.check_keys(zone, keys, expected)
|
||||
expected[0].metadata["Successor"] = expected[1].key.tag
|
||||
expected[1].metadata["Predecessor"] = expected[0].key.tag
|
||||
# Three is a crowd scenario.
|
||||
expected[1].metadata["Successor"] = expected[2].key.tag
|
||||
expected[2].metadata["Predecessor"] = expected[1].key.tag
|
||||
isctest.kasp.check_keyrelationships(keys, expected)
|
||||
for kp in expected:
|
||||
kp.set_expected_keytimes(config, offset=None)
|
||||
# The first successor KSK is already being retired.
|
||||
expected[1].timing["Retired"] = now + ipub
|
||||
expected[1].timing["Removed"] = now + ipub + iret
|
||||
isctest.kasp.check_keytimes(keys, expected)
|
||||
isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy)
|
||||
isctest.kasp.check_apex(server, zone, ksks, zsks, cdss=cdss)
|
||||
isctest.kasp.check_subdomain(server, zone, ksks, zsks)
|
||||
isctest.kasp.check_dnssec_verify(server, zone)
|
||||
|
|
|
|||
Loading…
Reference in a new issue