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

convert dnssec-policy tests to python

move the signatures-validity tests to tests_policy.py
This commit is contained in:
Evan Hunt
2025-06-27 17:43:13 -07:00
parent 0fabb0fbb6
commit 8ddec41987
6 changed files with 101 additions and 144 deletions

View File

@@ -13,6 +13,8 @@
// NS3
{% set long_sigs = long_sigs | default(False) %}
options {
query-source address 10.53.0.3;
notify-source 10.53.0.3;
@@ -464,28 +466,27 @@ zone "extended-ds-unknown-oid.example" {
file "extended-ds-unknown-oid.example.db.signed";
};
dnssec-policy "siginterval1" {
dnssec-policy "siginterval" {
keys {
ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
};
signatures-validity 1d;
signatures-refresh 21h;
{% if long_sigs %}
signatures-validity 35d;
signatures-refresh 28d;
{% else %}
signatures-validity 1d;
signatures-refresh 21h;
{% endif %}
signatures-validity-dnskey 90d;
};
dnssec-policy "siginterval2" {
keys {
ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
};
signatures-validity 35d;
signatures-refresh 28d;
signatures-validity-dnskey 90d;
zone "siginterval.example" {
type primary;
allow-update { any; };
dnssec-policy siginterval;
file "siginterval.example.db";
};
include "siginterval.conf";
include "trusted.conf";

View File

@@ -1,19 +0,0 @@
/*
* 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.
*/
zone "siginterval.example" {
type primary;
allow-update { any; };
dnssec-policy siginterval1;
file "siginterval.example.db";
};

View File

@@ -1,19 +0,0 @@
/*
* 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.
*/
zone "siginterval.example" {
type primary;
allow-update { any; };
dnssec-policy siginterval2;
file "siginterval.example.db";
};

View File

@@ -28,11 +28,6 @@ copy_setports ns4/named1.conf.in ns4/named.conf
} >>../ns3/bogus.example.db.signed
)
(
cd ns3
cp -f siginterval1.conf siginterval.conf
)
(
cd ns5
$SHELL sign.sh

View File

@@ -25,10 +25,6 @@ dig_with_opts() {
"$DIG" +tcp +noadd +nosea +nostat +nocmd +dnssec -p "$PORT" "$@"
}
dig_with_additionalopts() {
"$DIG" +noall +additional +dnssec -p "$PORT" "$@"
}
dig_with_answeropts() {
"$DIG" +noall +answer +dnssec -p "$PORT" "$@"
}
@@ -79,11 +75,6 @@ checkprivate() {
return 1
}
# strip NS and RRSIG NS from input
stripns() {
awk '($4 == "NS") || ($4 == "RRSIG" && $5 == "NS") { next} { print }' "$1"
}
#
# Ensure there is not multiple consecutive blank lines.
# Ensure there is a blank line before "Start view" and
@@ -1616,26 +1607,6 @@ n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
echo_i "checking that the NSEC record is properly generated when DNSKEY are added by dnssec-policy ($n)"
ret=0
dig_with_opts +dnssec a auto-nsec.example. @10.53.0.4 >dig.out.ns4.test$n || ret=1
grep "NOERROR" dig.out.ns4.test$n >/dev/null || ret=1
grep "flags:.* ad[ ;]" dig.out.ns4.test$n >/dev/null || ret=1
grep "IN.NSEC[^3].* DNSKEY" dig.out.ns4.test$n >/dev/null || ret=1
n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
echo_i "checking that the NSEC3 record is properly generated when DNSKEY are added by dnssec-policy ($n)"
ret=0
dig_with_opts +dnssec a auto-nsec3.example. @10.53.0.4 >dig.out.ns4.test$n || ret=1
grep "NOERROR" dig.out.ns4.test$n >/dev/null || ret=1
grep "flags:.* ad[ ;]" dig.out.ns4.test$n >/dev/null || ret=1
grep "IN.NSEC3 .* DNSKEY" dig.out.ns4.test$n >/dev/null || ret=1
n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
echo_i "checking that signing records have been marked as complete ($n)"
ret=0
checkprivate dynamic.example 10.53.0.3 || ret=1
@@ -2060,53 +2031,6 @@ n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
echo_i "check that increasing the signatures-validity resigning triggers re-signing ($n)"
ret=0
before=$($DIG axfr siginterval.example -p "$PORT" @10.53.0.3 | grep RRSIG.SOA)
cp ns3/siginterval2.conf ns3/siginterval.conf
rndccmd 10.53.0.3 reconfig 2>&1 | sed 's/^/ns3 /' | cat_i
i=10
while [ "$i" -ge 0 ]; do
after=$($DIG axfr siginterval.example -p "$PORT" @10.53.0.3 | grep RRSIG.SOA)
test "$before" != "$after" && break
sleep 1
i=$((i - 1))
done
n=$((n + 1))
if test "$before" = "$after"; then
echo_i "failed"
ret=1
fi
status=$((status + ret))
if [ -x "$PYTHON" ]; then
echo_i "check signatures-validity-dnskey sets longer expiry for DNSKEY ($n)"
ret=0
rndccmd 10.53.0.3 sign siginterval.example 2>&1 | sed 's/^/ns3 /' | cat_i
# convert expiry date to a comma-separated list of integers python can
# use as input to date(). strip leading 0s in months and days so
# python3 will recognize them as integers.
$DIG +dnssec +short -p "$PORT" @10.53.0.3 soa siginterval.example >dig.out.soa.test$n || ret=1
soaexpire=$(awk '$1 ~ /SOA/ { print $5 }' dig.out.soa.test$n \
| sed 's/\(....\)\(..\)\(..\).*/\1, \2, \3/' \
| sed 's/ 0/ /g')
$DIG +dnssec +short -p "$PORT" @10.53.0.3 dnskey siginterval.example >dig.out.dnskey.test$n || ret=1
dnskeyexpire=$(awk '$1 ~ /DNSKEY/ { print $5; exit 0 }' dig.out.dnskey.test$n \
| sed 's/\(....\)\(..\)\(..\).*/\1, \2, \3/' \
| sed 's/ 0/ /g')
$PYTHON >python.out.$n <<EOF
from datetime import date;
ke=date($dnskeyexpire)
se=date($soaexpire)
print((ke-se).days);
EOF
diff=$(cat python.out.$n)
[ "$diff" -ge 55 ] || ret=1
n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
fi
copy_setports ns4/named4.conf.in ns4/named.conf
rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i
sleep 3
@@ -3009,17 +2933,6 @@ n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
echo_i "checking signatures-validity second field hours vs days ($n)"
ret=0
# zone configured with 'signatures-validity 500d; signatures-refresh 1d'
# 499 days in the future w/ a 20 minute runtime to now allowance
min=$(TZ=UTC $PERL -e '@lt=localtime(time() + 499*3600*24 - 20*60); printf "%.4d%0.2d%0.2d%0.2d%0.2d%0.2d\n",$lt[5]+1900,$lt[4]+1,$lt[3],$lt[2],$lt[1],$lt[0];')
dig_with_opts @10.53.0.2 hours-vs-days AXFR >dig.out.ns2.test$n
awk -v min=$min '$4 == "RRSIG" { if ($9 < min) { exit(1); } }' dig.out.ns2.test$n || ret=1
n=$((n + 1))
test "$ret" -eq 0 || echo_i "failed"
status=$((status + ret))
echo_i "checking validation succeeds during transition to signed ($n)"
ret=0
dig_with_opts @10.53.0.4 inprogress A >dig.out.ns4.test$n || ret=1

View File

@@ -0,0 +1,86 @@
# 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.
from datetime import timedelta
import time
from dns import rdatatype
import isctest
def is_rrsig_soa(rrset):
return rrset.rdtype == rdatatype.RRSIG and rrset.covers == rdatatype.SOA
def test_signatures_validity(servers, templates):
# check that increasing signatures-validity triggers resigning
msg = isctest.query.create("siginterval.example.", "AXFR")
res = isctest.query.tcp(msg, "10.53.0.3")
before = next(filter(is_rrsig_soa, res.answer))
ns3 = servers["ns3"]
templates.render("ns3/named.conf", {"long_sigs": True})
with ns3.watch_log_from_here() as watcher:
ns3.reconfigure(log=False)
watcher.wait_for_line("siginterval.example/IN (signed): sending notifies")
res = isctest.query.tcp(msg, "10.53.0.3")
after = next(filter(is_rrsig_soa, res.answer))
assert after != before
ns3.rndc("sign siginterval.example", log=False)
msg = isctest.query.create("siginterval.example.", "SOA")
res = isctest.query.tcp(msg, "10.53.0.3")
sexp = res.answer[-1][0].expiration
msg = isctest.query.create("siginterval.example.", "DNSKEY")
res = isctest.query.tcp(msg, "10.53.0.3")
kexp = res.answer[-1][0].expiration
delta = timedelta(seconds=kexp - sexp)
assert delta > timedelta(days=54)
def test_signatures_validity_hours_vs_days():
# zone configured with 'signatures-validity 500d; signatures-refresh 1d'
msg = isctest.query.create("hours-vs-days.", "AXFR")
res = isctest.query.tcp(msg, "10.53.0.2")
# 499 days in the future w/ a 20 minute runtime to now allowance
future = timedelta(days=499) - timedelta(minutes=20)
minimum = time.time() + future.total_seconds()
for rrset in res.answer:
if rrset.rdtype != rdatatype.RRSIG:
continue
assert rrset[0].expiration >= minimum
def test_nsec_chain():
# check that NSEC records are properly generated when DNSKEYs
# are added by dnssec-policy
msg = isctest.query.create("auto-nsec.example", "A")
res = isctest.query.tcp(msg, "10.53.0.4")
isctest.check.noerror(res)
isctest.check.adflag(res)
assert [a for a in res.authority if a.rdtype == rdatatype.NSEC]
def test_nsec3_chain():
# check that NSEC3 records are properly generated when DNSKEYs
# are added by dnssec-policy
msg = isctest.query.create("auto-nsec3.example", "A")
res = isctest.query.tcp(msg, "10.53.0.4")
isctest.check.noerror(res)
isctest.check.adflag(res)
assert [a for a in res.authority if a.rdtype == rdatatype.NSEC3]