Add tests for DNSSEC sign statistics
This adds tests to the statschannel system test for testing if the dnskey sign operation counters are incremented correctly. It tests three cases: 1. A zone maintenance event where all the signatures that are about to expire are resigned. 2. A dynamic update event where the new RR and other relevant records (SOA, NSEC) are resigned. 3. Adding a standby key, that means the DNSKEY and SOA RRset are resigned.
This commit is contained in:
committed by
Matthijs Mekking
parent
312fa7f65e
commit
a8750a8805
@@ -9,14 +9,18 @@
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
rm -f traffic traffic.out.*
|
||||
rm -f traffic traffic.out.* traffic.json.* traffic.xml.*
|
||||
rm -f zones zones.out.* zones.json.* zones.xml.* zones.expect.*
|
||||
rm -f dig.out*
|
||||
rm -f */named.memstats
|
||||
rm -f */named.conf
|
||||
rm -f */named.run
|
||||
rm -f */named.run*
|
||||
rm -f ns*/named.lock
|
||||
rm -f ns*/named.stats
|
||||
rm -f xml.*stats json.*stats
|
||||
rm -f xml.*mem json.*mem
|
||||
rm -f compressed.headers regular.headers compressed.out regular.out
|
||||
rm -f ns*/managed-keys.bind*
|
||||
rm -f ns2/Kdnssec* ns2/dnssec.*.id
|
||||
rm -f ns2/dnssec.db.signed* ns2/dsset-dnssec.
|
||||
rm -f ns2/core
|
||||
|
||||
26
bin/tests/system/statschannel/ns2/dnssec.db.in
Normal file
26
bin/tests/system/statschannel/ns2/dnssec.db.in
Normal file
@@ -0,0 +1,26 @@
|
||||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; 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 http://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$ORIGIN .
|
||||
$TTL 300
|
||||
|
||||
dnssec. IN SOA mname1. . (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
dnssec. NS ns2.dnssec.
|
||||
ns2.dnssec. A 10.53.0.2
|
||||
|
||||
$ORIGIN dnssec.
|
||||
a A 10.0.0.1
|
||||
MX 10 mail.dnssec.
|
||||
mail A 10.0.0.2
|
||||
@@ -39,3 +39,13 @@ zone "example" {
|
||||
file "example.db";
|
||||
allow-transfer { any; };
|
||||
};
|
||||
|
||||
zone "dnssec" {
|
||||
type master;
|
||||
file "dnssec.db.signed";
|
||||
auto-dnssec maintain;
|
||||
allow-update { any; };
|
||||
zone-statistics full;
|
||||
dnssec-dnskey-kskonly yes;
|
||||
update-check-ksk yes;
|
||||
};
|
||||
|
||||
28
bin/tests/system/statschannel/ns2/sign.sh
Normal file
28
bin/tests/system/statschannel/ns2/sign.sh
Normal file
@@ -0,0 +1,28 @@
|
||||
#!/bin/sh -e
|
||||
#
|
||||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# 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 http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
# shellcheck source=conf.sh
|
||||
. "$SYSTEMTESTTOP/conf.sh"
|
||||
|
||||
set -e
|
||||
|
||||
zone=dnssec.
|
||||
infile=dnssec.db.in
|
||||
zonefile=dnssec.db.signed
|
||||
|
||||
ksk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -f KSK "$zone")
|
||||
zsk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone")
|
||||
# Sign deliberately with a very short expiration date.
|
||||
"$SIGNER" -S -x -O full -e "now"+1s -o "$zone" -f "$zonefile" "$infile" > /dev/null 2>&1
|
||||
|
||||
echo "$ksk" | sed -e 's/.*[+]//' -e 's/^0*//' > dnssec.ksk.id
|
||||
echo "$zsk" | sed -e 's/.*[+]//' -e 's/^0*//' > dnssec.zsk.id
|
||||
|
||||
@@ -9,9 +9,14 @@
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
# shellcheck source=conf.sh
|
||||
. "$SYSTEMTESTTOP/conf.sh"
|
||||
|
||||
$SHELL clean.sh
|
||||
|
||||
copy_setports ns2/named.conf.in ns2/named.conf
|
||||
|
||||
(
|
||||
cd ns2
|
||||
$SHELL sign.sh
|
||||
)
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
# shellcheck source=conf.sh
|
||||
. "$SYSTEMTESTTOP/conf.sh"
|
||||
|
||||
DIGCMD="$DIG @10.53.0.2 -p ${PORT}"
|
||||
RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s"
|
||||
@@ -54,12 +54,48 @@ gettraffic() {
|
||||
*) return 1 ;;
|
||||
esac
|
||||
file=`$PERL fetch.pl -p ${EXTRAPORT1} $path`
|
||||
cp $file $file.$1.$2
|
||||
$PERL traffic-${1}.pl $file 2>/dev/null | sort > traffic.out.$2
|
||||
result=$?
|
||||
rm -f $file
|
||||
return $result
|
||||
}
|
||||
|
||||
getzones() {
|
||||
sleep 1
|
||||
echo_i "... using $1"
|
||||
case $1 in
|
||||
xml) path='xml/v3/zones' ;;
|
||||
json) path='json/v1/zones' ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
file=`$PERL fetch.pl -p ${EXTRAPORT1} $path`
|
||||
cp $file $file.$1.$2
|
||||
$PERL zones-${1}.pl $file 2>/dev/null | sort > zones.out.$2
|
||||
result=$?
|
||||
return $result
|
||||
}
|
||||
|
||||
# TODO: Move wait_for_log and loadkeys_on to conf.sh.common
|
||||
wait_for_log() {
|
||||
msg=$1
|
||||
file=$2
|
||||
|
||||
for i in 1 2 3 4 5 6 7 8 9 10; do
|
||||
nextpart "$file" | grep "$msg" > /dev/null && return
|
||||
sleep 1
|
||||
done
|
||||
echo_i "exceeded time limit waiting for '$msg' in $file"
|
||||
ret=1
|
||||
}
|
||||
|
||||
loadkeys_on() {
|
||||
nsidx=$1
|
||||
zone=$2
|
||||
nextpart ns${nsidx}/named.run > /dev/null
|
||||
$RNDCCMD 10.53.0.${nsidx} loadkeys ${zone} | sed "s/^/ns${nsidx} /" | cat_i
|
||||
wait_for_log "next key event" ns${nsidx}/named.run
|
||||
}
|
||||
|
||||
status=0
|
||||
n=1
|
||||
ret=0
|
||||
@@ -243,5 +279,93 @@ if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
n=`expr $n + 1`
|
||||
|
||||
# Test dnssec sign statistics.
|
||||
zone="dnssec"
|
||||
stat_prefix="dnskey sign operations"
|
||||
ksk_id=`cat ns2/$zone.ksk.id`
|
||||
zsk_id=`cat ns2/$zone.zsk.id`
|
||||
|
||||
# 1. Test sign operations for scheduled resigning.
|
||||
ret=0
|
||||
# The dnssec zone has 10 RRsets to sign (including NSEC) with the ZSK and one
|
||||
# RRset (DNSKEY) with the KSK. So starting named with signatures that expire
|
||||
# almost right away, this should trigger 10 zsk and 1 ksk sign operations.
|
||||
# However, the DNSSEC maintenance assumes when we see the SOA record we have
|
||||
# walked the whole zone, since the SOA record should always have the most
|
||||
# recent signature. This however is not always the case, for example when
|
||||
# the signature expiration is the same, `dns_db_getsigningtime could return
|
||||
# the SOA RRset before a competing RRset. This happens here and so the
|
||||
# SOA RRset is updated and resigned twice at startup, that explains the
|
||||
# additional zsk sign operation (11 instead of 10).
|
||||
echo "${stat_prefix} ${zsk_id}: 11" > zones.expect
|
||||
echo "${stat_prefix} ${ksk_id}: 1" >> zones.expect
|
||||
cat zones.expect | sort > zones.expect.$n
|
||||
rm -f zones.expect
|
||||
# Fetch and check the dnssec sign statistics.
|
||||
echo_i "fetching zone stats data after zone maintenance at startup ($n)"
|
||||
if [ $PERL_XML ]; then
|
||||
getzones xml x$n || ret=1
|
||||
cmp zones.out.x$n zones.expect.$n || ret=1
|
||||
fi
|
||||
if [ $PERL_JSON ]; then
|
||||
getzones json j$n || ret=1
|
||||
cmp zones.out.j$n zones.expect.$n || ret=1
|
||||
fi
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
n=`expr $n + 1`
|
||||
|
||||
# 2. Test sign operations after dynamic update.
|
||||
ret=0
|
||||
(
|
||||
# Update dnssec zone to trigger signature creation.
|
||||
echo zone $zone
|
||||
echo server 10.53.0.2 "$PORT"
|
||||
echo update add $zone. 300 in txt "nsupdate added me"
|
||||
echo send
|
||||
) | $NSUPDATE
|
||||
# This should trigger the resign of SOA, TXT and NSEC (+3 zsk).
|
||||
echo "${stat_prefix} ${zsk_id}: 14" > zones.expect
|
||||
echo "${stat_prefix} ${ksk_id}: 1" >> zones.expect
|
||||
cat zones.expect | sort > zones.expect.$n
|
||||
rm -f zones.expect
|
||||
# Fetch and check the dnssec sign statistics.
|
||||
echo_i "fetching zone stats data after dynamic update ($n)"
|
||||
if [ $PERL_XML ]; then
|
||||
getzones xml x$n || ret=1
|
||||
cmp zones.out.x$n zones.expect.$n || ret=1
|
||||
fi
|
||||
if [ $PERL_JSON ]; then
|
||||
getzones json j$n || ret=1
|
||||
cmp zones.out.j$n zones.expect.$n || ret=1
|
||||
fi
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
n=`expr $n + 1`
|
||||
|
||||
# 3. Test sign operations of KSK.
|
||||
ret=0
|
||||
# Add a standby DNSKEY, this triggers resigning the DNSKEY RRset.
|
||||
zsk=$("$KEYGEN" -K ns2 -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone")
|
||||
$SETTIME -K ns2 -P now -A never $zsk.key > /dev/null
|
||||
loadkeys_on 2 $zone || ret=1
|
||||
# This should trigger the resign of SOA (+1 zsk) and DNSKEY (+1 ksk).
|
||||
echo "${stat_prefix} ${zsk_id}: 15" > zones.expect
|
||||
echo "${stat_prefix} ${ksk_id}: 2" >> zones.expect
|
||||
cat zones.expect | sort > zones.expect.$n
|
||||
rm -f zones.expect
|
||||
# Fetch and check the dnssec sign statistics.
|
||||
if [ $PERL_XML ]; then
|
||||
getzones xml x$n || ret=1
|
||||
cmp zones.out.x$n zones.expect.$n || ret=1
|
||||
fi
|
||||
if [ $PERL_JSON ]; then
|
||||
getzones json j$n || ret=1
|
||||
cmp zones.out.j$n zones.expect.$n || ret=1
|
||||
fi
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
n=`expr $n + 1`
|
||||
|
||||
echo_i "exit status: $status"
|
||||
[ $status -eq 0 ] || exit 1
|
||||
|
||||
30
bin/tests/system/statschannel/zones-json.pl
Normal file
30
bin/tests/system/statschannel/zones-json.pl
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# 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 http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
# zones-json.pl:
|
||||
# Parses the JSON version of the dnssec sign stats for the
|
||||
# "dnssec" zone in the default view into a normalized format.
|
||||
|
||||
use JSON;
|
||||
|
||||
my $file = $ARGV[0];
|
||||
open(INPUT, "<$file");
|
||||
my $text = do{local$/;<INPUT>};
|
||||
close(INPUT);
|
||||
|
||||
my $ref = decode_json($text);
|
||||
|
||||
|
||||
my $dnssecsign = $ref->{views}->{_default}->{zones}[0]->{"dnssec"};
|
||||
my $type = "dnskey sign operations ";
|
||||
foreach $key (keys %{$dnssecsign}) {
|
||||
print $type . $key . ": ". $dnssecsign->{$key} ."\n";
|
||||
}
|
||||
38
bin/tests/system/statschannel/zones-xml.pl
Normal file
38
bin/tests/system/statschannel/zones-xml.pl
Normal file
@@ -0,0 +1,38 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# 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 http://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
# zones-xml.pl:
|
||||
# Parses the XML version of the dnssec sign stats for the
|
||||
# "dnssec" zone in the default view into a normalized format.
|
||||
|
||||
use XML::Simple;
|
||||
|
||||
my $file = $ARGV[0];
|
||||
|
||||
my $ref = XMLin($file);
|
||||
|
||||
my $counters = $ref->{views}->{view}->{_default}->{zones}->{zone}->{dnssec}->{counters};
|
||||
|
||||
foreach $group (@$counters) {
|
||||
|
||||
my $type = $group->{type};
|
||||
|
||||
if ($type eq "dnssec") {
|
||||
my $prefix = "dnskey sign operations ";
|
||||
if (exists $group->{counter}->{name}) {
|
||||
print $prefix . $group->{counter}->{name} . ": " . $group->{counter}->{content} . "\n";
|
||||
} else {
|
||||
foreach $key (keys %{$group->{counter}}) {
|
||||
print $prefix . $key . ": ". $group->{counter}->{$key}->{content} ."\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1064,6 +1064,7 @@
|
||||
./bin/tests/system/statschannel/clean.sh SH 2015,2016,2017,2018,2019
|
||||
./bin/tests/system/statschannel/fetch.pl PERL 2015,2016,2018,2019
|
||||
./bin/tests/system/statschannel/mem-xml.pl PERL 2017,2018,2019
|
||||
./bin/tests/system/statschannel/ns2/sign.sh SH 2019
|
||||
./bin/tests/system/statschannel/prereq.sh SH 2015,2016,2018,2019
|
||||
./bin/tests/system/statschannel/server-json.pl PERL 2015,2016,2017,2018,2019
|
||||
./bin/tests/system/statschannel/server-xml.pl PERL 2015,2016,2017,2018,2019
|
||||
@@ -1076,6 +1077,8 @@
|
||||
./bin/tests/system/statschannel/traffic.expect.4 X 2015,2018,2019
|
||||
./bin/tests/system/statschannel/traffic.expect.5 X 2015,2016,2018,2019
|
||||
./bin/tests/system/statschannel/traffic.expect.6 X 2015,2016,2018,2019
|
||||
./bin/tests/system/statschannel/zones-json.pl PERL 2019
|
||||
./bin/tests/system/statschannel/zones-xml.pl PERL 2019
|
||||
./bin/tests/system/stop.pl SH 2001,2004,2005,2006,2007,2012,2016,2017,2018,2019
|
||||
./bin/tests/system/stop.sh SH 2000,2001,2004,2007,2012,2016,2018,2019
|
||||
./bin/tests/system/stopall.sh SH 2018,2019
|
||||
|
||||
Reference in New Issue
Block a user