mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-02 07:35:26 +00:00
Isolate rollover-multisigner test case
This commit is contained in:
1
bin/tests/system/rollover-multisigner/common.py
Symbolic link
1
bin/tests/system/rollover-multisigner/common.py
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../rollover/common.py
|
22
bin/tests/system/rollover-multisigner/ns3/kasp.conf.j2
Normal file
22
bin/tests/system/rollover-multisigner/ns3/kasp.conf.j2
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* 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 "multisigner-model2" {
|
||||||
|
dnskey-ttl 3600;
|
||||||
|
inline-signing no;
|
||||||
|
|
||||||
|
keys {
|
||||||
|
ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535;
|
||||||
|
zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535;
|
||||||
|
};
|
||||||
|
};
|
1
bin/tests/system/rollover-multisigner/ns3/named.common.conf.j2
Symbolic link
1
bin/tests/system/rollover-multisigner/ns3/named.common.conf.j2
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../rollover/ns3/named.common.conf.j2
|
34
bin/tests/system/rollover-multisigner/ns3/named.conf.j2
Normal file
34
bin/tests/system/rollover-multisigner/ns3/named.conf.j2
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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";
|
||||||
|
|
||||||
|
/* RFC 8901 Multi-signer Model 2. */
|
||||||
|
zone "multisigner-model2.kasp" {
|
||||||
|
type primary;
|
||||||
|
file "multisigner-model2.kasp.db";
|
||||||
|
dnssec-policy "multisigner-model2";
|
||||||
|
allow-update { any; };
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A zone that starts with keys that have tags that are
|
||||||
|
* outside of the desired multi-signer key tag range.
|
||||||
|
*/
|
||||||
|
zone "single-to-multisigner.kasp" {
|
||||||
|
type primary;
|
||||||
|
file "single-to-multisigner.kasp.db";
|
||||||
|
dnssec-policy "multisigner-model2";
|
||||||
|
allow-update { any; };
|
||||||
|
};
|
1
bin/tests/system/rollover-multisigner/ns3/template.db.in
Symbolic link
1
bin/tests/system/rollover-multisigner/ns3/template.db.in
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
../../rollover/ns3/template.db.in
|
67
bin/tests/system/rollover-multisigner/setup.sh
Normal file
67
bin/tests/system/rollover-multisigner/setup.sh
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#!/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"
|
||||||
|
|
||||||
|
# Multi-signer zones.
|
||||||
|
setup "multisigner-model2.kasp"
|
||||||
|
cp template.db.in "$zonefile"
|
||||||
|
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -f KSK -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.1)
|
||||||
|
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.2)
|
||||||
|
cat "${KSK}.key" | grep -v ";.*" >>"${zone}.db"
|
||||||
|
cat "${ZSK}.key" | grep -v ";.*" >>"${zone}.db"
|
||||||
|
# Import a ZSK of another provider into the DNSKEY RRset.
|
||||||
|
ZSK1=$($KEYGEN -K ../ -a $DEFAULT_ALGORITHM -L 3600 -M 0:32767 $zone 2>keygen.out.$zone.3)
|
||||||
|
cat "../${ZSK1}.key" | grep -v ";.*" >>"${zone}.db"
|
||||||
|
|
||||||
|
# We are changing an existing single-signed zone to multi-signed
|
||||||
|
# zone where the key tags do not match the dnssec-policy key tag range
|
||||||
|
setup single-to-multisigner.kasp
|
||||||
|
T="now-7d"
|
||||||
|
S="now-8635mi" # T - 1d5m
|
||||||
|
keytimes="-P $T -A $T"
|
||||||
|
cdstimes="-P sync $S"
|
||||||
|
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1)
|
||||||
|
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 $keytimes $zone 2>keygen.out.$zone.2)
|
||||||
|
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
||||||
|
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
||||||
|
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
|
@@ -0,0 +1,173 @@
|
|||||||
|
# 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
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
import os
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
pytest.importorskip("dns", minversion="2.0.0")
|
||||||
|
import dns.update
|
||||||
|
|
||||||
|
import isctest
|
||||||
|
from isctest.kasp import Iret
|
||||||
|
from common import (
|
||||||
|
pytestmark,
|
||||||
|
alg,
|
||||||
|
size,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_rollover_multisigner(servers, alg, size):
|
||||||
|
server = servers["ns3"]
|
||||||
|
policy = "multisigner-model2"
|
||||||
|
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),
|
||||||
|
"retire-safety": timedelta(hours=1),
|
||||||
|
"signatures-refresh": timedelta(days=5),
|
||||||
|
"signatures-validity": timedelta(days=14),
|
||||||
|
"zone-propagation-delay": timedelta(minutes=5),
|
||||||
|
}
|
||||||
|
ttl = int(config["dnskey-ttl"].total_seconds())
|
||||||
|
|
||||||
|
offset = -timedelta(days=7)
|
||||||
|
offval = int(offset.total_seconds())
|
||||||
|
|
||||||
|
def keygen(zone):
|
||||||
|
keygen_command = [
|
||||||
|
os.environ.get("KEYGEN"),
|
||||||
|
"-a",
|
||||||
|
alg,
|
||||||
|
"-L",
|
||||||
|
"3600",
|
||||||
|
"-M",
|
||||||
|
"0:32767",
|
||||||
|
zone,
|
||||||
|
]
|
||||||
|
|
||||||
|
return isctest.run.cmd(keygen_command).stdout.decode("utf-8")
|
||||||
|
|
||||||
|
zone = "multisigner-model2.kasp"
|
||||||
|
|
||||||
|
isctest.kasp.check_dnssec_verify(server, zone)
|
||||||
|
|
||||||
|
key_properties = [
|
||||||
|
f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden tag-range:32768-65535",
|
||||||
|
f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured tag-range:32768-65535",
|
||||||
|
]
|
||||||
|
expected = isctest.kasp.policy_to_properties(ttl, key_properties)
|
||||||
|
|
||||||
|
newprops = [f"zsk unlimited {alg} {size} tag-range:0-32767"]
|
||||||
|
expected2 = isctest.kasp.policy_to_properties(ttl, newprops)
|
||||||
|
expected2[0].properties["private"] = False
|
||||||
|
expected2[0].properties["legacy"] = True
|
||||||
|
expected = expected + expected2
|
||||||
|
|
||||||
|
ownkeys = isctest.kasp.keydir_to_keylist(zone, server.identifier)
|
||||||
|
extkeys = isctest.kasp.keydir_to_keylist(zone)
|
||||||
|
keys = ownkeys + extkeys
|
||||||
|
ksks = [k for k in ownkeys if k.is_ksk()]
|
||||||
|
zsks = [k for k in ownkeys if not k.is_ksk()]
|
||||||
|
zsks = zsks + extkeys
|
||||||
|
|
||||||
|
isctest.kasp.check_keys(zone, keys, expected)
|
||||||
|
for kp in expected:
|
||||||
|
kp.set_expected_keytimes(config)
|
||||||
|
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_subdomain(server, zone, ksks, zsks)
|
||||||
|
|
||||||
|
# Update zone with ZSK from another provider for zone.
|
||||||
|
out = keygen(zone)
|
||||||
|
newkeys = isctest.kasp.keystr_to_keylist(out)
|
||||||
|
newprops = [f"zsk unlimited {alg} {size} tag-range:0-32767"]
|
||||||
|
expected2 = isctest.kasp.policy_to_properties(ttl, newprops)
|
||||||
|
expected2[0].properties["private"] = False
|
||||||
|
expected2[0].properties["legacy"] = True
|
||||||
|
expected = expected + expected2
|
||||||
|
|
||||||
|
dnskey = newkeys[0].dnskey().split()
|
||||||
|
rdata = " ".join(dnskey[4:])
|
||||||
|
|
||||||
|
update_msg = dns.update.UpdateMessage(zone)
|
||||||
|
update_msg.add(f"{dnskey[0]}", 3600, "DNSKEY", rdata)
|
||||||
|
server.nsupdate(update_msg)
|
||||||
|
|
||||||
|
isctest.kasp.check_dnssec_verify(server, zone)
|
||||||
|
|
||||||
|
keys = keys + newkeys
|
||||||
|
zsks = zsks + newkeys
|
||||||
|
isctest.kasp.check_keys(zone, keys, expected)
|
||||||
|
isctest.kasp.check_apex(server, zone, ksks, zsks)
|
||||||
|
isctest.kasp.check_subdomain(server, zone, ksks, zsks)
|
||||||
|
|
||||||
|
# Remove ZSKs from the other providers for zone.
|
||||||
|
dnskey2 = extkeys[0].dnskey().split()
|
||||||
|
rdata2 = " ".join(dnskey2[4:])
|
||||||
|
update_msg = dns.update.UpdateMessage(zone)
|
||||||
|
update_msg.delete(f"{dnskey[0]}", "DNSKEY", rdata)
|
||||||
|
update_msg.delete(f"{dnskey2[0]}", "DNSKEY", rdata2)
|
||||||
|
server.nsupdate(update_msg)
|
||||||
|
|
||||||
|
isctest.kasp.check_dnssec_verify(server, zone)
|
||||||
|
|
||||||
|
expected = isctest.kasp.policy_to_properties(ttl, key_properties)
|
||||||
|
keys = ownkeys
|
||||||
|
ksks = [k for k in ownkeys if k.is_ksk()]
|
||||||
|
zsks = [k for k in ownkeys if not k.is_ksk()]
|
||||||
|
isctest.kasp.check_keys(zone, keys, expected)
|
||||||
|
isctest.kasp.check_apex(server, zone, ksks, zsks)
|
||||||
|
isctest.kasp.check_subdomain(server, zone, ksks, zsks)
|
||||||
|
|
||||||
|
# A zone transitioning from single-signed to multi-signed. We should have
|
||||||
|
# the old omnipresent keys outside of the desired key range and the new
|
||||||
|
# keys in the desired key range.
|
||||||
|
zone = "single-to-multisigner.kasp"
|
||||||
|
|
||||||
|
isctest.kasp.check_dnssec_verify(server, zone)
|
||||||
|
|
||||||
|
key_properties = [
|
||||||
|
f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden tag-range:32768-65535",
|
||||||
|
f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:hidden tag-range:32768-65535",
|
||||||
|
f"ksk unlimited {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent tag-range:0-32767 offset:{offval}",
|
||||||
|
f"zsk unlimited {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent tag-range:0-32767 offset:{offval}",
|
||||||
|
]
|
||||||
|
expected = isctest.kasp.policy_to_properties(ttl, key_properties)
|
||||||
|
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)
|
||||||
|
|
||||||
|
for kp in expected:
|
||||||
|
kp.set_expected_keytimes(config)
|
||||||
|
|
||||||
|
start = expected[0].key.get_timing("Created")
|
||||||
|
expected[2].timing["Retired"] = start
|
||||||
|
expected[2].timing["Removed"] = expected[2].timing["Retired"] + Iret(
|
||||||
|
config, zsk=False, ksk=True
|
||||||
|
)
|
||||||
|
expected[3].timing["Retired"] = start
|
||||||
|
expected[3].timing["Removed"] = expected[3].timing["Retired"] + Iret(
|
||||||
|
config, zsk=True, ksk=False
|
||||||
|
)
|
||||||
|
|
||||||
|
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_subdomain(server, zone, ksks, zsks)
|
@@ -19,13 +19,3 @@ dnssec-policy "manual-rollover" {
|
|||||||
zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
|
zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
dnssec-policy "multisigner-model2" {
|
|
||||||
dnskey-ttl 3600;
|
|
||||||
inline-signing no;
|
|
||||||
|
|
||||||
keys {
|
|
||||||
ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535;
|
|
||||||
zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
@@ -11,34 +11,11 @@
|
|||||||
* information regarding copyright ownership.
|
* information regarding copyright ownership.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// NS3
|
|
||||||
|
|
||||||
include "kasp.conf";
|
include "kasp.conf";
|
||||||
|
|
||||||
include "named.common.conf";
|
include "named.common.conf";
|
||||||
|
|
||||||
/* Manual rollover. */
|
|
||||||
zone "manual-rollover.kasp" {
|
zone "manual-rollover.kasp" {
|
||||||
type primary;
|
type primary;
|
||||||
file "manual-rollover.kasp.db";
|
file "manual-rollover.kasp.db";
|
||||||
dnssec-policy "manual-rollover";
|
dnssec-policy "manual-rollover";
|
||||||
};
|
};
|
||||||
|
|
||||||
/* RFC 8901 Multi-signer Model 2. */
|
|
||||||
zone "multisigner-model2.kasp" {
|
|
||||||
type primary;
|
|
||||||
file "multisigner-model2.kasp.db";
|
|
||||||
dnssec-policy "multisigner-model2";
|
|
||||||
allow-update { any; };
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A zone that starts with keys that have tags that are
|
|
||||||
* outside of the desired multi-signer key tag range.
|
|
||||||
*/
|
|
||||||
zone "single-to-multisigner.kasp" {
|
|
||||||
type primary;
|
|
||||||
file "single-to-multisigner.kasp.db";
|
|
||||||
dnssec-policy "multisigner-model2";
|
|
||||||
allow-update { any; };
|
|
||||||
};
|
|
||||||
|
@@ -52,30 +52,3 @@ private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile"
|
|||||||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
|
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile"
|
||||||
cp $infile $zonefile
|
cp $infile $zonefile
|
||||||
$SIGNER -PS -x -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
|
$SIGNER -PS -x -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1
|
||||||
|
|
||||||
# Multi-signer zones.
|
|
||||||
setup "multisigner-model2.kasp"
|
|
||||||
cp template.db.in "$zonefile"
|
|
||||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -f KSK -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.1)
|
|
||||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.2)
|
|
||||||
cat "${KSK}.key" | grep -v ";.*" >>"${zone}.db"
|
|
||||||
cat "${ZSK}.key" | grep -v ";.*" >>"${zone}.db"
|
|
||||||
# Import a ZSK of another provider into the DNSKEY RRset.
|
|
||||||
ZSK1=$($KEYGEN -K ../ -a $DEFAULT_ALGORITHM -L 3600 -M 0:32767 $zone 2>keygen.out.$zone.3)
|
|
||||||
cat "../${ZSK1}.key" | grep -v ";.*" >>"${zone}.db"
|
|
||||||
|
|
||||||
# We are changing an existing single-signed zone to multi-signed
|
|
||||||
# zone where the key tags do not match the dnssec-policy key tag range
|
|
||||||
setup single-to-multisigner.kasp
|
|
||||||
T="now-7d"
|
|
||||||
S="now-8635mi" # T - 1d5m
|
|
||||||
keytimes="-P $T -A $T"
|
|
||||||
cdstimes="-P sync $S"
|
|
||||||
KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1)
|
|
||||||
ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 $keytimes $zone 2>keygen.out.$zone.2)
|
|
||||||
$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1
|
|
||||||
$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1
|
|
||||||
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
|
|
||||||
|
@@ -9,17 +9,13 @@
|
|||||||
# See the COPYRIGHT file distributed with this work for additional
|
# See the COPYRIGHT file distributed with this work for additional
|
||||||
# information regarding copyright ownership.
|
# information regarding copyright ownership.
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
import os
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
pytest.importorskip("dns", minversion="2.0.0")
|
|
||||||
import dns.update
|
|
||||||
|
|
||||||
import isctest
|
import isctest
|
||||||
from isctest.kasp import KeyTimingMetadata, Ipub, IpubC, Iret
|
from isctest.kasp import KeyTimingMetadata, Ipub, Iret
|
||||||
|
|
||||||
from common import pytestmark
|
from common import pytestmark
|
||||||
|
|
||||||
@@ -161,150 +157,3 @@ def test_rollover_manual(servers):
|
|||||||
zsk = expected[3].key
|
zsk = expected[3].key
|
||||||
response = server.rndc(f"dnssec -rollover -key {zsk.tag} {zone}")
|
response = server.rndc(f"dnssec -rollover -key {zsk.tag} {zone}")
|
||||||
assert "key is not actively signing" in response
|
assert "key is not actively signing" in response
|
||||||
|
|
||||||
|
|
||||||
def test_rollover_multisigner(servers):
|
|
||||||
server = servers["ns3"]
|
|
||||||
policy = "multisigner-model2"
|
|
||||||
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),
|
|
||||||
"retire-safety": timedelta(hours=1),
|
|
||||||
"signatures-refresh": timedelta(days=5),
|
|
||||||
"signatures-validity": timedelta(days=14),
|
|
||||||
"zone-propagation-delay": timedelta(minutes=5),
|
|
||||||
}
|
|
||||||
ttl = int(config["dnskey-ttl"].total_seconds())
|
|
||||||
alg = os.environ["DEFAULT_ALGORITHM_NUMBER"]
|
|
||||||
size = os.environ["DEFAULT_BITS"]
|
|
||||||
|
|
||||||
offset = -timedelta(days=7)
|
|
||||||
offval = int(offset.total_seconds())
|
|
||||||
|
|
||||||
def keygen(zone):
|
|
||||||
keygen_command = [
|
|
||||||
os.environ.get("KEYGEN"),
|
|
||||||
"-a",
|
|
||||||
alg,
|
|
||||||
"-L",
|
|
||||||
"3600",
|
|
||||||
"-M",
|
|
||||||
"0:32767",
|
|
||||||
zone,
|
|
||||||
]
|
|
||||||
|
|
||||||
return isctest.run.cmd(keygen_command).stdout.decode("utf-8")
|
|
||||||
|
|
||||||
zone = "multisigner-model2.kasp"
|
|
||||||
|
|
||||||
isctest.kasp.check_dnssec_verify(server, zone)
|
|
||||||
|
|
||||||
key_properties = [
|
|
||||||
f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden tag-range:32768-65535",
|
|
||||||
f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured tag-range:32768-65535",
|
|
||||||
]
|
|
||||||
expected = isctest.kasp.policy_to_properties(ttl, key_properties)
|
|
||||||
|
|
||||||
newprops = [f"zsk unlimited {alg} {size} tag-range:0-32767"]
|
|
||||||
expected2 = isctest.kasp.policy_to_properties(ttl, newprops)
|
|
||||||
expected2[0].properties["private"] = False
|
|
||||||
expected2[0].properties["legacy"] = True
|
|
||||||
expected = expected + expected2
|
|
||||||
|
|
||||||
ownkeys = isctest.kasp.keydir_to_keylist(zone, server.identifier)
|
|
||||||
extkeys = isctest.kasp.keydir_to_keylist(zone)
|
|
||||||
keys = ownkeys + extkeys
|
|
||||||
ksks = [k for k in ownkeys if k.is_ksk()]
|
|
||||||
zsks = [k for k in ownkeys if not k.is_ksk()]
|
|
||||||
zsks = zsks + extkeys
|
|
||||||
|
|
||||||
isctest.kasp.check_keys(zone, keys, expected)
|
|
||||||
for kp in expected:
|
|
||||||
kp.set_expected_keytimes(config)
|
|
||||||
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_subdomain(server, zone, ksks, zsks)
|
|
||||||
|
|
||||||
# Update zone with ZSK from another provider for zone.
|
|
||||||
out = keygen(zone)
|
|
||||||
newkeys = isctest.kasp.keystr_to_keylist(out)
|
|
||||||
newprops = [f"zsk unlimited {alg} {size} tag-range:0-32767"]
|
|
||||||
expected2 = isctest.kasp.policy_to_properties(ttl, newprops)
|
|
||||||
expected2[0].properties["private"] = False
|
|
||||||
expected2[0].properties["legacy"] = True
|
|
||||||
expected = expected + expected2
|
|
||||||
|
|
||||||
dnskey = newkeys[0].dnskey().split()
|
|
||||||
rdata = " ".join(dnskey[4:])
|
|
||||||
|
|
||||||
update_msg = dns.update.UpdateMessage(zone)
|
|
||||||
update_msg.add(f"{dnskey[0]}", 3600, "DNSKEY", rdata)
|
|
||||||
server.nsupdate(update_msg)
|
|
||||||
|
|
||||||
isctest.kasp.check_dnssec_verify(server, zone)
|
|
||||||
|
|
||||||
keys = keys + newkeys
|
|
||||||
zsks = zsks + newkeys
|
|
||||||
isctest.kasp.check_keys(zone, keys, expected)
|
|
||||||
isctest.kasp.check_apex(server, zone, ksks, zsks)
|
|
||||||
isctest.kasp.check_subdomain(server, zone, ksks, zsks)
|
|
||||||
|
|
||||||
# Remove ZSKs from the other providers for zone.
|
|
||||||
dnskey2 = extkeys[0].dnskey().split()
|
|
||||||
rdata2 = " ".join(dnskey2[4:])
|
|
||||||
update_msg = dns.update.UpdateMessage(zone)
|
|
||||||
update_msg.delete(f"{dnskey[0]}", "DNSKEY", rdata)
|
|
||||||
update_msg.delete(f"{dnskey2[0]}", "DNSKEY", rdata2)
|
|
||||||
server.nsupdate(update_msg)
|
|
||||||
|
|
||||||
isctest.kasp.check_dnssec_verify(server, zone)
|
|
||||||
|
|
||||||
expected = isctest.kasp.policy_to_properties(ttl, key_properties)
|
|
||||||
keys = ownkeys
|
|
||||||
ksks = [k for k in ownkeys if k.is_ksk()]
|
|
||||||
zsks = [k for k in ownkeys if not k.is_ksk()]
|
|
||||||
isctest.kasp.check_keys(zone, keys, expected)
|
|
||||||
isctest.kasp.check_apex(server, zone, ksks, zsks)
|
|
||||||
isctest.kasp.check_subdomain(server, zone, ksks, zsks)
|
|
||||||
|
|
||||||
# A zone transitioning from single-signed to multi-signed. We should have
|
|
||||||
# the old omnipresent keys outside of the desired key range and the new
|
|
||||||
# keys in the desired key range.
|
|
||||||
zone = "single-to-multisigner.kasp"
|
|
||||||
|
|
||||||
isctest.kasp.check_dnssec_verify(server, zone)
|
|
||||||
|
|
||||||
key_properties = [
|
|
||||||
f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden tag-range:32768-65535",
|
|
||||||
f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:hidden tag-range:32768-65535",
|
|
||||||
f"ksk unlimited {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent tag-range:0-32767 offset:{offval}",
|
|
||||||
f"zsk unlimited {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent tag-range:0-32767 offset:{offval}",
|
|
||||||
]
|
|
||||||
expected = isctest.kasp.policy_to_properties(ttl, key_properties)
|
|
||||||
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)
|
|
||||||
|
|
||||||
for kp in expected:
|
|
||||||
kp.set_expected_keytimes(config)
|
|
||||||
|
|
||||||
start = expected[0].key.get_timing("Created")
|
|
||||||
expected[2].timing["Retired"] = start
|
|
||||||
expected[2].timing["Removed"] = expected[2].timing["Retired"] + Iret(
|
|
||||||
config, zsk=False, ksk=True
|
|
||||||
)
|
|
||||||
expected[3].timing["Retired"] = start
|
|
||||||
expected[3].timing["Removed"] = expected[3].timing["Retired"] + Iret(
|
|
||||||
config, zsk=True, ksk=False
|
|
||||||
)
|
|
||||||
|
|
||||||
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_subdomain(server, zone, ksks, zsks)
|
|
||||||
|
Reference in New Issue
Block a user