From: Evan Hunt Date: Sat, 28 Jun 2025 00:43:13 +0000 (-0700) Subject: convert dnssec-policy tests to python X-Git-Tag: v9.21.11~13^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ddec41987c9f9283800fa0b4a4b302e701d545c;p=thirdparty%2Fbind9.git convert dnssec-policy tests to python move the signatures-validity tests to tests_policy.py --- diff --git a/bin/tests/system/dnssec/ns3/named.conf.j2 b/bin/tests/system/dnssec/ns3/named.conf.j2 index a9a1b207bf3..47d0422ad2c 100644 --- a/bin/tests/system/dnssec/ns3/named.conf.j2 +++ b/bin/tests/system/dnssec/ns3/named.conf.j2 @@ -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"; diff --git a/bin/tests/system/dnssec/ns3/siginterval1.conf b/bin/tests/system/dnssec/ns3/siginterval1.conf deleted file mode 100644 index 1d82f680d14..00000000000 --- a/bin/tests/system/dnssec/ns3/siginterval1.conf +++ /dev/null @@ -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"; -}; diff --git a/bin/tests/system/dnssec/ns3/siginterval2.conf b/bin/tests/system/dnssec/ns3/siginterval2.conf deleted file mode 100644 index fa9c6267fe6..00000000000 --- a/bin/tests/system/dnssec/ns3/siginterval2.conf +++ /dev/null @@ -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"; -}; diff --git a/bin/tests/system/dnssec/setup.sh b/bin/tests/system/dnssec/setup.sh index c6234f686c3..14970719b94 100644 --- a/bin/tests/system/dnssec/setup.sh +++ b/bin/tests/system/dnssec/setup.sh @@ -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 diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index dc5f77bb742..b0033f61277 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -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 <&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 diff --git a/bin/tests/system/dnssec/tests_policy.py b/bin/tests/system/dnssec/tests_policy.py new file mode 100644 index 00000000000..bbeb8189b3e --- /dev/null +++ b/bin/tests/system/dnssec/tests_policy.py @@ -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]