--- /dev/null
+../rollover/common.py
\ No newline at end of file
--- /dev/null
+/*
+ * 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@;
+ };
+};
--- /dev/null
+../../rollover/ns3/named.common.conf.j2
\ No newline at end of file
--- /dev/null
+/*
+ * 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";
+};
--- /dev/null
+../../rollover/ns3/template.db.in
\ No newline at end of file
--- /dev/null
+#!/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
--- /dev/null
+# 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)
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),
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@;
- };
-};
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";
-};
$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
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)