mirror of
https://github.com/isc-projects/bind9.git
synced 2026-04-15 22:09:31 -04:00
Verify mirror zone AXFRs
Update axfr_commit() so that all incoming versions of a mirror zone transferred using AXFR are verified before being used. If zone verification fails, discard the received version of the zone, wait until the next refresh and retry.
This commit is contained in:
parent
eaf1c0f6eb
commit
d86f1d00ad
10 changed files with 184 additions and 0 deletions
|
|
@ -8,5 +8,13 @@
|
|||
# information regarding copyright ownership.
|
||||
|
||||
rm -f */*.conf
|
||||
rm -f */*.db
|
||||
rm -f */*.mirror
|
||||
rm -f */*.prev
|
||||
rm -f */*.signed
|
||||
rm -f */K*
|
||||
rm -f */db-*
|
||||
rm -f */dsset-*
|
||||
rm -f */named.memstats
|
||||
rm -f */named.run
|
||||
rm -f dig.out.*
|
||||
|
|
|
|||
|
|
@ -9,6 +9,15 @@
|
|||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.2;
|
||||
notify-source 10.53.0.2;
|
||||
|
|
@ -19,3 +28,18 @@ options {
|
|||
listen-on-v6 { none; };
|
||||
recursion no;
|
||||
};
|
||||
|
||||
zone "verify-axfr" {
|
||||
type master;
|
||||
file "verify-axfr.db.signed";
|
||||
};
|
||||
|
||||
zone "verify-unsigned" {
|
||||
type master;
|
||||
file "verify.db.in";
|
||||
};
|
||||
|
||||
zone "verify-untrusted" {
|
||||
type master;
|
||||
file "verify-untrusted.db.signed";
|
||||
};
|
||||
|
|
|
|||
48
bin/tests/system/mirror/ns2/sign.sh
Normal file
48
bin/tests/system/mirror/ns2/sign.sh
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#!/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.
|
||||
|
||||
SYSTEMTESTTOP=../..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
|
||||
keys_to_trust=""
|
||||
|
||||
ORIGINAL_SERIAL=`awk '$2 == "SOA" {print $5}' verify.db.in`
|
||||
UPDATED_SERIAL_BAD=`expr ${ORIGINAL_SERIAL} + 1`
|
||||
UPDATED_SERIAL_GOOD=`expr ${ORIGINAL_SERIAL} + 2`
|
||||
|
||||
for variant in axfr untrusted; do
|
||||
zone=verify-$variant
|
||||
infile=verify.db.in
|
||||
zonefile=verify-$variant.db
|
||||
|
||||
keyname1=`$KEYGEN -a RSASHA256 -f KSK $zone 2> /dev/null`
|
||||
keyname2=`$KEYGEN -a RSASHA256 $zone 2> /dev/null`
|
||||
|
||||
cat $infile $keyname1.key $keyname2.key > $zonefile
|
||||
|
||||
# Prepare a properly signed version of the zone ("*.original.signed").
|
||||
$SIGNER -P -o $zone $zonefile > /dev/null
|
||||
cp $zonefile.signed $zonefile.original.signed
|
||||
# Prepare a version of the zone with a bogus SOA RRSIG ("*.bad.signed").
|
||||
sed "s/${ORIGINAL_SERIAL}/${UPDATED_SERIAL_BAD}/;" $zonefile.signed > $zonefile.bad.signed
|
||||
# Prepare another properly signed version of the zone ("*.good.signed").
|
||||
sed "s/${ORIGINAL_SERIAL}/${UPDATED_SERIAL_GOOD}/;" $zonefile > $zonefile.good
|
||||
$SIGNER -P -o $zone $zonefile.good > /dev/null
|
||||
rm -f $zonefile.good
|
||||
|
||||
# Except for the "verify-untrusted" zone, declare the KSK used for
|
||||
# signing the zone to be a trust anchor for ns3.
|
||||
if [ "$variant" != "untrusted" ]; then
|
||||
keys_to_trust="$keys_to_trust $keyname1"
|
||||
fi
|
||||
done
|
||||
|
||||
keyfile_to_trusted_keys $keys_to_trust > trusted-mirror.conf
|
||||
13
bin/tests/system/mirror/ns2/verify.db.in
Normal file
13
bin/tests/system/mirror/ns2/verify.db.in
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
; 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.
|
||||
|
||||
$TTL 3600
|
||||
@ SOA ns2 hostmaster 2000010100 3600 1200 604800 3600
|
||||
@ NS ns2
|
||||
ns2 A 10.53.0.2
|
||||
|
|
@ -9,6 +9,15 @@
|
|||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.3;
|
||||
notify-source 10.53.0.3;
|
||||
|
|
@ -24,3 +33,26 @@ zone "." {
|
|||
type hint;
|
||||
file "../../common/root.hint";
|
||||
};
|
||||
|
||||
zone "verify-axfr" {
|
||||
type slave;
|
||||
masters { 10.53.0.2; };
|
||||
mirror yes;
|
||||
file "verify-axfr.db.mirror";
|
||||
};
|
||||
|
||||
zone "verify-unsigned" {
|
||||
type slave;
|
||||
masters { 10.53.0.2; };
|
||||
mirror yes;
|
||||
file "verify-unsigned.db.mirror";
|
||||
};
|
||||
|
||||
zone "verify-untrusted" {
|
||||
type slave;
|
||||
masters { 10.53.0.2; };
|
||||
mirror yes;
|
||||
file "verify-untrusted.db.mirror";
|
||||
};
|
||||
|
||||
include "../ns2/trusted-mirror.conf";
|
||||
|
|
|
|||
|
|
@ -17,3 +17,8 @@ $SHELL clean.sh
|
|||
copy_setports ns1/named.conf.in ns1/named.conf
|
||||
copy_setports ns2/named.conf.in ns2/named.conf
|
||||
copy_setports ns3/named.conf.in ns3/named.conf
|
||||
|
||||
( cd ns2 && $SHELL -e sign.sh )
|
||||
|
||||
cat ns2/verify-axfr.db.bad.signed > ns2/verify-axfr.db.signed
|
||||
cat ns2/verify-untrusted.db.original.signed > ns2/verify-untrusted.db.signed
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
SYSTEMTESTTOP=..
|
||||
. $SYSTEMTESTTOP/conf.sh
|
||||
|
||||
DIGOPTS="-p ${PORT} +dnssec +time=1 +tries=1 +multi"
|
||||
RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s"
|
||||
|
||||
# Wait until the transfer of the given zone to ns3 either completes successfully
|
||||
|
|
@ -51,5 +52,54 @@ reload_zone() {
|
|||
status=0
|
||||
n=0
|
||||
|
||||
ORIGINAL_SERIAL=`awk '$2 == "SOA" {print $5}' ns2/verify.db.in`
|
||||
UPDATED_SERIAL_BAD=`expr ${ORIGINAL_SERIAL} + 1`
|
||||
UPDATED_SERIAL_GOOD=`expr ${ORIGINAL_SERIAL} + 2`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "checking that an unsigned mirror zone is rejected ($n)"
|
||||
ret=0
|
||||
wait_for_transfer verify-unsigned
|
||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-unsigned SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
||||
nextpart ns3/named.run | grep "verify-unsigned.*Zone contains no DNSSEC keys" > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "checking that a mirror zone signed using an untrusted key is rejected ($n)"
|
||||
ret=0
|
||||
nextpartreset ns3/named.run
|
||||
wait_for_transfer verify-untrusted
|
||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-untrusted SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
||||
nextpart ns3/named.run | grep "verify-untrusted.*No trusted KSK DNSKEY found" > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "checking that an AXFR of an incorrectly signed mirror zone is rejected ($n)"
|
||||
ret=0
|
||||
nextpartreset ns3/named.run
|
||||
wait_for_transfer verify-axfr
|
||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-axfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||
grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1
|
||||
nextpart ns3/named.run | grep "No correct RSASHA256 signature for verify-axfr SOA" > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
n=`expr $n + 1`
|
||||
echo_i "checking that an AXFR of an updated, correctly signed mirror zone is accepted ($n)"
|
||||
ret=0
|
||||
nextpart ns3/named.run > /dev/null
|
||||
cat ns2/verify-axfr.db.good.signed > ns2/verify-axfr.db.signed
|
||||
reload_zone verify-axfr ${UPDATED_SERIAL_GOOD}
|
||||
$RNDCCMD 10.53.0.3 retransfer verify-axfr > /dev/null 2>&1
|
||||
wait_for_transfer verify-axfr
|
||||
$DIG $DIGOPTS @10.53.0.3 +norec verify-axfr SOA > dig.out.ns3.test$n 2>&1 || ret=1
|
||||
grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1
|
||||
if [ $ret != 0 ]; then echo_i "failed"; fi
|
||||
status=`expr $status + $ret`
|
||||
|
||||
echo_i "exit status: $status"
|
||||
[ $status -eq 0 ] || exit 1
|
||||
|
|
|
|||
|
|
@ -334,6 +334,7 @@ axfr_commit(dns_xfrin_ctx_t *xfr) {
|
|||
|
||||
CHECK(axfr_apply(xfr));
|
||||
CHECK(dns_db_endload(xfr->db, &xfr->axfr));
|
||||
CHECK(dns_zone_verifydb(xfr->zone, xfr->db, NULL));
|
||||
|
||||
result = ISC_R_SUCCESS;
|
||||
failure:
|
||||
|
|
|
|||
|
|
@ -15305,6 +15305,7 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
|
|||
goto same_master;
|
||||
|
||||
case DNS_R_TOOMANYRECORDS:
|
||||
case DNS_R_VERIFYFAILURE:
|
||||
DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
|
||||
inc_stats(zone, dns_zonestatscounter_xfrfail);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1599,6 +1599,8 @@
|
|||
./bin/tests/system/mirror/ns1/named.conf.in CONF-C 2018
|
||||
./bin/tests/system/mirror/ns1/root.db.in ZONE 2018
|
||||
./bin/tests/system/mirror/ns2/named.conf.in CONF-C 2018
|
||||
./bin/tests/system/mirror/ns2/sign.sh SH 2018
|
||||
./bin/tests/system/mirror/ns2/verify.db.in ZONE 2018
|
||||
./bin/tests/system/mirror/ns3/named.conf.in CONF-C 2018
|
||||
./bin/tests/system/mirror/setup.sh SH 2018
|
||||
./bin/tests/system/mirror/tests.sh SH 2018
|
||||
|
|
|
|||
Loading…
Reference in a new issue