]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Verify mirror zone AXFRs
authorMichał Kępień <michal@isc.org>
Thu, 28 Jun 2018 11:38:39 +0000 (13:38 +0200)
committerMichał Kępień <michal@isc.org>
Thu, 28 Jun 2018 11:38:39 +0000 (13:38 +0200)
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.

bin/tests/system/mirror/clean.sh
bin/tests/system/mirror/ns2/named.conf.in
bin/tests/system/mirror/ns2/sign.sh [new file with mode: 0644]
bin/tests/system/mirror/ns2/verify.db.in [new file with mode: 0644]
bin/tests/system/mirror/ns3/named.conf.in
bin/tests/system/mirror/setup.sh
bin/tests/system/mirror/tests.sh
lib/dns/xfrin.c
lib/dns/zone.c
util/copyrights

index 983f1ac2734789d0a715397437a34d5d153626fc..e856da152134764cd3fb66ba1412a84214fd4227 100644 (file)
@@ -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.*
index f8208e82a7a40097113719a0cda91f85857e77f8..04803c27acc622861e99ac84eb9ca57fab9fd997 100644 (file)
@@ -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";
+};
diff --git a/bin/tests/system/mirror/ns2/sign.sh b/bin/tests/system/mirror/ns2/sign.sh
new file mode 100644 (file)
index 0000000..df40ab7
--- /dev/null
@@ -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
diff --git a/bin/tests/system/mirror/ns2/verify.db.in b/bin/tests/system/mirror/ns2/verify.db.in
new file mode 100644 (file)
index 0000000..dbee4c7
--- /dev/null
@@ -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
index 4d6b2ad5c5dfda5b5b0219cbc2d47d5b2855451a..5452695f0285a69e1e1d3f41c2693f7bf5d41cf0 100644 (file)
@@ -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";
index 5093722efe0c01fa9d19ff3a4ebb05b872c5dc34..9204787cb6f4ef9d50fb4da980fb90f50da511db 100644 (file)
@@ -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
index fdc0eda190e9b60a4af85042c155ff494cc04675..a6e0417a9690bd73eda73dcc5c8292f08472127c 100644 (file)
@@ -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
index b3186bc67e26073ff61cf7522c802d20217837f0..6fad0b840372e2498112d86957cd7a649ba6866f 100644 (file)
@@ -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:
index 2f4f15464e1bd84e86e4766cfed71f81decec403..667a83466e5a9b24ae61becd8715ed4e77d17d08 100644 (file)
@@ -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;
index b87da463e4dcb402d39fb948d772519eaf5ffbeb..ef2bbb0a3d011b41741a3b86f83df26a3e3e7ce2 100644 (file)
 ./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