Isolate rollover-enable-dnssec test case

(cherry picked from commit e294177312)
This commit is contained in:
Nicki Křížek 2025-06-11 16:26:37 +02:00
parent e90f93fc68
commit 7f6789e300
13 changed files with 281 additions and 192 deletions

View file

@ -162,6 +162,7 @@ TESTS = \
rollover-csk-roll1 \
rollover-csk-roll2 \
rollover-dynamic2inline \
rollover-enable-dnssec \
rollover-going-insecure \
rollover-ksk-3crowd \
rollover-ksk-doubleksk \

View file

@ -0,0 +1 @@
../rollover/common.py

View file

@ -0,0 +1,31 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* 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 https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
dnssec-policy "enable-dnssec" {
signatures-refresh P1W;
signatures-validity P2W;
signatures-validity-dnskey P2W;
dnskey-ttl 300;
max-zone-ttl PT12H;
zone-propagation-delay PT5M;
retire-safety PT20M;
publish-safety PT5M;
parent-propagation-delay 1h;
parent-ds-ttl 2h;
keys {
csk lifetime unlimited algorithm @DEFAULT_ALGORITHM_NUMBER@;
};
};

View file

@ -0,0 +1 @@
../../rollover/ns3/named.common.conf.j2

View file

@ -0,0 +1,36 @@
/*
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
*
* SPDX-License-Identifier: MPL-2.0
*
* 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 https://mozilla.org/MPL/2.0/.
*
* See the COPYRIGHT file distributed with this work for additional
* information regarding copyright ownership.
*/
include "kasp.conf";
include "named.common.conf";
zone "step1.enable-dnssec.autosign" {
type primary;
file "step1.enable-dnssec.autosign.db";
dnssec-policy "enable-dnssec";
};
zone "step2.enable-dnssec.autosign" {
type primary;
file "step2.enable-dnssec.autosign.db";
dnssec-policy "enable-dnssec";
};
zone "step3.enable-dnssec.autosign" {
type primary;
file "step3.enable-dnssec.autosign.db";
dnssec-policy "enable-dnssec";
};
zone "step4.enable-dnssec.autosign" {
type primary;
file "step4.enable-dnssec.autosign.db";
dnssec-policy "enable-dnssec";
};

View file

@ -0,0 +1 @@
../../rollover/ns3/template.db.in

View file

@ -0,0 +1,100 @@
#!/bin/sh -e
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# 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 https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
# shellcheck source=conf.sh
. ../conf.sh
cd "ns3"
setup() {
zone="$1"
echo_i "setting up zone: $zone"
zonefile="${zone}.db"
infile="${zone}.db.infile"
echo "$zone" >>zones
}
# Set in the key state files the Predecessor/Successor fields.
# Key $1 is the predecessor of key $2.
key_successor() {
id1=$(keyfile_to_key_id "$1")
id2=$(keyfile_to_key_id "$2")
echo "Predecessor: ${id1}" >>"${2}.state"
echo "Successor: ${id2}" >>"${1}.state"
}
# Make lines shorter by storing key states in environment variables.
H="HIDDEN"
R="RUMOURED"
O="OMNIPRESENT"
U="UNRETENTIVE"
#
# The zones at enable-dnssec.autosign represent the various steps of the
# initial signing of a zone.
#
# Step 1:
# This is an unsigned zone and named should perform the initial steps of
# introducing the DNSSEC records in the right order.
setup step1.enable-dnssec.autosign
cp template.db.in $zonefile
# Step 2:
# The DNSKEY has been published long enough to become OMNIPRESENT.
setup step2.enable-dnssec.autosign
# DNSKEY TTL: 300 seconds
# zone-propagation-delay: 5 minutes (300 seconds)
# publish-safety: 5 minutes (300 seconds)
# Total: 900 seconds
TpubN="now-900s"
keytimes="-P ${TpubN} -A ${TpubN}"
CSK=$($KEYGEN -k enable-dnssec -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
$SETTIME -s -g $O -k $R $TpubN -r $R $TpubN -d $H $TpubN -z $R $TpubN "$CSK" >settime.out.$zone.1 2>&1
cat template.db.in "${CSK}.key" >"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 3:
# The zone signatures have been published long enough to become OMNIPRESENT.
setup step3.enable-dnssec.autosign
# Passed time since publication:
# max-zone-ttl: 12 hours (43200 seconds)
# zone-propagation-delay: 5 minutes (300 seconds)
TpubN="now-43500s"
# We can submit the DS now.
keytimes="-P ${TpubN} -A ${TpubN}"
CSK=$($KEYGEN -k enable-dnssec -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
$SETTIME -s -g $O -k $O $TpubN -r $O $TpubN -d $H $TpubN -z $R $TpubN "$CSK" >settime.out.$zone.1 2>&1
cat template.db.in "${CSK}.key" >"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 4:
# The DS has been submitted long enough ago to become OMNIPRESENT.
setup step4.enable-dnssec.autosign
# DS TTL: 2 hour (7200 seconds)
# parent-propagation-delay: 1 hour (3600 seconds)
# Total aditional time: 10800 seconds
# 43500 + 10800 = 54300
TpubN="now-54300s"
TsbmN="now-10800s"
keytimes="-P ${TpubN} -A ${TpubN} -P sync ${TsbmN}"
CSK=$($KEYGEN -k enable-dnssec -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
$SETTIME -s -g $O -P ds $TsbmN -k $O $TpubN -r $O $TpubN -d $R $TpubN -z $O $TsbmN "$CSK" >settime.out.$zone.1 2>&1
cat template.db.in "${CSK}.key" >"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1

View file

@ -0,0 +1,109 @@
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# 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 https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
# pylint: disable=redefined-outer-name,unused-import
import isctest
from isctest.kasp import Ipub, IpubC, Iret
from common import (
pytestmark,
alg,
size,
CDSS,
TIMEDELTA,
)
CONFIG = {
"dnskey-ttl": TIMEDELTA["PT5M"],
"ds-ttl": TIMEDELTA["PT2H"],
"max-zone-ttl": TIMEDELTA["PT12H"],
"parent-propagation-delay": TIMEDELTA["PT1H"],
"publish-safety": TIMEDELTA["PT5M"],
"retire-safety": TIMEDELTA["PT20M"],
"signatures-refresh": TIMEDELTA["P7D"],
"signatures-validity": TIMEDELTA["P14D"],
"zone-propagation-delay": TIMEDELTA["PT5M"],
}
POLICY = "enable-dnssec"
IPUB = Ipub(CONFIG)
IPUBC = IpubC(CONFIG, rollover=False)
IRETZSK = Iret(CONFIG, rollover=False)
IRETKSK = Iret(CONFIG, zsk=False, ksk=True, rollover=False)
OFFSETS = {}
OFFSETS["step1"] = 0
OFFSETS["step2"] = -int(IPUB.total_seconds())
OFFSETS["step3"] = -int(IRETZSK.total_seconds())
OFFSETS["step4"] = -int(IPUBC.total_seconds() + IRETKSK.total_seconds())
def test_rollover_enable_dnssec_step1(alg, size, servers):
step = {
"zone": "step1.enable-dnssec.autosign",
"cdss": CDSS,
"keyprops": [
f"csk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden offset:{OFFSETS['step1']}",
],
# Next key event is when the DNSKEY RRset becomes OMNIPRESENT,
# after the publication interval.
"nextev": IPUB,
}
isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
def test_rollover_enable_dnssec_step2(alg, size, servers):
step = {
"zone": "step2.enable-dnssec.autosign",
"cdss": CDSS,
# The DNSKEY is omnipresent, but the zone signatures not yet.
# Thus, the DS remains hidden.
# dnskey: rumoured -> omnipresent
# krrsig: rumoured -> omnipresent
"keyprops": [
f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:hidden offset:{OFFSETS['step2']}",
],
# Next key event is when the zone signatures become OMNIPRESENT,
# Minus the time already elapsed.
"nextev": IRETZSK - IPUB,
}
isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
def test_rollover_enable_dnssec_step3(alg, size, servers):
step = {
"zone": "step3.enable-dnssec.autosign",
"cdss": CDSS,
# All signatures should be omnipresent, so the DS can be submitted.
# zrrsig: rumoured -> omnipresent
# ds: hidden -> rumoured
"keyprops": [
f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:rumoured offset:{OFFSETS['step3']}",
],
# Next key event is when the DS can move to the OMNIPRESENT state.
# This is after the retire interval.
"nextev": IRETKSK,
}
isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)
def test_rollover_enable_dnssec_step4(alg, size, servers):
step = {
"zone": "step4.enable-dnssec.autosign",
"cdss": CDSS,
# DS has been published long enough.
# ds: rumoured -> omnipresent
"keyprops": [
f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step4']}",
],
# Next key event is never, the zone dnssec-policy has been
# established. So we fall back to the default loadkeys interval.
"nextev": TIMEDELTA["PT1H"],
}
isctest.kasp.check_rollover_step(servers["ns3"], CONFIG, POLICY, step)

View file

@ -44,6 +44,7 @@ pytestmark = pytest.mark.extra_artifacts(
TIMEDELTA = {
0: timedelta(seconds=0),
"PT5M": timedelta(minutes=5),
"PT20M": timedelta(minutes=20),
"PT1H": timedelta(hours=1),
"PT2H": timedelta(hours=2),
"PT6H": timedelta(hours=6),

View file

@ -29,22 +29,3 @@ dnssec-policy "multisigner-model2" {
zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535;
};
};
dnssec-policy "enable-dnssec" {
signatures-refresh P1W;
signatures-validity P2W;
signatures-validity-dnskey P2W;
dnskey-ttl 300;
max-zone-ttl PT12H;
zone-propagation-delay PT5M;
retire-safety PT20M;
publish-safety PT5M;
parent-propagation-delay 1h;
parent-ds-ttl 2h;
keys {
csk lifetime unlimited algorithm @DEFAULT_ALGORITHM_NUMBER@;
};
};

View file

@ -42,27 +42,3 @@ zone "single-to-multisigner.kasp" {
dnssec-policy "multisigner-model2";
allow-update { any; };
};
/*
* Zones for testing enabling DNSSEC.
*/
zone "step1.enable-dnssec.autosign" {
type primary;
file "step1.enable-dnssec.autosign.db";
dnssec-policy "enable-dnssec";
};
zone "step2.enable-dnssec.autosign" {
type primary;
file "step2.enable-dnssec.autosign.db";
dnssec-policy "enable-dnssec";
};
zone "step3.enable-dnssec.autosign" {
type primary;
file "step3.enable-dnssec.autosign.db";
dnssec-policy "enable-dnssec";
};
zone "step4.enable-dnssec.autosign" {
type primary;
file "step4.enable-dnssec.autosign.db";
dnssec-policy "enable-dnssec";
};

View file

@ -79,63 +79,3 @@ cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
$SIGNER -PS -z -x -s now-2w -e now-1mi -o $zone -f "${zonefile}" $infile >signer.out.$zone.1 2>&1
echo "Lifetime: 0" >>"${KSK}".state
echo "Lifetime: 0" >>"${ZSK}".state
#
# The zones at enable-dnssec.autosign represent the various steps of the
# initial signing of a zone.
#
# Step 1:
# This is an unsigned zone and named should perform the initial steps of
# introducing the DNSSEC records in the right order.
setup step1.enable-dnssec.autosign
cp template.db.in $zonefile
# Step 2:
# The DNSKEY has been published long enough to become OMNIPRESENT.
setup step2.enable-dnssec.autosign
# DNSKEY TTL: 300 seconds
# zone-propagation-delay: 5 minutes (300 seconds)
# publish-safety: 5 minutes (300 seconds)
# Total: 900 seconds
TpubN="now-900s"
keytimes="-P ${TpubN} -A ${TpubN}"
CSK=$($KEYGEN -k enable-dnssec -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
$SETTIME -s -g $O -k $R $TpubN -r $R $TpubN -d $H $TpubN -z $R $TpubN "$CSK" >settime.out.$zone.1 2>&1
cat template.db.in "${CSK}.key" >"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 3:
# The zone signatures have been published long enough to become OMNIPRESENT.
setup step3.enable-dnssec.autosign
# Passed time since publication:
# max-zone-ttl: 12 hours (43200 seconds)
# zone-propagation-delay: 5 minutes (300 seconds)
TpubN="now-43500s"
# We can submit the DS now.
keytimes="-P ${TpubN} -A ${TpubN}"
CSK=$($KEYGEN -k enable-dnssec -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
$SETTIME -s -g $O -k $O $TpubN -r $O $TpubN -d $H $TpubN -z $R $TpubN "$CSK" >settime.out.$zone.1 2>&1
cat template.db.in "${CSK}.key" >"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
# Step 4:
# The DS has been submitted long enough ago to become OMNIPRESENT.
setup step4.enable-dnssec.autosign
# DS TTL: 2 hour (7200 seconds)
# parent-propagation-delay: 1 hour (3600 seconds)
# Total aditional time: 10800 seconds
# 43500 + 10800 = 54300
TpubN="now-54300s"
TsbmN="now-10800s"
keytimes="-P ${TpubN} -A ${TpubN} -P sync ${TsbmN}"
CSK=$($KEYGEN -k enable-dnssec -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1)
$SETTIME -s -g $O -P ds $TsbmN -k $O $TpubN -r $O $TpubN -d $R $TpubN -z $O $TsbmN "$CSK" >settime.out.$zone.1 2>&1
cat template.db.in "${CSK}.key" >"$infile"
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile"
cp $infile $zonefile
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1

View file

@ -308,92 +308,3 @@ def test_rollover_multisigner(servers):
isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy)
isctest.kasp.check_apex(server, zone, ksks, zsks)
isctest.kasp.check_subdomain(server, zone, ksks, zsks)
def test_rollover_enable_dnssec(servers):
server = servers["ns3"]
policy = "enable-dnssec"
cdss = ["CDNSKEY", "CDS (SHA-256)"]
config = {
"dnskey-ttl": timedelta(seconds=300),
"ds-ttl": timedelta(hours=2),
"max-zone-ttl": timedelta(hours=12),
"parent-propagation-delay": timedelta(hours=1),
"publish-safety": timedelta(minutes=5),
"retire-safety": timedelta(minutes=20),
"signatures-refresh": timedelta(days=7),
"signatures-validity": timedelta(days=14),
"zone-propagation-delay": timedelta(minutes=5),
}
alg = os.environ["DEFAULT_ALGORITHM_NUMBER"]
size = os.environ["DEFAULT_BITS"]
ipub = Ipub(config)
ipubC = IpubC(config, rollover=False)
iretZSK = Iret(config, rollover=False)
iretKSK = Iret(config, zsk=False, ksk=True, rollover=False)
offsets = {
"step1": 0,
"step2": -int(ipub.total_seconds()),
"step3": -int(iretZSK.total_seconds()),
"step4": -int(ipubC.total_seconds() + iretKSK.total_seconds()),
}
steps = [
{
# Step 1.
"zone": "step1.enable-dnssec.autosign",
"cdss": cdss,
"keyprops": [
f"csk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden offset:{offsets['step1']}",
],
# Next key event is when the DNSKEY RRset becomes OMNIPRESENT,
# after the publication interval.
"nextev": ipub,
},
{
# Step 2.
"zone": "step2.enable-dnssec.autosign",
"cdss": cdss,
# The DNSKEY is omnipresent, but the zone signatures not yet.
# Thus, the DS remains hidden.
# dnskey: rumoured -> omnipresent
# krrsig: rumoured -> omnipresent
"keyprops": [
f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:hidden offset:{offsets['step2']}",
],
# Next key event is when the zone signatures become OMNIPRESENT,
# Minus the time already elapsed.
"nextev": iretZSK - ipub,
},
{
# Step 3.
"zone": "step3.enable-dnssec.autosign",
"cdss": cdss,
# All signatures should be omnipresent, so the DS can be submitted.
# zrrsig: rumoured -> omnipresent
# ds: hidden -> rumoured
"keyprops": [
f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:rumoured offset:{offsets['step3']}",
],
# Next key event is when the DS can move to the OMNIPRESENT state.
# This is after the retire interval.
"nextev": iretKSK,
},
{
# Step 4.
"zone": "step4.enable-dnssec.autosign",
"cdss": cdss,
# DS has been published long enough.
# ds: rumoured -> omnipresent
"keyprops": [
f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step4']}",
],
# Next key event is never, the zone dnssec-policy has been
# established. So we fall back to the default loadkeys interval.
"nextev": timedelta(hours=1),
},
]
for step in steps:
isctest.kasp.check_rollover_step(server, config, policy, step)