2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 06:25:31 +00:00

Convert policy changes tests to pytest

These test cases involve a reconfiguration. The first one is a zone
that changes from dynamic to inline-signing. The others are tests that
key lifetimes are updated correctly after changing them.
This commit is contained in:
Matthijs Mekking
2025-03-19 11:35:18 +01:00
parent 2b7ae5f067
commit de3c0970eb
13 changed files with 463 additions and 193 deletions

View File

@@ -44,14 +44,6 @@ zone "." {
file "../../_common/root.hint.blackhole";
};
/* This zone switch from dynamic to inline-signing. */
zone "dynamic2inline.kasp" {
type primary;
file "dynamic2inline.kasp.db";
allow-update { any; };
dnssec-policy "default";
};
/* These zones are going insecure. */
zone "step1.going-insecure.kasp" {
type primary;
@@ -99,27 +91,3 @@ zone example {
file "example.db";
dnssec-policy modified;
};
zone longer-lifetime {
type primary;
file "longer-lifetime.db";
dnssec-policy short-lifetime;
};
zone shorter-lifetime {
type primary;
file "shorter-lifetime.db";
dnssec-policy long-lifetime;
};
zone limit-lifetime {
type primary;
file "limit-lifetime.db";
dnssec-policy unlimited-lifetime;
};
zone unlimit-lifetime {
type primary;
file "unlimit-lifetime.db";
dnssec-policy short-lifetime;
};

View File

@@ -43,14 +43,6 @@ zone "." {
file "../../_common/root.hint.blackhole";
};
/* This zone switch from dynamic to inline-signing. */
zone "dynamic2inline.kasp" {
type primary;
file "dynamic2inline.kasp.db";
allow-update { any; };
dnssec-policy "default";
};
/* Zones for testing going insecure. */
zone "step1.going-insecure.kasp" {
type primary;
@@ -177,27 +169,3 @@ zone example {
file "example.db";
dnssec-policy modified;
};
zone longer-lifetime {
type primary;
file "longer-lifetime.db";
dnssec-policy long-lifetime;
};
zone shorter-lifetime {
type primary;
file "shorter-lifetime.db";
dnssec-policy short-lifetime;
};
zone limit-lifetime {
type primary;
file "limit-lifetime.db";
dnssec-policy short-lifetime;
};
zone unlimit-lifetime {
type primary;
file "unlimit-lifetime.db";
dnssec-policy unlimited-lifetime;
};

View File

@@ -29,11 +29,6 @@ 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
@@ -420,6 +415,3 @@ $SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $in
#
echo "example" >>zones
cp example.db.in example.db
setup "dynamic2inline.kasp"
cp template.db.in $zonefile

View File

@@ -276,93 +276,6 @@ csk_rollover_predecessor_keytimes() {
[ "$Lcsk" = 0 ] || set_retired_removed "KEY1" "${Lcsk}" "${IretCSK}"
}
# Test dynamic zones that switch to inline-signing.
set_zone "dynamic2inline.kasp"
set_policy "default" "1" "3600"
set_server "ns6" "10.53.0.6"
# Key properties.
key_clear "KEY1"
set_keyrole "KEY1" "csk"
set_keylifetime "KEY1" "0"
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"
# Various signing policy checks.
check_keys
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
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.
#
@@ -668,40 +581,6 @@ wait_for_done_signing() {
status=$((status + ret))
}
# Test dynamic zones that switch to inline-signing.
set_zone "dynamic2inline.kasp"
set_policy "default" "1" "3600"
set_server "ns6" "10.53.0.6"
# Key properties.
key_clear "KEY1"
set_keyrole "KEY1" "csk"
set_keylifetime "KEY1" "0"
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"
# Various signing policy checks.
check_keys
check_dnssecstatus "$SERVER" "$POLICY" "$ZONE"
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.
#

View File

@@ -0,0 +1,30 @@
/*
* 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 "csk-algoroll" {
signatures-refresh P5D;
signatures-validity 30d;
signatures-validity-dnskey 30d;
keys {
csk lifetime unlimited algorithm rsasha256;
};
dnskey-ttl 1h;
publish-safety PT1H;
retire-safety 2h;
zone-propagation-delay 3600;
max-zone-ttl 6h;
parent-propagation-delay pt1h;
parent-ds-ttl 7200;
};

View File

@@ -0,0 +1,30 @@
/*
* 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 "csk-algoroll" {
signatures-refresh P5D;
signatures-validity 30d;
signatures-validity-dnskey 30d;
keys {
csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
};
dnskey-ttl 1h;
publish-safety PT1H;
retire-safety 2h;
zone-propagation-delay 3600;
max-zone-ttl 6h;
parent-propagation-delay pt1h;
parent-ds-ttl 7200;
};

View File

@@ -0,0 +1,50 @@
/*
* 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 "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@;
};
};
{% if RSASHA1_SUPPORTED == "1" %}
dnssec-policy "rsasha1" {
signatures-refresh P5D;
signatures-validity 30d;
signatures-validity-dnskey 30d;
keys {
ksk lifetime unlimited algorithm rsasha1;
zsk lifetime unlimited algorithm rsasha1;
};
dnskey-ttl 1h;
publish-safety PT1H;
retire-safety 2h;
zone-propagation-delay 3600;
max-zone-ttl 6h;
parent-propagation-delay pt1h;
parent-ds-ttl 7200;
};
{% endif %}

View File

@@ -0,0 +1,78 @@
/*
* 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.
*/
// NS6
include "kasp.conf";
include "csk1.conf";
options {
query-source address 10.53.0.6;
notify-source 10.53.0.6;
transfer-source 10.53.0.6;
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.6; };
listen-on-v6 { none; };
allow-transfer { any; };
recursion no;
key-directory ".";
dnssec-validation no;
};
key rndc_key {
secret "1234abcd8765";
algorithm @DEFAULT_HMAC@;
};
controls {
inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
zone "." {
type hint;
file "../../_common/root.hint.blackhole";
};
/* This zone switch from dynamic to inline-signing. */
zone "dynamic2inline.kasp" {
type primary;
file "dynamic2inline.kasp.db";
allow-update { any; };
dnssec-policy "default";
};
/* Lifetime changes. */
zone longer-lifetime {
type primary;
file "longer-lifetime.db";
dnssec-policy short-lifetime;
};
zone shorter-lifetime {
type primary;
file "shorter-lifetime.db";
dnssec-policy long-lifetime;
};
zone limit-lifetime {
type primary;
file "limit-lifetime.db";
dnssec-policy unlimited-lifetime;
};
zone unlimit-lifetime {
type primary;
file "unlimit-lifetime.db";
dnssec-policy short-lifetime;
};

View File

@@ -0,0 +1,77 @@
/*
* 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.
*/
// NS6
include "kasp.conf";
include "csk2.conf";
options {
query-source address 10.53.0.6;
notify-source 10.53.0.6;
transfer-source 10.53.0.6;
port @PORT@;
pid-file "named.pid";
listen-on { 10.53.0.6; };
listen-on-v6 { none; };
allow-transfer { any; };
recursion no;
dnssec-validation no;
};
key rndc_key {
secret "1234abcd8765";
algorithm @DEFAULT_HMAC@;
};
controls {
inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
};
zone "." {
type hint;
file "../../_common/root.hint.blackhole";
};
/* This zone switch from dynamic to inline-signing. */
zone "dynamic2inline.kasp" {
type primary;
file "dynamic2inline.kasp.db";
allow-update { any; };
dnssec-policy "default";
};
/* Lifetime changes. */
zone longer-lifetime {
type primary;
file "longer-lifetime.db";
dnssec-policy long-lifetime;
};
zone shorter-lifetime {
type primary;
file "shorter-lifetime.db";
dnssec-policy short-lifetime;
};
zone limit-lifetime {
type primary;
file "limit-lifetime.db";
dnssec-policy short-lifetime;
};
zone unlimit-lifetime {
type primary;
file "unlimit-lifetime.db";
dnssec-policy unlimited-lifetime;
};

View File

@@ -0,0 +1,36 @@
#!/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
echo_i "ns6/setup.sh"
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"
for zn in dynamic2inline.kasp shorter-lifetime longer-lifetime limit-lifetime \
unlimit-lifetime; do
setup $zn
cp template.db.in $zonefile
done

View File

@@ -0,0 +1,27 @@
; 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.
$TTL 300
@ IN SOA mname1. . (
1 ; serial
20 ; refresh (20 seconds)
20 ; retry (20 seconds)
1814400 ; expire (3 weeks)
3600 ; minimum (1 hour)
)
NS ns6
ns6 A 10.53.0.6
a A 10.0.0.1
b A 10.0.0.2
c A 10.0.0.3

View File

@@ -20,3 +20,7 @@ set -e
cd ns3
$SHELL setup.sh
)
(
cd ns6
$SHELL setup.sh
)

View File

@@ -10,6 +10,7 @@
# information regarding copyright ownership.
import os
import shutil
from datetime import timedelta
@@ -1256,3 +1257,133 @@ def test_rollover_csk_roll2(servers):
for step in steps:
check_rollover_step(server, config, policy, step)
def test_rollover_policy_changes(servers):
server = servers["ns6"]
cdss = ["CDNSKEY", "CDS (SHA-256)"]
alg = os.environ["DEFAULT_ALGORITHM_NUMBER"]
size = os.environ["DEFAULT_BITS"]
default_config = {
"dnskey-ttl": timedelta(hours=1),
"ds-ttl": timedelta(days=1),
"max-zone-ttl": timedelta(days=1),
"parent-propagation-delay": timedelta(hours=1),
"publish-safety": timedelta(hours=1),
"purge-keys": timedelta(days=90),
"retire-safety": timedelta(hours=1),
"signatures-refresh": timedelta(days=5),
"signatures-validity": timedelta(days=14),
"zone-propagation-delay": timedelta(seconds=300),
}
start_time = KeyTimingMetadata.now()
# Test dynamic zones that switch to inline-signing.
isctest.log.info("check dynamic zone that switches to inline-signing")
d2i = {
"zone": "dynamic2inline.kasp",
"cdss": cdss,
"config": default_config,
"policy": "default",
"keyprops": [
f"csk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden",
],
"nextev": None,
}
steps = [d2i]
# Test key lifetime changes.
isctest.log.info("check key lifetime changes are updated correctly")
lifetime = {
"P1Y": int(timedelta(days=365).total_seconds()),
"P6M": int(timedelta(days=31 * 6).total_seconds()),
}
lifetime_update_tests = [
{
"zone": "shorter-lifetime",
"policy": "long-lifetime",
"lifetime": lifetime["P1Y"],
},
{
"zone": "longer-lifetime",
"policy": "short-lifetime",
"lifetime": lifetime["P6M"],
},
{
"zone": "limit-lifetime",
"policy": "unlimited-lifetime",
"lifetime": 0,
},
{
"zone": "unlimit-lifetime",
"policy": "short-lifetime",
"lifetime": lifetime["P6M"],
},
]
for lut in lifetime_update_tests:
step = {
"zone": lut["zone"],
"cdss": cdss,
"config": default_config,
"policy": lut["policy"],
"keyprops": [
f"csk {lut['lifetime']} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden",
],
"nextev": None,
}
steps.append(step)
for step in steps:
check_rollover_step(server, step["config"], step["policy"], step)
# Reconfigure, changing DNSSEC policies and other configuration options,
# triggering algorithm rollovers and other dnssec-policy changes.
shutil.copyfile("ns6/named2.conf", "ns6/named.conf")
server.rndc("reconfig")
# Calculate time passed to correctly check for next key events.
now = KeyTimingMetadata.now()
time_passed = now.value - start_time.value
# Test dynamic zones that switch to inline-signing (after reconfig).
steps = [d2i]
# Test key lifetime changes (after reconfig).
lifetime_update_tests = [
{
"zone": "shorter-lifetime",
"policy": "short-lifetime",
"lifetime": lifetime["P6M"],
},
{
"zone": "longer-lifetime",
"policy": "long-lifetime",
"lifetime": lifetime["P1Y"],
},
{
"zone": "limit-lifetime",
"policy": "short-lifetime",
"lifetime": lifetime["P6M"],
},
{
"zone": "unlimit-lifetime",
"policy": "unlimited-lifetime",
"lifetime": 0,
},
]
for lut in lifetime_update_tests:
step = {
"zone": lut["zone"],
"cdss": cdss,
"config": default_config,
"policy": lut["policy"],
"keyprops": [
f"csk {lut['lifetime']} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden",
],
"nextev": None,
}
steps.append(step)
for step in steps:
check_rollover_step(server, step["config"], step["policy"], step)