1#!/bin/sh 2# 3# Copyright (C) Internet Systems Consortium, Inc. ("ISC") 4# 5# This Source Code Form is subject to the terms of the Mozilla Public 6# License, v. 2.0. If a copy of the MPL was not distributed with this 7# file, You can obtain one at http://mozilla.org/MPL/2.0/. 8# 9# See the COPYRIGHT file distributed with this work for additional 10# information regarding copyright ownership. 11 12SYSTEMTESTTOP=.. 13. $SYSTEMTESTTOP/conf.sh 14 15DIGOPTS="-p ${PORT} -b 10.53.0.1 +dnssec +time=2 +tries=1 +multi" 16RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s" 17 18# Wait until the transfer of the given zone to ns3 either completes successfully 19# or is aborted by a verification failure or a REFUSED response from the master. 20# Note that matching on any transfer status is deliberately avoided because some 21# checks performed by this test cause transfer attempts to end with the "IXFR 22# failed" status, which is followed by an AXFR retry and this test needs to 23# check what the result of the latter transfer attempt is. 24wait_for_transfer() { 25 zone=$1 26 for i in 1 2 3 4 5 6 7 8 9 10; do 27 # Wait until a "freeing transfer context" message is logged 28 # after one of the transfer results we are looking for is 29 # logged. This is needed to prevent races when checking for 30 # "mirror zone is now in use" messages. 31 nextpartpeek ns3/named.run | \ 32 awk "matched; /'$zone\/IN'.*Transfer status: (success|verify failure|REFUSED)/ {matched=1}" | \ 33 grep "'$zone/IN'.*freeing transfer context" > /dev/null && return 34 sleep 1 35 done 36 echo_i "exceeded time limit waiting for proof of '$zone' being transferred to appear in ns3/named.run" 37 ret=1 38} 39 40# Wait until loading the given zone on the given server either completes 41# successfully for the specified serial number or fails. 42wait_for_load() { 43 zone=$1 44 serial=$2 45 log=$3 46 for i in 1 2 3 4 5 6 7 8 9 10; do 47 # Wait until a "zone_postload: (...): done" message is logged 48 # after one of the loading-related messages we are looking for 49 # is logged. This is needed to prevent races when checking for 50 # "mirror zone is now in use" messages. 51 nextpartpeek $log | \ 52 awk "matched; /$zone.*(loaded serial $serial|unable to load)/ {matched=1}" | \ 53 grep "zone_postload: zone $zone/IN: done" > /dev/null && return 54 sleep 1 55 done 56 echo_i "exceeded time limit waiting for proof of '$zone' being loaded to appear in $log" 57 ret=1 58} 59 60# Trigger a reload of ns2 and wait until loading the given zone completes. 61reload_zone() { 62 zone=$1 63 serial=$2 64 rndc_reload ns2 10.53.0.2 65 wait_for_load $zone $serial ns2/named.run 66} 67 68status=0 69n=0 70 71ORIGINAL_SERIAL=`awk '$2 == "SOA" {print $5}' ns2/verify.db.in` 72UPDATED_SERIAL_BAD=`expr ${ORIGINAL_SERIAL} + 1` 73UPDATED_SERIAL_GOOD=`expr ${ORIGINAL_SERIAL} + 2` 74 75n=`expr $n + 1` 76echo_i "checking that an unsigned mirror zone is rejected ($n)" 77ret=0 78wait_for_transfer verify-unsigned 79$DIG $DIGOPTS @10.53.0.3 +norec verify-unsigned SOA > dig.out.ns3.test$n 2>&1 || ret=1 80grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 81grep "${ORIGINAL_SERIAL}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1 82nextpartpeek ns3/named.run | grep "verify-unsigned.*Zone contains no DNSSEC keys" > /dev/null || ret=1 83nextpartpeek ns3/named.run | grep "verify-unsigned.*mirror zone is now in use" > /dev/null && ret=1 84if [ $ret != 0 ]; then echo_i "failed"; fi 85status=`expr $status + $ret` 86 87n=`expr $n + 1` 88echo_i "checking that a mirror zone signed using an untrusted key is rejected ($n)" 89ret=0 90nextpartreset ns3/named.run 91wait_for_transfer verify-untrusted 92$DIG $DIGOPTS @10.53.0.3 +norec verify-untrusted SOA > dig.out.ns3.test$n 2>&1 || ret=1 93grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 94grep "${ORIGINAL_SERIAL}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1 95nextpartpeek ns3/named.run | grep "verify-untrusted.*No trusted DNSKEY found" > /dev/null || ret=1 96nextpartpeek ns3/named.run | grep "verify-untrusted.*mirror zone is now in use" > /dev/null && ret=1 97if [ $ret != 0 ]; then echo_i "failed"; fi 98status=`expr $status + $ret` 99 100n=`expr $n + 1` 101echo_i "checking that a mirror zone signed using a CSK without the SEP bit set is accepted ($n)" 102ret=0 103nextpartreset ns3/named.run 104wait_for_transfer verify-csk 105$DIG $DIGOPTS @10.53.0.3 +norec verify-csk SOA > dig.out.ns3.test$n 2>&1 || ret=1 106grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null && ret=1 107grep "${ORIGINAL_SERIAL}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1 108nextpartpeek ns3/named.run | grep "verify-csk.*mirror zone is now in use" > /dev/null || ret=1 109if [ $ret != 0 ]; then echo_i "failed"; fi 110status=`expr $status + $ret` 111 112n=`expr $n + 1` 113echo_i "checking that an AXFR of an incorrectly signed mirror zone is rejected ($n)" 114ret=0 115nextpartreset ns3/named.run 116wait_for_transfer verify-axfr 117$DIG $DIGOPTS @10.53.0.3 +norec verify-axfr SOA > dig.out.ns3.test$n 2>&1 || ret=1 118grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 119grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1 120nextpartpeek ns3/named.run | grep "No correct RSASHA256 signature for verify-axfr SOA" > /dev/null || ret=1 121nextpartpeek ns3/named.run | grep "verify-axfr.*mirror zone is now in use" > /dev/null && ret=1 122if [ $ret != 0 ]; then echo_i "failed"; fi 123status=`expr $status + $ret` 124 125n=`expr $n + 1` 126echo_i "checking that an AXFR of an updated, correctly signed mirror zone is accepted ($n)" 127ret=0 128nextpart ns3/named.run > /dev/null 129cat ns2/verify-axfr.db.good.signed > ns2/verify-axfr.db.signed 130reload_zone verify-axfr ${UPDATED_SERIAL_GOOD} 131$RNDCCMD 10.53.0.3 retransfer verify-axfr > /dev/null 2>&1 132wait_for_transfer verify-axfr 133$DIG $DIGOPTS @10.53.0.3 +norec verify-axfr SOA > dig.out.ns3.test$n 2>&1 || ret=1 134grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null && ret=1 135grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1 136nextpartpeek ns3/named.run | grep "verify-axfr.*mirror zone is now in use" > /dev/null || ret=1 137if [ $ret != 0 ]; then echo_i "failed"; fi 138status=`expr $status + $ret` 139 140n=`expr $n + 1` 141echo_i "checking that an IXFR of an incorrectly signed mirror zone is rejected ($n)" 142nextpartreset ns3/named.run 143ret=0 144wait_for_transfer verify-ixfr 145# Sanity check: the initial, properly signed version of the zone should have 146# been announced as coming into effect. 147nextpart ns3/named.run | grep "verify-ixfr.*mirror zone is now in use" > /dev/null || ret=1 148# Make a copy of the original zone file for reuse in journal tests below. 149cp ns2/verify-ixfr.db.signed ns3/verify-journal.db.mirror 150# Wait 1 second so that the zone file timestamp changes and the subsequent 151# invocation of "rndc reload" triggers a zone reload. 152sleep 1 153cat ns2/verify-ixfr.db.bad.signed > ns2/verify-ixfr.db.signed 154reload_zone verify-ixfr ${UPDATED_SERIAL_BAD} 155# Make a copy of the bad zone journal for reuse in journal tests below. 156cp ns2/verify-ixfr.db.signed.jnl ns3/verify-journal.db.bad.mirror.jnl 157# Trigger IXFR. 158$RNDCCMD 10.53.0.3 refresh verify-ixfr > /dev/null 2>&1 159wait_for_transfer verify-ixfr 160# Ensure the transfer was incremental as expected. 161if [ `nextpartpeek ns3/named.run | grep "verify-ixfr.*got incremental response" | wc -l` -eq 0 ]; then 162 echo_i "failed: did not get an incremental response" 163 ret=1 164fi 165# Ensure the new, bad version of the zone was not accepted. 166$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1 167# A positive answer is expected as the original version of the "verify-ixfr" 168# zone should have been successfully verified. 169grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null && ret=1 170grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1 171nextpartpeek ns3/named.run | grep "No correct RSASHA256 signature for verify-ixfr SOA" > /dev/null || ret=1 172# Despite the verification failure for this IXFR, this mirror zone should still 173# be in use as its previous version should have been verified successfully. 174nextpartpeek ns3/named.run | grep "verify-ixfr.*mirror zone is no longer in use" > /dev/null && ret=1 175if [ $ret != 0 ]; then echo_i "failed"; fi 176status=`expr $status + $ret` 177 178n=`expr $n + 1` 179echo_i "checking that an IXFR of an updated, correctly signed mirror zone is accepted after AXFR failover ($n)" 180ret=0 181nextpart ns3/named.run > /dev/null 182# Wait 1 second so that the zone file timestamp changes and the subsequent 183# invocation of "rndc reload" triggers a zone reload. 184sleep 1 185cat ns2/verify-ixfr.db.good.signed > ns2/verify-ixfr.db.signed 186reload_zone verify-ixfr ${UPDATED_SERIAL_GOOD} 187# Make a copy of the good zone journal for reuse in journal tests below. 188cp ns2/verify-ixfr.db.signed.jnl ns3/verify-journal.db.good.mirror.jnl 189# Trigger IXFR. 190$RNDCCMD 10.53.0.3 refresh verify-ixfr > /dev/null 2>&1 191wait_for_transfer verify-ixfr 192# Ensure the new, good version of the zone was accepted. 193$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1 194grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null && ret=1 195grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1 196# The log message announcing the mirror zone coming into effect should not have 197# been logged this time since the mirror zone in question is expected to 198# already be in use before this test case is checked. 199nextpartpeek ns3/named.run | grep "verify-ixfr.*mirror zone is now in use" > /dev/null && ret=1 200if [ $ret != 0 ]; then echo_i "failed"; fi 201status=`expr $status + $ret` 202 203n=`expr $n + 1` 204echo_i "checking that loading an incorrectly signed mirror zone from disk fails ($n)" 205ret=0 206nextpartreset ns3/named.run 207wait_for_load verify-load ${UPDATED_SERIAL_BAD} ns3/named.run 208$DIG $DIGOPTS @10.53.0.3 +norec verify-load SOA > dig.out.ns3.test$n 2>&1 || ret=1 209grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 210grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1 211nextpartpeek ns3/named.run | grep "No correct RSASHA256 signature for verify-load SOA" > /dev/null || ret=1 212nextpartpeek ns3/named.run | grep "verify-load.*mirror zone is now in use" > /dev/null && ret=1 213if [ $ret != 0 ]; then echo_i "failed"; fi 214status=`expr $status + $ret` 215 216n=`expr $n + 1` 217echo_i "ensuring trust anchor telemetry queries are sent upstream for a mirror zone ($n)" 218ret=0 219# ns3 is started with "-T tat=3", so TAT queries should have already been sent. 220grep "_ta-[-0-9a-f]*/NULL" ns1/named.run > /dev/null || ret=1 221if [ $ret != 0 ]; then echo_i "failed"; fi 222status=`expr $status + $ret` 223 224n=`expr $n + 1` 225echo_i "checking that loading a correctly signed mirror zone from disk succeeds ($n)" 226ret=0 227$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} mirror ns3 228cat ns2/verify-load.db.good.signed > ns3/verify-load.db.mirror 229nextpart ns3/named.run > /dev/null 230$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} mirror ns3 231wait_for_load verify-load ${UPDATED_SERIAL_GOOD} ns3/named.run 232$DIG $DIGOPTS @10.53.0.3 +norec verify-load SOA > dig.out.ns3.test$n 2>&1 || ret=1 233grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null && ret=1 234grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1 235nextpartpeek ns3/named.run | grep "verify-load.*mirror zone is now in use" > /dev/null || ret=1 236if [ $ret != 0 ]; then echo_i "failed"; fi 237status=`expr $status + $ret` 238 239n=`expr $n + 1` 240echo_i "checking that loading a journal for an incorrectly signed mirror zone fails ($n)" 241ret=0 242$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} mirror ns3 243cp ns3/verify-journal.db.mirror ns3/verify-ixfr.db.mirror 244cp ns3/verify-journal.db.bad.mirror.jnl ns3/verify-ixfr.db.mirror.jnl 245# Temporarily disable transfers of the "verify-ixfr" zone on ns2. This is 246# required to reliably test whether the message announcing the mirror zone 247# coming into effect is not logged after a failed journal verification since 248# otherwise a corrected version of the zone may be transferred after 249# verification fails but before we look for the aforementioned log message. 250# (NOTE: Keep the embedded newline in the sed function list below.) 251sed '/^zone "verify-ixfr" {$/,/^};$/ { 252 s/10.53.0.3/10.53.0.254/ 253}' ns2/named.conf > ns2/named.conf.modified 254mv ns2/named.conf.modified ns2/named.conf 255rndc_reconfig ns2 10.53.0.2 256nextpart ns3/named.run > /dev/null 257$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} mirror ns3 258wait_for_load verify-ixfr ${UPDATED_SERIAL_BAD} ns3/named.run 259$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1 260grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 261grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1 262nextpartpeek ns3/named.run | grep "No correct RSASHA256 signature for verify-ixfr SOA" > /dev/null || ret=1 263nextpartpeek ns3/named.run | grep "verify-ixfr.*mirror zone is now in use" > /dev/null && ret=1 264# Restore transfers for the "verify-ixfr" zone on ns2. 265# (NOTE: Keep the embedded newline in the sed function list below.) 266sed '/^zone "verify-ixfr" {$/,/^};$/ { 267 s/10.53.0.254/10.53.0.3/ 268}' ns2/named.conf > ns2/named.conf.modified 269mv ns2/named.conf.modified ns2/named.conf 270rndc_reconfig ns2 10.53.0.2 271if [ $ret != 0 ]; then echo_i "failed"; fi 272status=`expr $status + $ret` 273 274n=`expr $n + 1` 275echo_i "checking that loading a journal for a correctly signed mirror zone succeeds ($n)" 276ret=0 277$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} mirror ns3 278cp ns3/verify-journal.db.mirror ns3/verify-ixfr.db.mirror 279cp ns3/verify-journal.db.good.mirror.jnl ns3/verify-ixfr.db.mirror.jnl 280nextpart ns3/named.run > /dev/null 281$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} mirror ns3 282wait_for_load verify-ixfr ${UPDATED_SERIAL_GOOD} ns3/named.run 283$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1 284grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null && ret=1 285grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1 286nextpartpeek ns3/named.run | grep "verify-ixfr.*mirror zone is now in use" > /dev/null || ret=1 287if [ $ret != 0 ]; then echo_i "failed"; fi 288status=`expr $status + $ret` 289 290n=`expr $n + 1` 291echo_i "checking delegations sourced from a mirror zone ($n)" 292ret=0 293$DIG $DIGOPTS @10.53.0.3 foo.example A +norec > dig.out.ns3.test$n 2>&1 || ret=1 294# Check response code and flags in the answer. 295grep "NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 296grep "flags:.* ad" dig.out.ns3.test$n > /dev/null && ret=1 297# Check that a delegation containing a DS RRset and glue is present. 298grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null || ret=1 299grep "example.*IN.*NS" dig.out.ns3.test$n > /dev/null || ret=1 300grep "example.*IN.*DS" dig.out.ns3.test$n > /dev/null || ret=1 301grep "ns2.example.*A.*10.53.0.2" dig.out.ns3.test$n > /dev/null || ret=1 302if [ $ret != 0 ]; then echo_i "failed"; fi 303status=`expr $status + $ret` 304 305n=`expr $n + 1` 306echo_i "checking that resolution involving a mirror zone works as expected ($n)" 307ret=0 308$DIG $DIGOPTS @10.53.0.3 foo.example A > dig.out.ns3.test$n 2>&1 || ret=1 309# Check response code and flags in the answer. 310grep "NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 311grep "flags:.* ad" dig.out.ns3.test$n > /dev/null || ret=1 312# Ensure ns1 was not queried. 313grep "query 'foo.example/A/IN'" ns1/named.run > /dev/null && ret=1 314if [ $ret != 0 ]; then echo_i "failed"; fi 315status=`expr $status + $ret` 316 317n=`expr $n + 1` 318echo_i "checking that non-recursive queries for names below mirror zone get responded from cache ($n)" 319ret=0 320# Issue a non-recursive query for an RRset which is expected to be in cache. 321$DIG $DIGOPTS @10.53.0.3 +norec foo.example. A > dig.out.ns3.test$n 2>&1 || ret=1 322# Check response code and flags in the answer. 323grep "NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 324grep "flags:.* ad" dig.out.ns3.test$n > /dev/null || ret=1 325# Ensure the response is not a delegation. 326grep "ANSWER: 0" dig.out.ns3.test$n > /dev/null && ret=1 327grep "foo.example.*IN.*A.*127.0.0.1" dig.out.ns3.test$n > /dev/null || ret=1 328if [ $ret != 0 ]; then echo_i "failed"; fi 329status=`expr $status + $ret` 330 331n=`expr $n + 1` 332echo_i "checking that delegations from cache which improve mirror zone delegations are properly handled ($n)" 333ret=0 334# First, issue a recursive query in order to cache an RRset which is not within 335# the mirror zone's bailiwick. 336$DIG $DIGOPTS @10.53.0.3 sub.example. NS > dig.out.ns3.test$n.1 2>&1 || ret=1 337# Ensure the child-side NS RRset is returned. 338grep "NOERROR" dig.out.ns3.test$n.1 > /dev/null || ret=1 339grep "ANSWER: 2" dig.out.ns3.test$n.1 > /dev/null || ret=1 340grep "sub.example.*IN.*NS" dig.out.ns3.test$n.1 > /dev/null || ret=1 341# Issue a non-recursive query for something below the cached zone cut. 342$DIG $DIGOPTS @10.53.0.3 +norec foo.sub.example. A > dig.out.ns3.test$n.2 2>&1 || ret=1 343# Ensure the cached NS RRset is returned in a delegation, along with the 344# parent-side DS RRset. 345grep "NOERROR" dig.out.ns3.test$n.2 > /dev/null || ret=1 346grep "ANSWER: 0" dig.out.ns3.test$n.2 > /dev/null || ret=1 347grep "sub.example.*IN.*NS" dig.out.ns3.test$n.2 > /dev/null || ret=1 348grep "sub.example.*IN.*DS" dig.out.ns3.test$n.2 > /dev/null || ret=1 349if [ $ret != 0 ]; then echo_i "failed"; fi 350status=`expr $status + $ret` 351 352n=`expr $n + 1` 353echo_i "checking flags set in a DNSKEY response sourced from a mirror zone ($n)" 354ret=0 355$DIG $DIGOPTS @10.53.0.3 . DNSKEY > dig.out.ns3.test$n 2>&1 || ret=1 356# Check response code and flags in the answer. 357grep "NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 358grep "flags:.* aa" dig.out.ns3.test$n > /dev/null && ret=1 359grep "flags:.* ad" dig.out.ns3.test$n > /dev/null || ret=1 360if [ $ret != 0 ]; then echo_i "failed"; fi 361status=`expr $status + $ret` 362 363n=`expr $n + 1` 364echo_i "checking flags set in a SOA response sourced from a mirror zone ($n)" 365ret=0 366$DIG $DIGOPTS @10.53.0.3 . SOA > dig.out.ns3.test$n 2>&1 || ret=1 367# Check response code and flags in the answer. 368grep "NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 369grep "flags:.* aa" dig.out.ns3.test$n > /dev/null && ret=1 370grep "flags:.* ad" dig.out.ns3.test$n > /dev/null || ret=1 371if [ $ret != 0 ]; then echo_i "failed"; fi 372status=`expr $status + $ret` 373 374n=`expr $n + 1` 375echo_i "checking that resolution succeeds with unavailable mirror zone data ($n)" 376ret=0 377wait_for_transfer initially-unavailable 378# Query for a record in a zone that is set up to be mirrored, but 379# untransferrable from the configured master. Resolution should still succeed. 380$DIG $DIGOPTS @10.53.0.3 foo.initially-unavailable. A > dig.out.ns3.test$n.1 2>&1 || ret=1 381# Check response code and flags in the answer. 382grep "NOERROR" dig.out.ns3.test$n.1 > /dev/null || ret=1 383grep "flags:.* ad" dig.out.ns3.test$n.1 > /dev/null || ret=1 384# Sanity check: the authoritative server should have been queried. 385nextpart ns2/named.run | grep "query 'foo.initially-unavailable/A/IN'" > /dev/null || ret=1 386# Reconfigure ns2 so that the zone can be mirrored on ns3. 387sed '/^zone "initially-unavailable" {$/,/^};$/ { 388 s/10.53.0.254/10.53.0.3/ 389}' ns2/named.conf > ns2/named.conf.modified 390mv ns2/named.conf.modified ns2/named.conf 391rndc_reconfig ns2 10.53.0.2 392# Flush the cache on ns3 and retransfer the mirror zone. 393$RNDCCMD 10.53.0.3 flush > /dev/null 2>&1 394nextpart ns3/named.run > /dev/null 395$RNDCCMD 10.53.0.3 retransfer initially-unavailable > /dev/null 2>&1 396wait_for_transfer initially-unavailable 397# Query for the same record again. Resolution should still succeed. 398$DIG $DIGOPTS @10.53.0.3 foo.initially-unavailable. A > dig.out.ns3.test$n.2 2>&1 || ret=1 399# Check response code and flags in the answer. 400grep "NOERROR" dig.out.ns3.test$n.2 > /dev/null || ret=1 401grep "flags:.* ad" dig.out.ns3.test$n.2 > /dev/null || ret=1 402# Ensure the authoritative server was not queried. 403nextpart ns2/named.run | grep "query 'foo.initially-unavailable/A/IN'" > /dev/null && ret=1 404if [ $ret != 0 ]; then echo_i "failed"; fi 405status=`expr $status + $ret` 406 407n=`expr $n + 1` 408echo_i "checking that resolution succeeds with expired mirror zone data ($n)" 409ret=0 410# Reconfigure ns2 so that the zone from the previous test can no longer be 411# mirrored on ns3. 412sed '/^zone "initially-unavailable" {$/,/^};$/ { 413 s/10.53.0.3/10.53.0.254/ 414}' ns2/named.conf > ns2/named.conf.modified 415mv ns2/named.conf.modified ns2/named.conf 416rndc_reconfig ns2 10.53.0.2 417# Stop ns3, update the timestamp of the zone file to one far in the past, then 418# restart ns3. 419$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} mirror ns3 420touch -t 200001010000 ns3/initially-unavailable.db.mirror 421nextpart ns3/named.run > /dev/null 422$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} mirror ns3 423# Ensure named attempts to retransfer the zone due to its expiry. 424wait_for_transfer initially-unavailable 425# Ensure the expected messages were logged. 426nextpartpeek ns3/named.run | grep "initially-unavailable.*expired" > /dev/null || ret=1 427nextpartpeek ns3/named.run | grep "initially-unavailable.*mirror zone is no longer in use" > /dev/null || ret=1 428# Query for a record in the expired zone. Resolution should still succeed. 429$DIG $DIGOPTS @10.53.0.3 foo.initially-unavailable. A > dig.out.ns3.test$n 2>&1 || ret=1 430# Check response code and flags in the answer. 431grep "NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 432grep "flags:.* ad" dig.out.ns3.test$n > /dev/null || ret=1 433# Sanity check: the authoritative server should have been queried. 434nextpart ns2/named.run | grep "query 'foo.initially-unavailable/A/IN'" > /dev/null || ret=1 435if [ $ret != 0 ]; then echo_i "failed"; fi 436status=`expr $status + $ret` 437 438n=`expr $n + 1` 439echo_i "checking that clients without cache access cannot retrieve mirror zone data ($n)" 440ret=0 441$DIG $DIGOPTS @10.53.0.3 -b 10.53.0.3 +norec . SOA > dig.out.ns3.test$n 2>&1 || ret=1 442# Check response code and flags in the answer. 443grep "REFUSED" dig.out.ns3.test$n > /dev/null || ret=1 444grep "flags:.* ad" dig.out.ns3.test$n > /dev/null && ret=1 445if [ $ret != 0 ]; then echo_i "failed"; fi 446status=`expr $status + $ret` 447 448n=`expr $n + 1` 449echo_i "checking that outgoing transfers of mirror zones are disabled by default ($n)" 450ret=0 451$DIG $DIGOPTS @10.53.0.3 . AXFR > dig.out.ns3.test$n 2>&1 || ret=1 452grep "; Transfer failed" dig.out.ns3.test$n > /dev/null || ret=1 453if [ $ret != 0 ]; then echo_i "failed"; fi 454status=`expr $status + $ret` 455 456n=`expr $n + 1` 457echo_i "checking that notifies are disabled by default for mirror zones ($n)" 458ret=0 459grep "initially-unavailable.*sending notifies" ns3/named.run > /dev/null && ret=1 460if [ $ret != 0 ]; then echo_i "failed"; fi 461status=`expr $status + $ret` 462 463n=`expr $n + 1` 464echo_i "checking output of \"rndc zonestatus\" for a mirror zone ($n)" 465ret=0 466$RNDCCMD 10.53.0.3 zonestatus . > rndc.out.ns3.test$n 2>&1 467grep "type: mirror" rndc.out.ns3.test$n > /dev/null || ret=1 468if [ $ret != 0 ]; then echo_i "failed"; fi 469status=`expr $status + $ret` 470 471n=`expr $n + 1` 472echo_i "checking that \"rndc reconfig\" properly handles a mirror -> slave zone type change ($n)" 473ret=0 474# Sanity check before we start. 475$DIG $DIGOPTS @10.53.0.3 +norec verify-reconfig SOA > dig.out.ns3.test$n.1 2>&1 || ret=1 476grep "NOERROR" dig.out.ns3.test$n.1 > /dev/null || ret=1 477grep "flags:.* aa" dig.out.ns3.test$n.1 > /dev/null && ret=1 478grep "flags:.* ad" dig.out.ns3.test$n.1 > /dev/null || ret=1 479# Reconfigure the zone so that it is no longer a mirror zone. 480# (NOTE: Keep the embedded newline in the sed function list below.) 481sed '/^zone "verify-reconfig" {$/,/^};$/ { 482 s/type mirror;/type slave;/ 483}' ns3/named.conf > ns3/named.conf.modified 484mv ns3/named.conf.modified ns3/named.conf 485nextpart ns3/named.run > /dev/null 486rndc_reconfig ns3 10.53.0.3 487# Zones whose type was changed should not be reusable, which means the tested 488# zone should have been reloaded from disk. 489wait_for_load verify-reconfig ${ORIGINAL_SERIAL} ns3/named.run 490# Ensure responses sourced from the reconfigured zone have AA=1 and AD=0. 491$DIG $DIGOPTS @10.53.0.3 +norec verify-reconfig SOA > dig.out.ns3.test$n.2 2>&1 || ret=1 492grep "NOERROR" dig.out.ns3.test$n.2 > /dev/null || ret=1 493grep "flags:.* aa" dig.out.ns3.test$n.2 > /dev/null || ret=1 494grep "flags:.* ad" dig.out.ns3.test$n.2 > /dev/null && ret=1 495if [ $ret != 0 ]; then echo_i "failed"; fi 496status=`expr $status + $ret` 497 498n=`expr $n + 1` 499echo_i "checking that \"rndc reconfig\" properly handles a slave -> mirror zone type change ($n)" 500ret=0 501# Put an incorrectly signed version of the zone in the zone file used by ns3. 502nextpart ns3/named.run > /dev/null 503cat ns2/verify-reconfig.db.bad.signed > ns3/verify-reconfig.db.mirror 504# Reconfigure the zone so that it is a mirror zone again. 505# (NOTE: Keep the embedded newline in the sed function list below.) 506sed '/^zone "verify-reconfig" {$/,/^};$/ { 507 s/type slave;/type mirror;/ 508}' ns3/named.conf > ns3/named.conf.modified 509mv ns3/named.conf.modified ns3/named.conf 510rndc_reconfig ns3 10.53.0.3 511# The reconfigured zone should fail verification. 512wait_for_load verify-reconfig ${UPDATED_SERIAL_BAD} ns3/named.run 513$DIG $DIGOPTS @10.53.0.3 +norec verify-reconfig SOA > dig.out.ns3.test$n 2>&1 || ret=1 514grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1 515nextpart ns3/named.run | grep "No correct RSASHA256 signature for verify-reconfig SOA" > /dev/null || ret=1 516if [ $ret != 0 ]; then echo_i "failed"; fi 517status=`expr $status + $ret` 518 519n=`expr $n + 1` 520echo_i "checking that a mirror zone can be added using rndc ($n)" 521ret=0 522# Sanity check: the zone should not exist in the root zone. 523$DIG $DIGOPTS @10.53.0.3 +norec verify-addzone SOA > dig.out.ns3.test$n.1 2>&1 || ret=1 524grep "NXDOMAIN" dig.out.ns3.test$n.1 > /dev/null || ret=1 525grep "flags:.* aa" dig.out.ns3.test$n.1 > /dev/null && ret=1 526grep "flags:.* ad" dig.out.ns3.test$n.1 > /dev/null || ret=1 527# Mirror a zone which does not exist in the root zone. 528nextpart ns3/named.run > /dev/null 529$RNDCCMD 10.53.0.3 addzone verify-addzone '{ type mirror; masters { 10.53.0.2; }; };' > rndc.out.ns3.test$n 2>&1 || ret=1 530wait_for_transfer verify-addzone 531# Check whether the mirror zone was added and whether it behaves as expected. 532$DIG $DIGOPTS @10.53.0.3 +norec verify-addzone SOA > dig.out.ns3.test$n.2 2>&1 || ret=1 533grep "NOERROR" dig.out.ns3.test$n.2 > /dev/null || ret=1 534grep "flags:.* aa" dig.out.ns3.test$n.2 > /dev/null && ret=1 535grep "flags:.* ad" dig.out.ns3.test$n.2 > /dev/null || ret=1 536if [ $ret != 0 ]; then echo_i "failed"; fi 537status=`expr $status + $ret` 538 539n=`expr $n + 1` 540echo_i "checking that a mirror zone can be deleted using rndc ($n)" 541ret=0 542# Remove the mirror zone added in the previous test. 543nextpart ns3/named.run > /dev/null 544$RNDCCMD 10.53.0.3 delzone verify-addzone > rndc.out.ns3.test$n 2>&1 || ret=1 545wait_for_log 20 "zone verify-addzone/IN: mirror zone is no longer in use; reverting to normal recursion" ns3/named.run || ret=1 546# Check whether the mirror zone was removed. 547$DIG $DIGOPTS @10.53.0.3 +norec verify-addzone SOA > dig.out.ns3.test$n 2>&1 || ret=1 548grep "NXDOMAIN" dig.out.ns3.test$n > /dev/null || ret=1 549grep "flags:.* aa" dig.out.ns3.test$n > /dev/null && ret=1 550grep "flags:.* ad" dig.out.ns3.test$n > /dev/null || ret=1 551if [ $ret != 0 ]; then echo_i "failed"; fi 552status=`expr $status + $ret` 553 554echo_i "exit status: $status" 555[ $status -eq 0 ] || exit 1 556