]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
rollover-going-insecure: From setup.sh to pytest bootstrap
authorMatthijs Mekking <matthijs@isc.org>
Fri, 28 Nov 2025 09:43:42 +0000 (10:43 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Fri, 19 Dec 2025 10:47:50 +0000 (11:47 +0100)
Symlink ns1 and ns2 to rollover/ns1 and rollover/ns2.
Symlink ns3/template.db.j2.manual to rollover/ns3/template.db.j2.manual.

Since the bootstrapping is done before the templates are rendered
automatically, replace @DEFAULT_ALGORITHM@ in ns3/kasp.conf.j2 to
ecdsa256 and rename to ns3/kasp.conf.

Now we have to fake different lifetimes, so adjust fake_lifetime
to update a single key.

Note that we have changed the setup slightly: We also sign the
step2 zones, but with post validation disabled. This is more
accurate because we need to test that the public keys and signatures
are being removed from the zone.

bin/tests/system/rollover-going-insecure/ns1 [new symlink]
bin/tests/system/rollover-going-insecure/ns2 [new symlink]
bin/tests/system/rollover-going-insecure/ns3/kasp.conf [moved from bin/tests/system/rollover-going-insecure/ns3/kasp.conf.j2 with 78% similarity]
bin/tests/system/rollover-going-insecure/ns3/template.db.in [deleted symlink]
bin/tests/system/rollover-going-insecure/ns3/template.db.j2.manual [new symlink]
bin/tests/system/rollover-going-insecure/ns3/trusted.conf.j2 [new symlink]
bin/tests/system/rollover-going-insecure/setup.sh [deleted file]
bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py
bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py
bin/tests/system/rollover/setup.py

diff --git a/bin/tests/system/rollover-going-insecure/ns1 b/bin/tests/system/rollover-going-insecure/ns1
new file mode 120000 (symlink)
index 0000000..76608be
--- /dev/null
@@ -0,0 +1 @@
+../rollover/ns1
\ No newline at end of file
diff --git a/bin/tests/system/rollover-going-insecure/ns2 b/bin/tests/system/rollover-going-insecure/ns2
new file mode 120000 (symlink)
index 0000000..41a09bb
--- /dev/null
@@ -0,0 +1 @@
+../rollover/ns2
\ No newline at end of file
similarity index 78%
rename from bin/tests/system/rollover-going-insecure/ns3/kasp.conf.j2
rename to bin/tests/system/rollover-going-insecure/ns3/kasp.conf
index 70a4323c7e28945053044bf85c1387408d5bbb59..f04b692194006efd5582c614c1a9c6efb5bbecfd 100644 (file)
@@ -15,7 +15,7 @@ dnssec-policy "unsigning" {
        dnskey-ttl 7200;
 
        keys {
-               ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
-               zsk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@;
+               ksk key-directory lifetime unlimited algorithm ecdsa256;
+               zsk key-directory lifetime P60D algorithm ecdsa256;
        };
 };
diff --git a/bin/tests/system/rollover-going-insecure/ns3/template.db.in b/bin/tests/system/rollover-going-insecure/ns3/template.db.in
deleted file mode 120000 (symlink)
index ce6d526..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../rollover/ns3/template.db.in
\ No newline at end of file
diff --git a/bin/tests/system/rollover-going-insecure/ns3/template.db.j2.manual b/bin/tests/system/rollover-going-insecure/ns3/template.db.j2.manual
new file mode 120000 (symlink)
index 0000000..38619a0
--- /dev/null
@@ -0,0 +1 @@
+../../rollover/ns3/template.db.j2.manual
\ No newline at end of file
diff --git a/bin/tests/system/rollover-going-insecure/ns3/trusted.conf.j2 b/bin/tests/system/rollover-going-insecure/ns3/trusted.conf.j2
new file mode 120000 (symlink)
index 0000000..cb0be77
--- /dev/null
@@ -0,0 +1 @@
+../../_common/trusted.conf.j2
\ No newline at end of file
diff --git a/bin/tests/system/rollover-going-insecure/setup.sh b/bin/tests/system/rollover-going-insecure/setup.sh
deleted file mode 100644 (file)
index 11213c1..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/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"
-}
-
-# Make lines shorter by storing key states in environment variables.
-H="HIDDEN"
-R="RUMOURED"
-O="OMNIPRESENT"
-U="UNRETENTIVE"
-
-# 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
-  # Step 1:
-  # Set up a zone with dnssec-policy that is going insecure.
-  setup step1.$zn
-  echo "$zone" >>zones
-  T="now-10d"
-  S="now-12955mi"
-  keytimes="-P $T -A $T"
-  cdstimes="-P sync $S"
-  KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1)
-  ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2)
-  cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
-  private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
-  private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
-  cp $infile $zonefile
-  $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
-
-  # Step 2:
-  # Set up a zone with dnssec-policy that is going insecure. Don't add
-  # this zone to the zones file, because this zone is no longer expected
-  # to be fully signed.
-  setup step2.$zn
-  # The DS was withdrawn from the parent zone 26 hours ago.
-  D="now-26h"
-  keytimes="-P $T -A $T -I $D -D now"
-  cdstimes="-P sync $S -D sync $D"
-  KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1)
-  ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2)
-  $SETTIME -s -g $H -k $O $T -r $O $T -d $U $D -D ds $D "$KSK" >settime.out.$zone.1 2>&1
-  $SETTIME -s -g $H -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
-  # Fake lifetime of old algorithm keys.
-  echo "Lifetime: 0" >>"${KSK}.state"
-  echo "Lifetime: 5184000" >>"${ZSK}.state"
-  cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile"
-  private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
-  private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
-  cp $infile $zonefile
-done
index 61aa583f554abcc3819af33ffb3b8c8908eeaa74..92950124ed8478694403e55f2e2278c0b2ecb7d3 100644 (file)
@@ -22,6 +22,28 @@ from rollover.common import (
     DURATION,
     UNSIGNING_CONFIG,
 )
+from rollover.setup import (
+    configure_root,
+    configure_tld,
+    configure_going_insecure,
+)
+
+
+def bootstrap():
+    data = {
+        "tlds": [],
+        "trust_anchors": [],
+    }
+
+    tlds = []
+    tld_name = "kasp"
+    delegations = configure_going_insecure(tld_name, reconfig=False)
+    tld = configure_tld(tld_name, delegations)
+    tlds.append(tld)
+    data["tlds"].append(tld_name)
+    ta = configure_root(tlds)
+    data["trust_anchors"].append(ta)
+    return data
 
 
 @pytest.mark.parametrize(
index 9a2d240934b06afbba0136ffca06238c62413047..5cd8d65816784f4df860402d7df71e6ada97dda6 100644 (file)
@@ -23,6 +23,28 @@ from rollover.common import (
     DURATION,
     UNSIGNING_CONFIG,
 )
+from rollover.setup import (
+    configure_root,
+    configure_tld,
+    configure_going_insecure,
+)
+
+
+def bootstrap():
+    data = {
+        "tlds": [],
+        "trust_anchors": [],
+    }
+
+    tlds = []
+    tld_name = "kasp"
+    delegations = configure_going_insecure(tld_name, reconfig=True)
+    tld = configure_tld(tld_name, delegations)
+    tlds.append(tld)
+    data["tlds"].append(tld_name)
+    ta = configure_root(tlds)
+    data["trust_anchors"].append(ta)
+    return data
 
 
 @pytest.fixture(scope="module", autouse=True)
index d4b35be6156ec49479d9258444a6c04dae3e7e96..b3e5b2fa0609abc97bd12419f4749df7754e5b2d 100644 (file)
@@ -94,13 +94,12 @@ def configure_root(delegations: List[Zone]) -> TrustAnchor:
     return ksk.into_ta("static-ds")
 
 
-def fake_lifetime(keys: List[str]):
+def fake_lifetime(key: str, lifetime: int):
     """
-    Fake lifetime of old algorithm keys.
+    Fake lifetime of key.
     """
-    for key in keys:
-        with open(f"ns3/{key}.state", "a") as statefile:
-            statefile.write("Lifetime: 0\n")
+    with open(f"ns3/{key}.state", "a", encoding="utf-8") as statefile:
+        statefile.write(f"Lifetime: {lifetime}\n")
 
 
 def set_key_relationship(key1: str, key2: str):
@@ -363,7 +362,8 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]:
             cwd="ns3",
         )
         # Signing.
-        fake_lifetime([ksk1_name, zsk1_name])
+        fake_lifetime(ksk1_name, 0)
+        fake_lifetime(zsk1_name, 0)
         render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name])
 
         # Step 3:
@@ -404,7 +404,8 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]:
             cwd="ns3",
         )
         # Signing.
-        fake_lifetime([ksk1_name, zsk1_name])
+        fake_lifetime(ksk1_name, 0)
+        fake_lifetime(zsk1_name, 0)
         render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name])
 
         # Step 4:
@@ -445,7 +446,8 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]:
             cwd="ns3",
         )
         # Signing.
-        fake_lifetime([ksk1_name, zsk1_name])
+        fake_lifetime(ksk1_name, 0)
+        fake_lifetime(zsk1_name, 0)
         render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name])
 
         # Step 5:
@@ -486,7 +488,8 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]:
             cwd="ns3",
         )
         # Signing.
-        fake_lifetime([ksk1_name, zsk1_name])
+        fake_lifetime(ksk1_name, 0)
+        fake_lifetime(zsk1_name, 0)
         render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name])
 
         # Step 6:
@@ -526,7 +529,8 @@ def configure_algo_ksk_zsk(tld: str, reconfig: bool = False) -> List[Zone]:
             cwd="ns3",
         )
         # Signing.
-        fake_lifetime([ksk1_name, zsk1_name])
+        fake_lifetime(ksk1_name, 0)
+        fake_lifetime(zsk1_name, 0)
         render_and_sign_zone(zonename, [ksk1_name, zsk1_name, ksk2_name, zsk2_name])
 
     return zones
@@ -1283,3 +1287,69 @@ def configure_enable_dnssec(tld: str, policy: str) -> List[Zone]:
     render_and_sign_zone(zonename, [csk_name], extra_options="-z")
 
     return zones
+
+
+def configure_going_insecure(tld: str, reconfig: bool = False) -> List[Zone]:
+    zones = []
+    keygen = CmdHelper("KEYGEN", "-a ECDSA256 -L 7200")
+    settime = CmdHelper("SETTIME", "-s")
+
+    # The child zones (step1, step2) beneath these zones represent the various
+    # steps of unsigning a zone.
+    for zone in [f"going-insecure.{tld}", f"going-insecure-dynamic.{tld}"]:
+        # Set up a zone with dnssec-policy that is going insecure.
+
+        # Step 1:
+        zonename = f"step1.{zone}"
+        zones.append(Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3")))
+        isctest.log.info(f"setup {zonename}")
+        # Timing metadata.
+        TpubN = "now-10d"
+        TsbmN = "now-12955mi"
+        keytimes = f"-P {TpubN} -A {TpubN}"
+        cdstimes = f"-P sync {TsbmN}"
+        # Key generation.
+        ksk_name = keygen(f"-f KSK {keytimes} {cdstimes} {zonename}", cwd="ns3").strip()
+        zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip()
+        settime(
+            f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -d OMNIPRESENT {TpubN} {ksk_name}",
+            cwd="ns3",
+        )
+        settime(
+            f"-g OMNIPRESENT -k OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} {zsk_name}",
+            cwd="ns3",
+        )
+        # Signing.
+        render_and_sign_zone(zonename, [ksk_name, zsk_name])
+
+        if reconfig:
+            # Step 2:
+            zonename = f"step2.{zone}"
+            zones.append(
+                Zone(zonename, f"{zonename}.db", Nameserver("ns3", "10.53.0.3"))
+            )
+            isctest.log.info(f"setup {zonename}")
+            # The DS was withdrawn from the parent zone 26 hours ago.
+            TremN = "now-26h"
+            keytimes = f"-P {TpubN} -A {TpubN} -I {TremN} -D now"
+            cdstimes = f"-P sync {TsbmN} -D sync {TremN}"
+            # Key generation.
+            ksk_name = keygen(
+                f"-f KSK {keytimes} {cdstimes} {zonename}", cwd="ns3"
+            ).strip()
+            zsk_name = keygen(f"{keytimes} {zonename}", cwd="ns3").strip()
+            settime(
+                f"-g HIDDEN -k OMNIPRESENT {TpubN} -r OMNIPRESENT {TpubN} -d UNRETENTIVE {TremN} -D ds {TremN} {ksk_name}",
+                cwd="ns3",
+            )
+            settime(
+                f"-g HIDDEN -k OMNIPRESENT {TpubN} -z OMNIPRESENT {TpubN} {zsk_name}",
+                cwd="ns3",
+            )
+            # Fake lifetime of old algorithm keys.
+            fake_lifetime(ksk_name, 0)
+            fake_lifetime(zsk_name, 5184000)
+            # Signing.
+            render_and_sign_zone(zonename, [ksk_name, zsk_name], extra_options="-P")
+
+    return zones