mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 15:05:23 +00:00
convert dnssec-policy tests to python
move the signatures-validity tests to tests_policy.py
This commit is contained in:
@@ -13,6 +13,8 @@
|
|||||||
|
|
||||||
// NS3
|
// NS3
|
||||||
|
|
||||||
|
{% set long_sigs = long_sigs | default(False) %}
|
||||||
|
|
||||||
options {
|
options {
|
||||||
query-source address 10.53.0.3;
|
query-source address 10.53.0.3;
|
||||||
notify-source 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";
|
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;
|
|
||||||
signatures-validity-dnskey 90d;
|
|
||||||
};
|
|
||||||
|
|
||||||
dnssec-policy "siginterval2" {
|
|
||||||
keys {
|
keys {
|
||||||
ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
|
ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
|
||||||
zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
|
zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
{% if long_sigs %}
|
||||||
signatures-validity 35d;
|
signatures-validity 35d;
|
||||||
signatures-refresh 28d;
|
signatures-refresh 28d;
|
||||||
|
{% else %}
|
||||||
|
signatures-validity 1d;
|
||||||
|
signatures-refresh 21h;
|
||||||
|
{% endif %}
|
||||||
signatures-validity-dnskey 90d;
|
signatures-validity-dnskey 90d;
|
||||||
};
|
};
|
||||||
|
|
||||||
include "siginterval.conf";
|
zone "siginterval.example" {
|
||||||
|
type primary;
|
||||||
|
allow-update { any; };
|
||||||
|
dnssec-policy siginterval;
|
||||||
|
file "siginterval.example.db";
|
||||||
|
};
|
||||||
|
|
||||||
include "trusted.conf";
|
include "trusted.conf";
|
||||||
|
@@ -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";
|
|
||||||
};
|
|
@@ -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";
|
|
||||||
};
|
|
@@ -28,11 +28,6 @@ copy_setports ns4/named1.conf.in ns4/named.conf
|
|||||||
} >>../ns3/bogus.example.db.signed
|
} >>../ns3/bogus.example.db.signed
|
||||||
)
|
)
|
||||||
|
|
||||||
(
|
|
||||||
cd ns3
|
|
||||||
cp -f siginterval1.conf siginterval.conf
|
|
||||||
)
|
|
||||||
|
|
||||||
(
|
(
|
||||||
cd ns5
|
cd ns5
|
||||||
$SHELL sign.sh
|
$SHELL sign.sh
|
||||||
|
@@ -25,10 +25,6 @@ dig_with_opts() {
|
|||||||
"$DIG" +tcp +noadd +nosea +nostat +nocmd +dnssec -p "$PORT" "$@"
|
"$DIG" +tcp +noadd +nosea +nostat +nocmd +dnssec -p "$PORT" "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
dig_with_additionalopts() {
|
|
||||||
"$DIG" +noall +additional +dnssec -p "$PORT" "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
dig_with_answeropts() {
|
dig_with_answeropts() {
|
||||||
"$DIG" +noall +answer +dnssec -p "$PORT" "$@"
|
"$DIG" +noall +answer +dnssec -p "$PORT" "$@"
|
||||||
}
|
}
|
||||||
@@ -79,11 +75,6 @@ checkprivate() {
|
|||||||
return 1
|
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 not multiple consecutive blank lines.
|
||||||
# Ensure there is a blank line before "Start view" and
|
# Ensure there is a blank line before "Start view" and
|
||||||
@@ -1616,26 +1607,6 @@ n=$((n + 1))
|
|||||||
test "$ret" -eq 0 || echo_i "failed"
|
test "$ret" -eq 0 || echo_i "failed"
|
||||||
status=$((status + ret))
|
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)"
|
echo_i "checking that signing records have been marked as complete ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
checkprivate dynamic.example 10.53.0.3 || ret=1
|
checkprivate dynamic.example 10.53.0.3 || ret=1
|
||||||
@@ -2060,53 +2031,6 @@ n=$((n + 1))
|
|||||||
test "$ret" -eq 0 || echo_i "failed"
|
test "$ret" -eq 0 || echo_i "failed"
|
||||||
status=$((status + ret))
|
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
|
copy_setports ns4/named4.conf.in ns4/named.conf
|
||||||
rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i
|
rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i
|
||||||
sleep 3
|
sleep 3
|
||||||
@@ -3009,17 +2933,6 @@ n=$((n + 1))
|
|||||||
test "$ret" -eq 0 || echo_i "failed"
|
test "$ret" -eq 0 || echo_i "failed"
|
||||||
status=$((status + ret))
|
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)"
|
echo_i "checking validation succeeds during transition to signed ($n)"
|
||||||
ret=0
|
ret=0
|
||||||
dig_with_opts @10.53.0.4 inprogress A >dig.out.ns4.test$n || ret=1
|
dig_with_opts @10.53.0.4 inprogress A >dig.out.ns4.test$n || ret=1
|
||||||
|
86
bin/tests/system/dnssec/tests_policy.py
Normal file
86
bin/tests/system/dnssec/tests_policy.py
Normal 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]
|
Reference in New Issue
Block a user