1#!/bin/sh 2 3# Copyright (C) Internet Systems Consortium, Inc. ("ISC") 4# 5# SPDX-License-Identifier: MPL-2.0 6# 7# This Source Code Form is subject to the terms of the Mozilla Public 8# License, v. 2.0. If a copy of the MPL was not distributed with this 9# file, you can obtain one at https://mozilla.org/MPL/2.0/. 10# 11# See the COPYRIGHT file distributed with this work for additional 12# information regarding copyright ownership. 13 14set -e 15 16. ../conf.sh 17 18DIGOPTS="+tcp +dnssec -p ${PORT}" 19RNDCCMD="$RNDC -c ../_common/rndc.conf -p ${CONTROLPORT} -s" 20 21dig_with_opts() { 22 $DIG $DIGOPTS "$@" 23} 24 25rndccmd() { 26 $RNDCCMD "$@" 27} 28 29wait_for_serial() ( 30 $DIG $DIGOPTS "@$1" "$2" SOA >"$4" 31 serial=$(awk '$4 == "SOA" { print $7 }' "$4") 32 [ "$3" -eq "${serial:--1}" ] 33) 34 35status=0 36n=0 37ret=0 38 39# Make sure nsec3 zone is NSEC3 signed. 40for i in 1 2 3 4 5 6 7 8 9 0; do 41 nsec3param=$($DIG $DIGOPTS +nodnssec +short @10.53.0.3 nsec3param nsec3.) || ret=1 42 test "$nsec3param" = "1 0 0 -" && break 43 sleep 1 44done 45 46if [ $ret != 0 ]; then 47 echo_i "pre-condition failed, test aborted" 48 exit 1 49fi 50 51n=$((n + 1)) 52echo_i "checking that an unsupported algorithm is not used for signing ($n)" 53ret=0 54grep -q "algorithm is unsupported" ns3/named.run || ret=1 55if [ $ret != 0 ]; then echo_i "failed"; fi 56status=$((status + ret)) 57 58n=$((n + 1)) 59echo_i "checking that rrsigs are replaced with ksk only ($n)" 60ret=0 61$DIG $DIGOPTS @10.53.0.3 axfr nsec3. \ 62 | awk '/RRSIG NSEC3/ {a[$1]++} END { for (i in a) {if (a[i] != 1) exit (1)}}' || ret=1 63if [ $ret != 0 ]; then echo_i "failed"; fi 64status=$((status + ret)) 65 66n=$((n + 1)) 67echo_i "checking that the zone is signed on initial transfer ($n)" 68ret=0 69zone_is_signed() { 70 $DIG $DIGOPTS @10.53.0.3 bits. AXFR >dig.out.ns3.test$n || return 1 71 $VERIFY -z -o bits. dig.out.ns3.test$n >verify.out.bits.test$n || return 1 72 return 0 73} 74retry_quiet 10 zone_is_signed || ret=1 75if [ $ret != 0 ]; then echo_i "failed"; fi 76status=$((status + ret)) 77 78n=$((n + 1)) 79echo_i "checking expired signatures are updated on load ($n)" 80ret=0 81$DIG $DIGOPTS @10.53.0.3 +noall +answer +dnssec expired SOA >dig.out.ns3.test$n || ret=1 82expiry=$(awk '$4 == "RRSIG" { print $9 }' dig.out.ns3.test$n) 83[ "$expiry" = "20110101000000" ] && ret=1 84if [ $ret != 0 ]; then echo_i "failed"; fi 85status=$((status + ret)) 86 87n=$((n + 1)) 88echo_i "checking removal of private type record via 'rndc signing -clear' ($n)" 89ret=0 90$RNDCCMD 10.53.0.3 signing -list bits >signing.out.test$n 2>&1 || ret=1 91keys=$(sed -n -e 's/Done signing with key \(.*\)$/\1/p' signing.out.test$n) 92for key in $keys; do 93 $RNDCCMD 10.53.0.3 signing -clear ${key} bits >/dev/null || ret=1 94 break # We only want to remove 1 record for now. 95done 2>&1 | sed 's/^/ns3 /' | cat_i 96 97for i in 1 2 3 4 5 6 7 8 9 10; do 98 ans=0 99 $RNDCCMD 10.53.0.3 signing -list bits >signing.out.test$n 2>&1 || ret=1 100 num=$(grep "Done signing with" signing.out.test$n | wc -l) 101 [ $num = 1 ] && break 102 sleep 1 103done 104[ $ans = 0 ] || ret=1 105 106if [ $ret != 0 ]; then echo_i "failed"; fi 107status=$((status + ret)) 108 109n=$((n + 1)) 110echo_i "checking private type was properly signed ($n)" 111ret=0 112$DIG $DIGOPTS @10.53.0.6 bits TYPE65534 >dig.out.ns6.test$n || ret=1 113# One private type record, one signature 114grep "ANSWER: 2," dig.out.ns6.test$n >/dev/null || ret=1 115grep "flags:.* ad[ ;]" dig.out.ns6.test$n >/dev/null || ret=1 116 117if [ $ret != 0 ]; then echo_i "failed"; fi 118status=$((status + ret)) 119 120n=$((n + 1)) 121echo_i "checking removal of remaining private type record via 'rndc signing -clear all' ($n)" 122ret=0 123$RNDCCMD 10.53.0.3 signing -clear all bits >signing.out.test$n.clear || ret=1 124 125for i in 1 2 3 4 5 6 7 8 9 10; do 126 ans=0 127 $RNDCCMD 10.53.0.3 signing -list bits >signing.out.test$n 2>&1 || ret=1 128 grep "No signing records found" signing.out.test$n >/dev/null || ans=1 129 [ $ans = 1 ] || break 130 sleep 1 131done 132[ $ans = 0 ] || ret=1 133 134if [ $ret != 0 ]; then echo_i "failed"; fi 135status=$((status + ret)) 136 137n=$((n + 1)) 138echo_i "checking negative private type response was properly signed ($n)" 139ret=0 140sleep 1 141$DIG $DIGOPTS @10.53.0.6 bits TYPE65534 >dig.out.ns6.test$n || ret=1 142grep "status: NOERROR" dig.out.ns6.test$n >/dev/null || ret=1 143grep "ANSWER: 0," dig.out.ns6.test$n >/dev/null || ret=1 144grep "flags:.* ad[ ;]" dig.out.ns6.test$n >/dev/null || ret=1 145 146if [ $ret != 0 ]; then echo_i "failed"; fi 147status=$((status + ret)) 148 149n=$((n + 1)) 150echo_i "checking that the record is added on the hidden primary ($n)" 151ret=0 152 153$NSUPDATE <<EOF || ret=1 154zone bits 155server 10.53.0.2 ${PORT} 156update add added.bits 0 A 1.2.3.4 157send 158EOF 159 160$DIG $DIGOPTS @10.53.0.2 added.bits A >dig.out.ns2.test$n || ret=1 161grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 162grep "ANSWER: 1," dig.out.ns2.test$n >/dev/null || ret=1 163if [ $ret != 0 ]; then echo_i "failed"; fi 164status=$((status + ret)) 165 166n=$((n + 1)) 167echo_i "checking that update has been transferred and has been signed ($n)" 168ret=0 169for i in 1 2 3 4 5 6 7 8 9 10; do 170 ret=0 171 $DIG $DIGOPTS @10.53.0.3 added.bits A >dig.out.ns3.test$n || ret=1 172 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 173 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ret=1 174 if [ $ret = 0 ]; then break; fi 175 sleep 1 176done 177if [ $ret != 0 ]; then echo_i "failed"; fi 178status=$((status + ret)) 179 180n=$((n + 1)) 181echo_i "checking YYYYMMDDVV (2011072400) serial on hidden primary ($n)" 182ret=0 183 184$NSUPDATE <<EOF || ret=1 185zone bits 186server 10.53.0.2 ${PORT} 187update add bits 0 SOA ns2.bits. . 2011072400 20 20 1814400 3600 188send 189EOF 190 191$DIG $DIGOPTS @10.53.0.2 bits SOA >dig.out.ns2.test$n || ret=1 192grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 193grep "ANSWER: 1," dig.out.ns2.test$n >/dev/null || ret=1 194grep "2011072400" dig.out.ns2.test$n >/dev/null || ret=1 195if [ $ret != 0 ]; then echo_i "failed"; fi 196status=$((status + ret)) 197 198n=$((n + 1)) 199echo_i "checking YYYYMMDDVV (2011072400) serial in signed zone ($n)" 200for i in 1 2 3 4 5 6 7 8 9 10; do 201 ret=0 202 $DIG $DIGOPTS @10.53.0.3 bits SOA >dig.out.ns3.test$n || ret=1 203 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 204 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ret=1 205 grep "2011072400" dig.out.ns3.test$n >/dev/null || ret=1 206 if [ $ret = 0 ]; then break; fi 207 sleep 1 208done 209if [ $ret != 0 ]; then echo_i "failed"; fi 210status=$((status + ret)) 211 212n=$((n + 1)) 213echo_i "checking that the zone is signed on initial transfer, noixfr ($n)" 214ret=0 215for i in 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10; do 216 ret=0 217 $RNDCCMD 10.53.0.3 signing -list noixfr >signing.out.test$n 2>&1 || ret=1 218 keys=$(grep '^Done signing' signing.out.test$n | wc -l) 219 [ $keys = 2 ] || ret=1 220 if [ $ret = 0 ]; then break; fi 221 sleep 1 222done 223if [ $ret != 0 ]; then echo_i "failed"; fi 224status=$((status + ret)) 225 226n=$((n + 1)) 227echo_i "checking that the record is added on the hidden primary, noixfr ($n)" 228ret=0 229 230$NSUPDATE <<EOF || ret=1 231zone noixfr 232server 10.53.0.4 ${PORT} 233update add added.noixfr 0 A 1.2.3.4 234send 235EOF 236 237$DIG $DIGOPTS @10.53.0.4 added.noixfr A >dig.out.ns4.test$n || ret=1 238grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 239grep "ANSWER: 1," dig.out.ns4.test$n >/dev/null || ret=1 240if [ $ret != 0 ]; then echo_i "failed"; fi 241status=$((status + ret)) 242 243n=$((n + 1)) 244echo_i "checking that update has been transferred and has been signed, noixfr ($n)" 245ret=0 246for i in 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10 1 2 3 4 5 6 7 8 9 10; do 247 ret=0 248 $DIG $DIGOPTS @10.53.0.3 added.noixfr A >dig.out.ns3.test$n || ret=1 249 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 250 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ret=1 251 if [ $ret = 0 ]; then break; fi 252 sleep 1 253done 254if [ $ret != 0 ]; then echo_i "failed"; fi 255status=$((status + ret)) 256 257n=$((n + 1)) 258echo_i "checking YYYYMMDDVV (2011072400) serial on hidden primary, noixfr ($n)" 259ret=0 260 261$NSUPDATE <<EOF || ret=1 262zone noixfr 263server 10.53.0.4 ${PORT} 264update add noixfr 0 SOA ns4.noixfr. . 2011072400 20 20 1814400 3600 265send 266EOF 267 268$DIG $DIGOPTS @10.53.0.4 noixfr SOA >dig.out.ns4.test$n || ret=1 269grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 270grep "ANSWER: 1," dig.out.ns4.test$n >/dev/null || ret=1 271grep "2011072400" dig.out.ns4.test$n >/dev/null || ret=1 272if [ $ret != 0 ]; then echo_i "failed"; fi 273status=$((status + ret)) 274 275n=$((n + 1)) 276echo_i "checking YYYYMMDDVV (2011072400) serial in signed zone, noixfr ($n)" 277for i in 1 2 3 4 5 6 7 8 9 10; do 278 ret=0 279 $DIG $DIGOPTS @10.53.0.3 noixfr SOA >dig.out.ns3.test$n || ret=1 280 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 281 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ret=1 282 grep "2011072400" dig.out.ns3.test$n >/dev/null || ret=1 283 if [ $ret = 0 ]; then break; fi 284 sleep 1 285done 286if [ $ret != 0 ]; then echo_i "failed"; fi 287status=$((status + ret)) 288 289n=$((n + 1)) 290echo_i "checking that the primary zone signed on initial load ($n)" 291ret=0 292for i in 1 2 3 4 5 6 7 8 9 10; do 293 ret=0 294 $RNDCCMD 10.53.0.3 signing -list primary >signing.out.test$n 2>&1 || ret=1 295 keys=$(grep '^Done signing' signing.out.test$n | wc -l) 296 [ $keys = 2 ] || ret=1 297 if [ $ret = 0 ]; then break; fi 298 sleep 1 299done 300if [ $ret != 0 ]; then echo_i "failed"; fi 301status=$((status + ret)) 302 303n=$((n + 1)) 304echo_i "checking removal of private type record via 'rndc signing -clear' (primary) ($n)" 305ret=0 306$RNDCCMD 10.53.0.3 signing -list primary >signing.out.test$n 2>&1 || ret=1 307keys=$(sed -n -e 's/Done signing with key \(.*\)$/\1/p' signing.out.test$n) 308for key in $keys; do 309 $RNDCCMD 10.53.0.3 signing -clear ${key} primary >/dev/null || ret=1 310 break # We only want to remove 1 record for now. 311done 2>&1 | sed 's/^/ns3 /' | cat_i 312 313for i in 1 2 3 4 5 6 7 8 9; do 314 ans=0 315 $RNDCCMD 10.53.0.3 signing -list primary >signing.out.test$n 2>&1 || ret=1 316 num=$(grep "Done signing with" signing.out.test$n | wc -l) 317 [ $num = 1 ] && break 318 sleep 1 319done 320[ $ans = 0 ] || ret=1 321 322if [ $ret != 0 ]; then echo_i "failed"; fi 323status=$((status + ret)) 324 325n=$((n + 1)) 326echo_i "checking private type was properly signed (primary) ($n)" 327ret=0 328$DIG $DIGOPTS @10.53.0.6 primary TYPE65534 >dig.out.ns6.test$n || ret=1 329grep "ANSWER: 2," dig.out.ns6.test$n >/dev/null || ret=1 330grep "flags:.* ad[ ;]" dig.out.ns6.test$n >/dev/null || ret=1 331 332if [ $ret != 0 ]; then echo_i "failed"; fi 333status=$((status + ret)) 334 335n=$((n + 1)) 336echo_i "checking removal of remaining private type record via 'rndc signing -clear' (primary) ($n)" 337ret=0 338$RNDCCMD 10.53.0.3 signing -clear all primary >/dev/null || ret=1 339for i in 1 2 3 4 5 6 7 8 9 10; do 340 ans=0 341 $RNDCCMD 10.53.0.3 signing -list primary >signing.out.test$n 2>&1 || ret=1 342 grep "No signing records found" signing.out.test$n >/dev/null || ans=1 343 [ $ans = 1 ] || break 344 sleep 1 345done 346[ $ans = 0 ] || ret=1 347 348if [ $ret != 0 ]; then echo_i "failed"; fi 349status=$((status + ret)) 350 351n=$((n + 1)) 352echo_i "check adding of record to unsigned primary ($n)" 353ret=0 354cp ns3/primary2.db.in ns3/primary.db 355rndc_reload ns3 10.53.0.3 primary 356for i in 1 2 3 4 5 6 7 8 9; do 357 ans=0 358 $DIG $DIGOPTS @10.53.0.3 e.primary A >dig.out.ns3.test$n || ret=1 359 grep "10.0.0.5" dig.out.ns3.test$n >/dev/null || ans=1 360 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ans=1 361 [ $ans = 1 ] || break 362 sleep 1 363done 364[ $ans = 0 ] || ret=1 365if [ $ret != 0 ]; then echo_i "failed"; fi 366status=$((status + ret)) 367 368n=$((n + 1)) 369echo_i "check adding record fails when SOA serial not changed ($n)" 370ret=0 371echo "c A 10.0.0.3" >>ns3/primary.db 372rndc_reload ns3 10.53.0.3 373sleep 1 374$DIG $DIGOPTS @10.53.0.3 c.primary A >dig.out.ns3.test$n || ret=1 375grep "NXDOMAIN" dig.out.ns3.test$n >/dev/null || ret=1 376if [ $ret != 0 ]; then echo_i "failed"; fi 377status=$((status + ret)) 378 379n=$((n + 1)) 380echo_i "check adding record works after updating SOA serial ($n)" 381ret=0 382cp ns3/primary3.db.in ns3/primary.db 383$RNDCCMD 10.53.0.3 reload primary 2>&1 | sed 's/^/ns3 /' | cat_i 384for i in 1 2 3 4 5 6 7 8 9; do 385 ans=0 386 $DIG $DIGOPTS @10.53.0.3 c.primary A >dig.out.ns3.test$n || ret=1 387 grep "10.0.0.3" dig.out.ns3.test$n >/dev/null || ans=1 388 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ans=1 389 [ $ans = 1 ] || break 390 sleep 1 391done 392[ $ans = 0 ] || ret=1 393if [ $ret != 0 ]; then echo_i "failed"; fi 394status=$((status + ret)) 395 396n=$((n + 1)) 397echo_i "check the added record was properly signed ($n)" 398ret=0 399$DIG $DIGOPTS @10.53.0.3 e.primary A >dig.out.ns6.test$n || ret=1 400grep "10.0.0.5" dig.out.ns6.test$n >/dev/null || ans=1 401grep "ANSWER: 2," dig.out.ns6.test$n >/dev/null || ans=1 402grep "flags:.* ad[ ;]" dig.out.ns6.test$n >/dev/null || ans=1 403if [ $ret != 0 ]; then echo_i "failed"; fi 404status=$((status + ret)) 405 406n=$((n + 1)) 407echo_i "checking that the dynamic primary zone signed on initial load ($n)" 408ret=0 409for i in 1 2 3 4 5 6 7 8 9 10; do 410 ret=0 411 $RNDCCMD 10.53.0.3 signing -list dynamic >signing.out.test$n 2>&1 || ret=1 412 keys=$(grep '^Done signing' signing.out.test$n | wc -l) 413 [ $keys = 2 ] || ret=1 414 if [ $ret = 0 ]; then break; fi 415 sleep 1 416done 417if [ $ret != 0 ]; then echo_i "failed"; fi 418status=$((status + ret)) 419 420n=$((n + 1)) 421echo_i "checking primary zone that was updated while offline is correct ($n)" 422ret=0 423$DIG $DIGOPTS +nodnssec +short @10.53.0.3 updated SOA >dig.out.ns3.soa.test$n || ret=1 424serial=$(awk '{print $3}' dig.out.ns3.soa.test$n) 425# serial should have changed 426[ "$serial" = "2000042407" ] && ret=1 427# e.updated should exist and should be signed 428$DIG $DIGOPTS @10.53.0.3 e.updated A >dig.out.ns3.test$n || ret=1 429grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 430grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ret=1 431# updated.db.signed.jnl should exist, should have the source serial 432# of primary2.db, and should show a minimal diff: no more than 8 added 433# records (SOA/RRSIG, 2 x NSEC/RRSIG, A/RRSIG), and 4 removed records 434# (SOA/RRSIG, NSEC/RRSIG). 435$JOURNALPRINT ns3/updated.db.signed.jnl >journalprint.out.test$n || ret=1 436serial=$(awk '/Source serial =/ {print $4}' journalprint.out.test$n) 437[ "$serial" = "2000042408" ] || ret=1 438diffsize=$(wc -l <journalprint.out.test$n) 439[ "$diffsize" -le 13 ] || ret=1 440if [ $ret != 0 ]; then echo_i "failed"; fi 441status=$((status + ret)) 442 443n=$((n + 1)) 444echo_i "checking adding of record to unsigned primary using UPDATE ($n)" 445ret=0 446 447[ -f ns3/dynamic.db.jnl ] && { 448 ret=1 449 echo_i "journal exists (pretest)" 450} 451 452$NSUPDATE <<EOF || ret=1 453zone dynamic 454server 10.53.0.3 ${PORT} 455update add e.dynamic 0 A 1.2.3.4 456send 457EOF 458 459[ -f ns3/dynamic.db.jnl ] || { 460 ret=1 461 echo_i "journal does not exist (posttest)" 462} 463 464for i in 1 2 3 4 5 6 7 8 9 10; do 465 ans=0 466 $DIG $DIGOPTS @10.53.0.3 e.dynamic >dig.out.ns3.test$n || ret=1 467 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ans=1 468 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ans=1 469 grep "1.2.3.4" dig.out.ns3.test$n >/dev/null || ans=1 470 [ $ans = 0 ] && break 471 sleep 1 472done 473[ $ans = 0 ] || { 474 ret=1 475 echo_i "signed record not found" 476 cat dig.out.ns3.test$n 477} 478 479if [ $ret != 0 ]; then echo_i "failed"; fi 480status=$((status + ret)) 481 482n=$((n + 1)) 483echo_i "stop bump in the wire signer server ($n)" 484ret=0 485stop_server ns3 || ret=1 486if [ $ret != 0 ]; then echo_i "failed"; fi 487status=$((status + ret)) 488 489n=$((n + 1)) 490echo_i "restart bump in the wire signer server ($n)" 491ret=0 492start_server --noclean --restart --port ${PORT} ns3 || ret=1 493if [ $ret != 0 ]; then echo_i "failed"; fi 494status=$((status + ret)) 495 496n=$((n + 1)) 497echo_i "checking YYYYMMDDVV (2011072450) serial on hidden primary ($n)" 498ret=0 499 500$NSUPDATE <<EOF || ret=1 501zone bits 502server 10.53.0.2 ${PORT} 503update add bits 0 SOA ns2.bits. . 2011072450 20 20 1814400 3600 504send 505EOF 506 507$DIG $DIGOPTS @10.53.0.2 bits SOA >dig.out.ns2.test$n || ret=1 508grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 509grep "ANSWER: 1," dig.out.ns2.test$n >/dev/null || ret=1 510grep "2011072450" dig.out.ns2.test$n >/dev/null || ret=1 511if [ $ret != 0 ]; then echo_i "failed"; fi 512status=$((status + ret)) 513 514n=$((n + 1)) 515echo_i "checking YYYYMMDDVV (2011072450) serial in signed zone ($n)" 516for i in 1 2 3 4 5 6 7 8 9 10; do 517 ret=0 518 $DIG $DIGOPTS @10.53.0.3 bits SOA >dig.out.ns3.test$n || ret=1 519 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 520 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ret=1 521 grep "2011072450" dig.out.ns3.test$n >/dev/null || ret=1 522 if [ $ret = 0 ]; then break; fi 523 sleep 1 524done 525if [ $ret != 0 ]; then echo_i "failed"; fi 526status=$((status + ret)) 527 528n=$((n + 1)) 529echo_i "checking YYYYMMDDVV (2011072450) serial on hidden primary, noixfr ($n)" 530ret=0 531 532$NSUPDATE <<EOF || ret=1 533zone noixfr 534server 10.53.0.4 ${PORT} 535update add noixfr 0 SOA ns4.noixfr. . 2011072450 20 20 1814400 3600 536send 537EOF 538 539$DIG $DIGOPTS @10.53.0.4 noixfr SOA >dig.out.ns4.test$n || ret=1 540grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 541grep "ANSWER: 1," dig.out.ns4.test$n >/dev/null || ret=1 542grep "2011072450" dig.out.ns4.test$n >/dev/null || ret=1 543if [ $ret != 0 ]; then echo_i "failed"; fi 544status=$((status + ret)) 545 546n=$((n + 1)) 547echo_i "checking YYYYMMDDVV (2011072450) serial in signed zone, noixfr ($n)" 548for i in 1 2 3 4 5 6 7 8 9 10; do 549 ret=0 550 $DIG $DIGOPTS @10.53.0.3 noixfr SOA >dig.out.ns3.test$n || ret=1 551 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 552 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ret=1 553 grep "2011072450" dig.out.ns3.test$n >/dev/null || ret=1 554 if [ $ret = 0 ]; then break; fi 555 sleep 1 556done 557if [ $ret != 0 ]; then echo_i "failed"; fi 558status=$((status + ret)) 559 560n=$((n + 1)) 561echo_i "checking forwarded update on hidden primary ($n)" 562ret=0 563 564$NSUPDATE <<EOF || ret=1 565zone bits 566server 10.53.0.3 ${PORT} 567update add bits 0 SOA ns2.bits. . 2011072460 20 20 1814400 3600 568send 569EOF 570 571$DIG $DIGOPTS @10.53.0.2 bits SOA >dig.out.ns2.test$n || ret=1 572grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 573grep "ANSWER: 1," dig.out.ns2.test$n >/dev/null || ret=1 574grep "2011072460" dig.out.ns2.test$n >/dev/null || ret=1 575if [ $ret != 0 ]; then echo_i "failed"; fi 576status=$((status + ret)) 577 578n=$((n + 1)) 579echo_i "checking forwarded update on signed zone ($n)" 580for i in 1 2 3 4 5 6 7 8 9 10; do 581 ret=0 582 $DIG $DIGOPTS @10.53.0.3 bits SOA >dig.out.ns3.test$n || ret=1 583 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 584 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ret=1 585 grep "2011072460" dig.out.ns3.test$n >/dev/null || ret=1 586 if [ $ret = 0 ]; then break; fi 587 sleep 1 588done 589if [ $ret != 0 ]; then echo_i "failed"; fi 590status=$((status + ret)) 591 592n=$((n + 1)) 593echo_i "checking forwarded update on hidden primary, noixfr ($n)" 594ret=0 595 596$NSUPDATE <<EOF || ret=1 597zone noixfr 598server 10.53.0.3 ${PORT} 599update add noixfr 0 SOA ns4.noixfr. . 2011072460 20 20 1814400 3600 600send 601EOF 602 603$DIG $DIGOPTS @10.53.0.4 noixfr SOA >dig.out.ns4.test$n || ret=1 604grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 605grep "ANSWER: 1," dig.out.ns4.test$n >/dev/null || ret=1 606grep "2011072460" dig.out.ns4.test$n >/dev/null || ret=1 607if [ $ret != 0 ]; then echo_i "failed"; fi 608status=$((status + ret)) 609 610n=$((n + 1)) 611echo_i "checking forwarded update on signed zone, noixfr ($n)" 612for i in 1 2 3 4 5 6 7 8 9 10; do 613 ret=0 614 $DIG $DIGOPTS @10.53.0.3 noixfr SOA >dig.out.ns3.test$n || ret=1 615 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 616 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ret=1 617 grep "2011072460" dig.out.ns3.test$n >/dev/null || ret=1 618 if [ $ret = 0 ]; then break; fi 619 sleep 1 620done 621if [ $ret != 0 ]; then echo_i "failed"; fi 622status=$((status + ret)) 623 624ret=0 625n=$((n + 1)) 626echo_i "checking turning on of inline signing in a secondary zone via reload ($n)" 627$DIG $DIGOPTS @10.53.0.5 +dnssec bits SOA >dig.out.ns5.test$n || ret=1 628grep "status: NOERROR" dig.out.ns5.test$n >/dev/null || ret=1 629grep "ANSWER: 1," dig.out.ns5.test$n >/dev/null || ret=1 630if [ $ret != 0 ]; then echo_i "setup broken"; fi 631status=$((status + ret)) 632copy_setports ns5/named.conf.post ns5/named.conf 633( 634 cd ns5 635 $KEYGEN -q -a ${DEFAULT_ALGORITHM} bits 636) >/dev/null 2>&1 637( 638 cd ns5 639 $KEYGEN -q -a ${DEFAULT_ALGORITHM} -f KSK bits 640) >/dev/null 2>&1 641rndc_reload ns5 10.53.0.5 642for i in 1 2 3 4 5 6 7 8 9 10; do 643 ret=0 644 $DIG $DIGOPTS @10.53.0.5 bits SOA >dig.out.ns5.test$n || ret=1 645 grep "status: NOERROR" dig.out.ns5.test$n >/dev/null || ret=1 646 grep "ANSWER: 2," dig.out.ns5.test$n >/dev/null || ret=1 647 if [ $ret = 0 ]; then break; fi 648 sleep 1 649done 650if [ $ret != 0 ]; then echo_i "failed"; fi 651status=$((status + ret)) 652 653n=$((n + 1)) 654echo_i "checking rndc freeze/thaw of dynamic inline zone no change ($n)" 655ret=0 656$RNDCCMD 10.53.0.3 freeze dynamic >freeze.test$n 2>&1 || { 657 echo_i "/' < freeze.test$n" 658 ret=1 659} 660sleep 1 661$RNDCCMD 10.53.0.3 thaw dynamic >thaw.test$n 2>&1 || { 662 echo_i "rndc thaw dynamic failed" 663 ret=1 664} 665sleep 1 666grep "zone dynamic/IN (unsigned): ixfr-from-differences: unchanged" ns3/named.run >/dev/null || ret=1 667if [ $ret != 0 ]; then echo_i "failed"; fi 668status=$((status + ret)) 669 670n=$((n + 1)) 671echo_i "checking rndc freeze/thaw of dynamic inline zone ($n)" 672ret=0 673$RNDCCMD 10.53.0.3 freeze dynamic >freeze.test$n 2>&1 || ret=1 674sleep 1 675awk '$2 == ";" && $3 ~ /serial/ { printf("%d %s %s\n", $1 + 1, $2, $3); next; } 676 { print; } 677 END { print "freeze1.dynamic. 0 TXT freeze1"; } ' ns3/dynamic.db >ns3/dynamic.db.new 678mv ns3/dynamic.db.new ns3/dynamic.db 679$RNDCCMD 10.53.0.3 thaw dynamic >thaw.test$n 2>&1 || ret=1 680if [ $ret != 0 ]; then echo_i "failed"; fi 681status=$((status + ret)) 682 683n=$((n + 1)) 684echo_i "check added record freeze1.dynamic ($n)" 685for i in 1 2 3 4 5 6 7 8 9; do 686 ret=0 687 $DIG $DIGOPTS @10.53.0.3 freeze1.dynamic TXT >dig.out.ns3.test$n || ret=1 688 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 689 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ret=1 690 test $ret = 0 && break 691 sleep 1 692done 693if [ $ret != 0 ]; then echo_i "failed"; fi 694status=$((status + ret)) 695 696# allow 1 second so that file time stamps change 697sleep 1 698 699n=$((n + 1)) 700echo_i "checking rndc freeze/thaw of server ($n)" 701ret=0 702$RNDCCMD 10.53.0.3 freeze >freeze.test$n 2>&1 || ret=1 703sleep 1 704awk '$2 == ";" && $3 ~ /serial/ { printf("%d %s %s\n", $1 + 1, $2, $3); next; } 705 { print; } 706 END { print "freeze2.dynamic. 0 TXT freeze2"; } ' ns3/dynamic.db >ns3/dynamic.db.new 707mv ns3/dynamic.db.new ns3/dynamic.db 708$RNDCCMD 10.53.0.3 thaw >thaw.test$n 2>&1 || ret=1 709if [ $ret != 0 ]; then echo_i "failed"; fi 710status=$((status + ret)) 711 712n=$((n + 1)) 713echo_i "check added record freeze2.dynamic ($n)" 714for i in 1 2 3 4 5 6 7 8 9; do 715 ret=0 716 $DIG $DIGOPTS @10.53.0.3 freeze2.dynamic TXT >dig.out.ns3.test$n || ret=1 717 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 718 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ret=1 719 test $ret = 0 && break 720 sleep 1 721done 722if [ $ret != 0 ]; then echo_i "failed"; fi 723status=$((status + ret)) 724 725n=$((n + 1)) 726echo_i "check rndc reload allows reuse of inline-signing zones ($n)" 727ret=0 728{ $RNDCCMD 10.53.0.3 reload 2>&1 || ret=1; } | sed 's/^/ns3 /' | cat_i 729grep "not reusable" ns3/named.run >/dev/null 2>&1 && ret=1 730if [ $ret != 0 ]; then echo_i "failed"; fi 731status=$((status + ret)) 732 733n=$((n + 1)) 734echo_i "check rndc sync removes both signed and unsigned journals ($n)" 735ret=0 736[ -f ns3/dynamic.db.jnl ] || ret=1 737[ -f ns3/dynamic.db.signed.jnl ] || ret=1 738$RNDCCMD 10.53.0.3 sync -clean dynamic 2>&1 || ret=1 739[ -f ns3/dynamic.db.jnl ] && ret=1 740[ -f ns3/dynamic.db.signed.jnl ] && ret=1 741if [ $ret != 0 ]; then echo_i "failed"; fi 742status=$((status + ret)) 743 744n=$((n + 1)) 745echo_i "checking that the retransfer record is added on the hidden primary ($n)" 746ret=0 747 748$NSUPDATE <<EOF || ret=1 749zone retransfer 750server 10.53.0.2 ${PORT} 751update add added.retransfer 0 A 1.2.3.4 752send 753 754EOF 755 756$DIG $DIGOPTS @10.53.0.2 added.retransfer A >dig.out.ns2.test$n || ret=1 757grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 758grep "ANSWER: 1," dig.out.ns2.test$n >/dev/null || ret=1 759if [ $ret != 0 ]; then echo_i "failed"; fi 760status=$((status + ret)) 761 762n=$((n + 1)) 763echo_i "checking that the change has not been transferred due to notify ($n)" 764ret=0 765for i in 0 1 2 3 4 5 6 7 8 9; do 766 ans=0 767 $DIG $DIGOPTS @10.53.0.3 added.retransfer A >dig.out.ns3.test$n || ret=1 768 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ans=1 769 [ $ans = 0 ] && break 770 sleep 1 771done 772if [ $ans != 1 ]; then 773 echo_i "failed" 774 ret=1 775fi 776status=$((status + ret)) 777 778n=$((n + 1)) 779echo_i "check rndc retransfer of a inline secondary zone works ($n)" 780ret=0 781$RNDCCMD 10.53.0.3 retransfer retransfer 2>&1 || ret=1 782for i in 0 1 2 3 4 5 6 7 8 9; do 783 ans=0 784 $DIG $DIGOPTS @10.53.0.3 added.retransfer A >dig.out.ns3.test$n || ret=1 785 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ans=1 786 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ans=1 787 [ $ans = 0 ] && break 788 sleep 1 789done 790[ $ans = 1 ] && ret=1 791if [ $ret != 0 ]; then echo_i "failed"; fi 792status=$((status + ret)) 793 794# NOTE: The test below should be considered fragile. More details can be found 795# in the comment inside ns7/named.conf. 796n=$((n + 1)) 797echo_i "check rndc retransfer of a inline nsec3 secondary does not trigger an infinite loop ($n)" 798ret=0 799zone=nsec3-loop 800# Add secondary zone using rndc 801$RNDCCMD 10.53.0.7 addzone $zone \ 802 '{ type secondary; primaries { 10.53.0.2; }; file "'$zone'.db"; inline-signing yes; dnssec-policy default; };' || ret=1 803# Wait until secondary zone is fully signed using NSEC 804for i in 1 2 3 4 5 6 7 8 9 0; do 805 ret=1 806 $RNDCCMD 10.53.0.7 signing -list $zone >signing.out.test$n 2>&1 || ret=1 807 keys=$(grep '^Done signing' signing.out.test$n | wc -l) 808 [ $keys -eq 3 ] && ret=0 && break 809 sleep 1 810done 811# Switch secondary zone to NSEC3 812$RNDCCMD 10.53.0.7 modzone $zone \ 813 '{ type secondary; primaries { 10.53.0.2; }; file "'$zone'.db"; inline-signing yes; dnssec-policy nsec3; };' || ret=1 814# Wait until secondary zone is fully signed using NSEC3 815for i in 1 2 3 4 5 6 7 8 9 0; do 816 ret=1 817 $DIG $DIGOPTS +nodnssec +short @10.53.0.7 nsec3param $zone >dig.out.ns7.test$n 818 nsec3param=$(cat dig.out.ns7.test$n) 819 test "$nsec3param" = "1 0 0 -" && ret=0 && break 820 sleep 1 821done 822 823# Attempt to retransfer the secondary zone from primary 824$RNDCCMD 10.53.0.7 retransfer $zone || ret=1 825# Check whether the signer managed to fully sign the retransferred zone by 826# waiting for a specific SOA serial number to appear in the logs; if this 827# specific SOA serial number does not appear in the logs, it means the signer 828# has either ran into an infinite loop or crashed; note that we check the logs 829# instead of sending SOA queries to the signer as these may influence its 830# behavior in a way which may prevent the desired scenario from being 831# reproduced (see comment in ns7/named.conf) 832for i in 1 2 3 4 5 6 7 8 9 0; do 833 ret=1 834 { 835 grep "ns2.$zone. . 10 20 20 1814400 3600" ns7/named.run >/dev/null 2>&1 836 rc=$? 837 } || true 838 [ $rc -eq 0 ] && ret=0 && break 839 sleep 1 840done 841if [ $ret != 0 ]; then echo_i "failed"; fi 842status=$((status + ret)) 843 844n=$((n + 1)) 845echo_i "stop bump in the wire signer server ($n)" 846ret=0 847stop_server ns3 || ret=1 848if [ $ret != 0 ]; then echo_i "failed"; fi 849status=$((status + ret)) 850 851echo_i "update SOA record while stopped" 852cp ns3/primary4.db.in ns3/primary.db 853rm -f ns3/primary.db.jnl 854 855n=$((n + 1)) 856echo_i "restart bump in the wire signer server ($n)" 857ret=0 858start_server --noclean --restart --port ${PORT} ns3 || ret=1 859if [ $ret != 0 ]; then echo_i "failed"; fi 860status=$((status + ret)) 861 862n=$((n + 1)) 863echo_i "updates to SOA parameters other than serial while stopped are reflected in signed zone ($n)" 864ret=0 865for i in 1 2 3 4 5 6 7 8 9; do 866 ans=0 867 $DIG $DIGOPTS @10.53.0.3 primary SOA >dig.out.ns3.test$n || ret=1 868 grep "hostmaster" dig.out.ns3.test$n >/dev/null || ans=1 869 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || ans=1 870 [ $ans = 1 ] || break 871 sleep 1 872done 873[ $ans = 0 ] || ret=1 874if [ $ret != 0 ]; then echo_i "failed"; fi 875status=$((status + ret)) 876 877n=$((n + 1)) 878echo_i "check that reloading all zones does not cause zone maintenance to cease for inline-signed zones ($n)" 879ret=1 880# Ensure "rndc reload" attempts to load ns3/primary.db by waiting 1 second so 881# that the file modification time has no possibility of being equal to 882# the one stored during server startup. 883sleep 1 884nextpart ns3/named.run >/dev/null 885cp ns3/primary5.db.in ns3/primary.db 886rndc_reload ns3 10.53.0.3 887for i in 1 2 3 4 5 6 7 8 9 10; do 888 if nextpart ns3/named.run | grep "zone primary.*sending notifies" >/dev/null; then 889 ret=0 890 break 891 fi 892 sleep 1 893done 894# Sanity check: file updates should be reflected in the signed zone, 895# i.e. SOA RNAME should no longer be set to "hostmaster". 896$DIG $DIGOPTS @10.53.0.3 primary SOA >dig.out.ns3.test$n || ret=1 897grep "hostmaster" dig.out.ns3.test$n >/dev/null && ret=1 898if [ $ret != 0 ]; then echo_i "failed"; fi 899status=$((status + ret)) 900 901n=$((n + 1)) 902echo_i "check that reloading errors prevent synchronization ($n)" 903ret=1 904$DIG $DIGOPTS +short @10.53.0.3 primary SOA >dig.out.ns3.test$n.1 || ret=1 905sleep 1 906nextpart ns3/named.run >/dev/null 907cp ns3/primary6.db.in ns3/primary.db 908rndc_reload ns3 10.53.0.3 909for i in 1 2 3 4 5 6 7 8 9 10; do 910 if nextpart ns3/named.run | grep "not loaded due to errors" >/dev/null; then 911 ret=0 912 break 913 fi 914 sleep 1 915done 916# Sanity check: the SOA record should be unchanged 917$DIG $DIGOPTS +short @10.53.0.3 primary SOA | grep -v '^;' >dig.out.ns3.test$n.2 918diff dig.out.ns3.test$n.1 dig.out.ns3.test$n.2 >/dev/null || ret=1 919if [ $ret != 0 ]; then echo_i "failed"; fi 920status=$((status + ret)) 921 922n=$((n + 1)) 923echo_i "check inline-signing with an include file ($n)" 924ret=0 925$DIG $DIGOPTS +short @10.53.0.3 primary SOA >dig.out.ns3.test$n.1 || ret=1 926if [ $ret != 0 ]; then echo_i "failed"; fi 927status=$((status + ret)) 928sleep 1 929nextpart ns3/named.run >/dev/null 930cp ns3/primary7.db.in ns3/primary.db 931rndc_reload ns3 10.53.0.3 932_includefile_loaded() { 933 $DIG $DIGOPTS @10.53.0.3 f.primary A >dig.out.ns3.test$n || return 1 934 grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || return 1 935 grep "ANSWER: 2," dig.out.ns3.test$n >/dev/null || return 1 936 grep "10\.0\.0\.7" dig.out.ns3.test$n >/dev/null || return 1 937 return 0 938} 939retry_quiet 10 _includefile_loaded 940# Sanity check: the SOA record should be changed 941$DIG $DIGOPTS +short @10.53.0.3 primary SOA | grep -v '^;' >dig.out.ns3.test$n.2 942diff dig.out.ns3.test$n.1 dig.out.ns3.test$n.2 >/dev/null && ret=1 943if [ $ret != 0 ]; then echo_i "failed"; fi 944status=$((status + ret)) 945 946n=$((n + 1)) 947echo_i "test add/del zone combinations ($n)" 948ret=0 949for zone in a b c d e f g h i j k l m n o p q r s t u v w x y z; do 950 $RNDCCMD 10.53.0.2 addzone test-$zone \ 951 '{ type primary; file "bits.db.in"; allow-transfer { any; }; };' || ret=1 952 $DIG $DIGOPTS @10.53.0.2 test-$zone SOA >dig.out.ns2.$zone.test$n || ret=1 953 grep "status: NOERROR," dig.out.ns2.$zone.test$n >/dev/null || { 954 ret=1 955 cat dig.out.ns2.$zone.test$n 956 } 957 $RNDCCMD 10.53.0.3 addzone test-$zone \ 958 '{ type secondary; primaries { 10.53.0.2; }; file "'test-$zone.bk'"; inline-signing yes; dnssec-policy default; allow-transfer { any; }; };' || ret=1 959 $RNDCCMD 10.53.0.3 delzone test-$zone >/dev/null 2>&1 || ret=1 960done 961if [ $ret != 0 ]; then echo_i "failed"; fi 962status=$((status + ret)) 963 964n=$((n + 1)) 965echo_i "testing adding external keys to a inline zone ($n)" 966ret=0 967$DIG $DIGOPTS @10.53.0.3 dnskey externalkey >dig.out.ns3.test$n || ret=1 968for alg in ${DEFAULT_ALGORITHM_NUMBER} ${ALTERNATIVE_ALGORITHM_NUMBER}; do 969 [ $alg = 13 -a ! -f checkecdsa ] && continue 970 971 case $alg in 972 7) echo_i "checking NSEC3RSASHA1" ;; 973 8) echo_i "checking RSASHA256" ;; 974 13) echo_i "checking ECDSAP256SHA256" ;; 975 *) echo_i "checking $alg" ;; 976 esac 977 978 dnskeys=$(grep "IN.DNSKEY.25[67] [0-9]* $alg " dig.out.ns3.test$n | wc -l) 979 rrsigs=$(grep "RRSIG.DNSKEY $alg " dig.out.ns3.test$n | wc -l) 980 test ${dnskeys:-0} -eq 4 || { 981 echo_i "failed $alg (dnskeys ${dnskeys:-0})" 982 ret=1 983 } 984 test ${rrsigs:-0} -eq 1 || { 985 echo_i "failed $alg (rrsigs ${rrsigs:-0})" 986 ret=1 987 } 988done 989if [ $ret != 0 ]; then echo_i "failed"; fi 990status=$((status + ret)) 991 992n=$((n + 1)) 993echo_i "testing imported key won't overwrite a private key ($n)" 994ret=0 995key=$($KEYGEN -q -a ${DEFAULT_ALGORITHM} import.example) 996cp ${key}.key import.key 997# import should fail 998$IMPORTKEY -f import.key import.example >/dev/null 2>&1 && ret=1 999rm -f ${key}.private 1000# private key removed; import should now succeed 1001$IMPORTKEY -f import.key import.example >/dev/null 2>&1 || ret=1 1002# now that it's an external key, re-import should succeed 1003$IMPORTKEY -f import.key import.example >/dev/null 2>&1 || ret=1 1004if [ $ret != 0 ]; then echo_i "failed"; fi 1005status=$((status + ret)) 1006 1007n=$((n + 1)) 1008echo_i "testing updating inline secure serial via 'rndc signing -serial' ($n)" 1009ret=0 1010$DIG $DIGOPTS nsec3. SOA @10.53.0.3 >dig.out.n3.pre.test$n || ret=1 1011newserial=$($PERL -e 'while (<>) { chomp; my @field = split /\s+/; printf("%u\n", $field[6] + 10) if ($field[3] eq "SOA"); }' <dig.out.n3.pre.test$n) 1012$RNDCCMD 10.53.0.3 signing -serial ${newserial:-0} nsec3 >/dev/null 2>&1 || ret=1 1013retry_quiet 5 wait_for_serial 10.53.0.3 nsec3. "${newserial:-0}" dig.out.ns3.post.test$n || ret=1 1014if [ $ret != 0 ]; then echo_i "failed"; fi 1015status=$((status + ret)) 1016 1017n=$((n + 1)) 1018echo_i "testing updating inline secure serial via 'rndc signing -serial' with negative change ($n)" 1019ret=0 1020$DIG $DIGOPTS nsec3. SOA @10.53.0.3 >dig.out.n3.pre.test$n || ret=1 1021oldserial=$(awk '$4 == "SOA" { print $7 }' dig.out.n3.pre.test$n) 1022newserial=$($PERL -e 'while (<>) { chomp; my @field = split /\s+/; printf("%u\n", $field[6] - 10) if ($field[3] eq "SOA"); }' <dig.out.n3.pre.test$n) 1023$RNDCCMD 10.53.0.3 signing -serial ${newserial:-0} nsec3 >/dev/null 2>&1 || ret=1 1024sleep 1 1025$DIG $DIGOPTS nsec3. SOA @10.53.0.3 >dig.out.ns3.post.test$n || ret=1 1026serial=$(awk '$4 == "SOA" { print $7 }' dig.out.ns3.post.test$n) 1027[ ${oldserial:-0} -eq ${serial:-1} ] || ret=1 1028if [ $ret != 0 ]; then echo_i "failed"; fi 1029status=$((status + ret)) 1030 1031# 1032# Freezing only operates on the raw zone. 1033# 1034n=$((n + 1)) 1035echo_i "testing updating inline secure serial via 'rndc signing -serial' when frozen ($n)" 1036ret=0 1037$DIG $DIGOPTS nsec3. SOA @10.53.0.3 >dig.out.n3.pre.test$n || ret=1 1038oldserial=$(awk '$4 == "SOA" { print $7 }' dig.out.n3.pre.test$n) 1039newserial=$($PERL -e 'while (<>) { chomp; my @field = split /\s+/; printf("%u\n", $field[6] + 10) if ($field[3] eq "SOA"); }' <dig.out.n3.pre.test$n) 1040$RNDCCMD 10.53.0.3 freeze nsec3 >/dev/null 2>&1 || ret=1 1041$RNDCCMD 10.53.0.3 signing -serial ${newserial:-0} nsec3 >/dev/null 2>&1 || ret=1 1042$RNDCCMD 10.53.0.3 thaw nsec3 >/dev/null 2>&1 || ret=1 1043retry_quiet 5 wait_for_serial 10.53.0.3 nsec3. "${newserial:-0}" dig.out.ns3.post1.test$n || ret=1 1044if [ $ret != 0 ]; then echo_i "failed"; fi 1045status=$((status + ret)) 1046 1047n=$((n + 1)) 1048echo_i "testing updating dynamic serial via 'rndc signing -serial' ($n)" 1049ret=0 1050$DIG $DIGOPTS bits. SOA @10.53.0.2 >dig.out.ns2.pre.test$n || ret=1 1051newserial=$($PERL -e 'while (<>) { chomp; my @field = split /\s+/; printf("%u\n", $field[6] + 10) if ($field[3] eq "SOA"); }' <dig.out.ns2.pre.test$n) 1052$RNDCCMD 10.53.0.2 signing -serial ${newserial:-0} bits >/dev/null 2>&1 || ret=1 1053retry_quiet 5 wait_for_serial 10.53.0.2 bits. "${newserial:-0}" dig.out.ns2.post.test$n || ret=1 1054if [ $ret != 0 ]; then echo_i "failed"; fi 1055status=$((status + ret)) 1056 1057n=$((n + 1)) 1058echo_i "testing updating dynamic serial via 'rndc signing -serial' with negative change ($n)" 1059ret=0 1060$DIG $DIGOPTS bits. SOA @10.53.0.2 >dig.out.ns2.pre.test$n || ret=1 1061oldserial=$(awk '$4 == "SOA" { print $7 }' dig.out.ns2.pre.test$n) 1062newserial=$($PERL -e 'while (<>) { chomp; my @field = split /\s+/; printf("%u\n", $field[6] - 10) if ($field[3] eq "SOA"); }' <dig.out.ns2.pre.test$n) 1063$RNDCCMD 10.53.0.2 signing -serial ${newserial:-0} bits >/dev/null 2>&1 || ret=1 1064retry_quiet 5 wait_for_serial 10.53.0.2 bits. "${newserial:-1}" dig.out.ns2.post1.test$n && ret=1 1065retry_quiet 5 wait_for_serial 10.53.0.2 bits. "${oldserial:-1}" dig.out.ns2.post2.test$n || ret=1 1066if [ $ret != 0 ]; then echo_i "failed"; fi 1067status=$((status + ret)) 1068 1069n=$((n + 1)) 1070echo_i "testing updating dynamic serial via 'rndc signing -serial' when frozen ($n)" 1071ret=0 1072$DIG $DIGOPTS bits. SOA @10.53.0.2 >dig.out.ns2.pre.test$n || ret=1 1073oldserial=$(awk '$4 == "SOA" { print $7 }' dig.out.ns2.pre.test$n) 1074newserial=$($PERL -e 'while (<>) { chomp; my @field = split /\s+/; printf("%u\n", $field[6] + 10) if ($field[3] eq "SOA"); }' <dig.out.ns2.pre.test$n) 1075$RNDCCMD 10.53.0.2 freeze bits >/dev/null 2>&1 || ret=1 1076$RNDCCMD 10.53.0.2 signing -serial ${newserial:-0} bits >/dev/null 2>&1 && ret=1 1077$RNDCCMD 10.53.0.2 thaw bits >/dev/null 2>&1 || ret=1 1078retry_quiet 5 wait_for_serial 10.53.0.2 bits. "${newserial:-1}" dig.out.ns2.post1.test$n && ret=1 1079retry_quiet 5 wait_for_serial 10.53.0.2 bits. "${oldserial:-1}" dig.out.ns2.post2.test$n || ret=1 1080if [ $ret != 0 ]; then echo_i "failed"; fi 1081status=$((status + ret)) 1082 1083# Wait until an update to the raw part of a given inline signed zone is fully 1084# processed. As waiting for a fixed amount of time is suboptimal and there is 1085# no single message that would signify both a successful modification and an 1086# error in a race-free manner, instead wait until either notifies are sent 1087# (which means the secure zone was modified) or a receive_secure_serial() error 1088# is logged (which means the zone was not modified and will not be modified any 1089# further in response to the relevant raw zone update). 1090wait_until_raw_zone_update_is_processed() { 1091 zone="$1" 1092 for i in 1 2 3 4 5 6 7 8 9 10; do 1093 if nextpart ns3/named.run | grep -E "zone ${zone}.*(sending notifies|receive_secure_serial)" >/dev/null; then 1094 return 1095 fi 1096 sleep 1 1097 done 1098} 1099 1100n=$((n + 1)) 1101echo_i "checking that changes to raw zone are applied to a previously unsigned secure zone ($n)" 1102ret=0 1103# Query for bar.nokeys/A and ensure the response is negative. As this zone 1104# does not have any signing keys set up, the response must be unsigned. 1105$DIG $DIGOPTS @10.53.0.3 bar.nokeys. A >dig.out.ns3.pre.test$n 2>&1 || ret=1 1106grep "status: NOERROR" dig.out.ns3.pre.test$n >/dev/null && ret=1 1107grep "RRSIG" dig.out.ns3.pre.test$n >/dev/null && ret=1 1108# Ensure the wait_until_raw_zone_update_is_processed() call below will ignore 1109# log messages generated before the raw zone is updated. 1110nextpart ns3/named.run >/dev/null 1111# Add a record to the raw zone on the primary. 1112$NSUPDATE <<EOF || ret=1 1113zone nokeys. 1114server 10.53.0.2 ${PORT} 1115update add bar.nokeys. 0 A 127.0.0.1 1116send 1117EOF 1118wait_until_raw_zone_update_is_processed "nokeys" 1119# Query for bar.nokeys/A again and ensure the signer now returns a positive, 1120# yet still unsigned response. 1121$DIG $DIGOPTS @10.53.0.3 bar.nokeys. A >dig.out.ns3.post.test$n 2>&1 || ret=1 1122grep "status: NOERROR" dig.out.ns3.post.test$n >/dev/null || ret=1 1123grep "RRSIG" dig.out.ns3.pre.test$n >/dev/null && ret=1 1124if [ $ret != 0 ]; then echo_i "failed"; fi 1125status=$((status + ret)) 1126 1127n=$((n + 1)) 1128echo_i "checking that changes to raw zone are not applied to a previously signed secure zone with no keys available (primary) ($n)" 1129ret=0 1130# Query for bar.removedkeys-primary/A and ensure the response is negative. As 1131# this zone has signing keys set up, the response must be signed. 1132$DIG $DIGOPTS @10.53.0.3 bar.removedkeys-primary. A >dig.out.ns3.pre.test$n 2>&1 || ret=1 1133grep "status: NOERROR" dig.out.ns3.pre.test$n >/dev/null && ret=1 1134grep "RRSIG" dig.out.ns3.pre.test$n >/dev/null || ret=1 1135# Remove the signing keys for this zone. 1136mv -f ns3/Kremovedkeys-primary* ns3/removedkeys 1137# Ensure the wait_until_raw_zone_update_is_processed() call below will ignore 1138# log messages generated before the raw zone is updated. 1139nextpart ns3/named.run >/dev/null 1140# Add a record to the raw zone on the primary. 1141$NSUPDATE <<EOF || ret=1 1142zone removedkeys-primary. 1143server 10.53.0.3 ${PORT} 1144update add bar.removedkeys-primary. 0 A 127.0.0.1 1145send 1146EOF 1147wait_until_raw_zone_update_is_processed "removedkeys-primary" 1148# Query for bar.removedkeys-primary/A again and ensure the signer still returns 1149# a negative, signed response. 1150$DIG $DIGOPTS @10.53.0.3 bar.removedkeys-primary. A >dig.out.ns3.post.test$n 2>&1 || ret=1 1151grep "status: NOERROR" dig.out.ns3.post.test$n >/dev/null && ret=1 1152grep "RRSIG" dig.out.ns3.pre.test$n >/dev/null || ret=1 1153if [ $ret != 0 ]; then echo_i "failed"; fi 1154status=$((status + ret)) 1155 1156n=$((n + 1)) 1157echo_i "checking that backlogged changes to raw zone are applied after keys become available (primary) ($n)" 1158ret=0 1159# Restore the signing keys for this zone. 1160mv ns3/removedkeys/Kremovedkeys-primary* ns3 1161$RNDCCMD 10.53.0.3 loadkeys removedkeys-primary >/dev/null 2>&1 || ret=1 1162# Determine what a SOA record with a bumped serial number should look like. 1163BUMPED_SOA=$(sed -n 's/.*\(add removedkeys-primary.*IN.*SOA\)/\1/p;' ns3/named.run | tail -1 | awk '{$8 += 1; print $0}') 1164# Ensure the wait_until_raw_zone_update_is_processed() call below will ignore 1165# log messages generated before the raw zone is updated. 1166nextpart ns3/named.run >/dev/null 1167# Bump the SOA serial number of the raw zone. 1168$NSUPDATE <<EOF || ret=1 1169zone removedkeys-primary. 1170server 10.53.0.3 ${PORT} 1171update del removedkeys-primary. SOA 1172update ${BUMPED_SOA} 1173send 1174EOF 1175wait_until_raw_zone_update_is_processed "removedkeys-primary" 1176# Query for bar.removedkeys-primary/A again and ensure the signer now returns a 1177# positive, signed response. 1178$DIG $DIGOPTS @10.53.0.3 bar.removedkeys-primary. A >dig.out.ns3.test$n 2>&1 || ret=1 1179grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 1180grep "RRSIG" dig.out.ns3.test$n >/dev/null || ret=1 1181if [ $ret != 0 ]; then echo_i "failed"; fi 1182status=$((status + ret)) 1183 1184n=$((n + 1)) 1185echo_i "checking that changes to raw zone are not applied to a previously signed secure zone with no keys available (secondary) ($n)" 1186ret=0 1187# Query for bar.removedkeys-secondary/A and ensure the response is negative. As this 1188# zone does have signing keys set up, the response must be signed. 1189$DIG $DIGOPTS @10.53.0.3 bar.removedkeys-secondary. A >dig.out.ns3.pre.test$n 2>&1 || ret=1 1190grep "status: NOERROR" dig.out.ns3.pre.test$n >/dev/null && ret=1 1191grep "RRSIG" dig.out.ns3.pre.test$n >/dev/null || ret=1 1192# Remove the signing keys for this zone. 1193mv -f ns3/Kremovedkeys-secondary* ns3/removedkeys 1194# Ensure the wait_until_raw_zone_update_is_processed() call below will ignore 1195# log messages generated before the raw zone is updated. 1196nextpart ns3/named.run >/dev/null 1197# Add a record to the raw zone on the primary. 1198$NSUPDATE <<EOF || ret=1 1199zone removedkeys-secondary. 1200server 10.53.0.2 ${PORT} 1201update add bar.removedkeys-secondary. 0 A 127.0.0.1 1202send 1203EOF 1204wait_until_raw_zone_update_is_processed "removedkeys-secondary" 1205# Query for bar.removedkeys-secondary/A again and ensure the signer still returns a 1206# negative, signed response. 1207$DIG $DIGOPTS @10.53.0.3 bar.removedkeys-secondary. A >dig.out.ns3.post.test$n 2>&1 || ret=1 1208grep "status: NOERROR" dig.out.ns3.post.test$n >/dev/null && ret=1 1209grep "RRSIG" dig.out.ns3.pre.test$n >/dev/null || ret=1 1210if [ $ret != 0 ]; then echo_i "failed"; fi 1211status=$((status + ret)) 1212 1213n=$((n + 1)) 1214echo_i "checking that backlogged changes to raw zone are applied after keys become available (secondary) ($n)" 1215ret=0 1216# Restore the signing keys for this zone. 1217mv ns3/removedkeys/Kremovedkeys-secondary* ns3 1218$RNDCCMD 10.53.0.3 loadkeys removedkeys-secondary >/dev/null 2>&1 || ret=1 1219# Determine what a SOA record with a bumped serial number should look like. 1220BUMPED_SOA=$(sed -n 's/.*\(add removedkeys-secondary.*IN.*SOA\)/\1/p;' ns2/named.run | tail -1 | awk '{$8 += 1; print $0}') 1221# Ensure the wait_until_raw_zone_update_is_processed() call below will ignore 1222# log messages generated before the raw zone is updated. 1223nextpart ns3/named.run >/dev/null 1224# Bump the SOA serial number of the raw zone on the primary. 1225$NSUPDATE <<EOF || ret=1 1226zone removedkeys-secondary. 1227server 10.53.0.2 ${PORT} 1228update del removedkeys-secondary. SOA 1229update ${BUMPED_SOA} 1230send 1231EOF 1232wait_until_raw_zone_update_is_processed "removedkeys-secondary" 1233# Query for bar.removedkeys-secondary/A again and ensure the signer now returns 1234# a positive, signed response. 1235$DIG $DIGOPTS @10.53.0.3 bar.removedkeys-secondary. A >dig.out.ns3.test$n 2>&1 || ret=1 1236grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 1237grep "RRSIG" dig.out.ns3.test$n >/dev/null || ret=1 1238if [ $ret != 0 ]; then echo_i "failed"; fi 1239status=$((status + ret)) 1240 1241# Check that the file $2 for zone $1 does not contain RRSIG records 1242# while the journal file for that zone does contain them. 1243ensure_sigs_only_in_journal() { 1244 origin="$1" 1245 masterfile="$2" 1246 $CHECKZONE -i none -f raw -D -o - "$origin" "$masterfile" 2>&1 | grep -w RRSIG >/dev/null && ret=1 1247 $CHECKZONE -j -i none -f raw -D -o - "$origin" "$masterfile" 2>&1 | grep -w RRSIG >/dev/null || ret=1 1248} 1249 1250n=$((n + 1)) 1251echo_i "checking that records added from a journal are scheduled to be resigned ($n)" 1252ret=0 1253zone="delayedkeys" 1254# Signing keys for the "delayedkeys" zone are not yet accessible. Thus, the 1255# zone file for the signed version of the zone will contain no DNSSEC records. 1256# Move keys into place now and load them, which will cause DNSSEC records to 1257# only be present in the journal for the signed version of the zone. 1258mv Kdelayedkeys* ns3/ 1259cp ns3/delayedkeys.conf.2 ns3/delayedkeys.conf 1260$RNDCCMD 10.53.0.3 reconfig >/dev/null 2>&1 || ret=1 1261 1262#$RNDCCMD 10.53.0.3 loadkeys delayedkeys > rndc.out.ns3.pre.test$n 2>&1 || ret=1 1263# Wait until the zone is signed. 1264check_done_signing() ( 1265 $RNDCCMD 10.53.0.3 signing -list delayedkeys >signing.out.test$n 2>&1 || true 1266 num=$(grep "Done signing with" signing.out.test$n | wc -l) 1267 [ $num -eq 2 ] 1268) 1269retry_quiet 10 check_done_signing || ret=1 1270# Halt rather than stopping the server to prevent the file from being 1271# flushed upon shutdown since we specifically want to avoid it. 1272stop_server --use-rndc --halt --port ${CONTROLPORT} ns3 || ret=1 1273ensure_sigs_only_in_journal delayedkeys ns3/delayedkeys.db.signed 1274start_server --noclean --restart --port ${PORT} ns3 || ret=1 1275# At this point, the raw zone journal will not have a source serial set. Upon 1276# server startup, receive_secure_serial() will rectify that, update SOA, resign 1277# it, and schedule its future resign. This will cause "rndc zonestatus" to 1278# return delayedkeys/SOA as the next node to resign, so we restart the server 1279# once again; with the raw zone journal now having a source serial set, 1280# receive_secure_serial() should refrain from introducing any zone changes. 1281stop_server --use-rndc --halt --port ${CONTROLPORT} ns3 || ret=1 1282ensure_sigs_only_in_journal delayedkeys ns3/delayedkeys.db.signed 1283nextpart ns3/named.run >/dev/null 1284start_server --noclean --restart --port ${PORT} ns3 || ret=1 1285# We can now test whether the secure zone journal was correctly processed: 1286# unless the records contained in it were scheduled for resigning, no resigning 1287# event will be scheduled at all since the secure zone file contains no 1288# DNSSEC records. 1289wait_for_log 20 "all zones loaded" ns3/named.run || ret=1 1290$RNDCCMD 10.53.0.3 zonestatus delayedkeys >rndc.out.ns3.post.test$n 2>&1 || ret=1 1291grep "next resign node:" rndc.out.ns3.post.test$n >/dev/null || ret=1 1292if [ $ret != 0 ]; then echo_i "failed"; fi 1293status=$((status + ret)) 1294 1295n=$((n + 1)) 1296echo_i "check that zonestatus reports 'type: primary' for an inline primary zone ($n)" 1297ret=0 1298$RNDCCMD 10.53.0.3 zonestatus primary >rndc.out.ns3.test$n || ret=1 1299grep "type: primary" rndc.out.ns3.test$n >/dev/null || ret=1 1300if [ $ret != 0 ]; then echo_i "failed"; fi 1301status=$((status + ret)) 1302 1303n=$((n + 1)) 1304echo_i "check that zonestatus reports 'type: secondary' for an inline secondary zone ($n)" 1305ret=0 1306$RNDCCMD 10.53.0.3 zonestatus bits >rndc.out.ns3.test$n || ret=1 1307grep "type: secondary" rndc.out.ns3.test$n >/dev/null || ret=1 1308if [ $ret != 0 ]; then echo_i "failed"; fi 1309status=$((status + ret)) 1310 1311n=$((n + 1)) 1312echo_i "checking reload of touched inline zones ($n)" 1313ret=0 1314echo_ic "pre-reload 'next key event'" 1315nextpart ns8/named.run >nextpart.pre$n.out 1316count=$(grep "zone example[0-9][0-9].com/IN (signed): next key event:" nextpart.pre$n.out | wc -l) 1317echo_ic "found: $count/16" 1318[ $count -eq 16 ] || ret=1 1319echo_ic "touch and reload" 1320touch ns8/example??.com.db 1321$RNDCCMD 10.53.0.8 reload 2>&1 | sed 's/^/ns3 /' | cat_i 1322sleep 5 1323echo_ic "post-reload 'next key event'" 1324nextpart ns8/named.run >nextpart.post$n.out 1325count=$(grep "zone example[0-9][0-9].com/IN (signed): next key event:" nextpart.post$n.out | wc -l) 1326echo_ic "found: $count/16" 1327[ $count -eq 16 ] || ret=1 1328if [ $ret != 0 ]; then echo_i "failed"; fi 1329status=$((status + ret)) 1330 1331n=$((n + 1)) 1332echo_i "checking second reload of touched inline zones ($n)" 1333ret=0 1334nextpart ns8/named.run >nextpart.pre$n.out 1335$RNDCCMD 10.53.0.8 reload 2>&1 | sed 's/^/ns3 /' | cat_i 1336sleep 5 1337nextpart ns8/named.run >nextpart.post$n.out 1338grep "ixfr-from-differences: unchanged" nextpart.post$n.out && ret=1 1339if [ $ret != 0 ]; then echo_i "failed"; fi 1340status=$((status + ret)) 1341 1342n=$((n + 1)) 1343echo_i "Check that 'rndc reload' of just the serial updates the signed instance ($n)" 1344ret=0 1345dig_with_opts @10.53.0.8 example SOA >dig.out.ns8.test$n.soa1 || ret=1 1346cp ns8/example2.db.in ns8/example.db || ret=1 1347nextpart ns8/named.run >/dev/null 1348rndccmd 10.53.0.8 reload || ret=1 1349wait_for_log 3 "all zones loaded" ns8/named.run 1350sleep 1 1351dig_with_opts @10.53.0.8 example SOA >dig.out.ns8.test$n.soa2 || ret=1 1352soa1=$(awk '$4 == "SOA" { print $7 }' dig.out.ns8.test$n.soa1) 1353soa2=$(awk '$4 == "SOA" { print $7 }' dig.out.ns8.test$n.soa2) 1354ttl1=$(awk '$4 == "SOA" { print $2 }' dig.out.ns8.test$n.soa1) 1355ttl2=$(awk '$4 == "SOA" { print $2 }' dig.out.ns8.test$n.soa2) 1356test ${soa1:-1000} -lt ${soa2:-0} || ret=1 1357test ${ttl1:-0} -eq 300 || ret=1 1358test ${ttl2:-0} -eq 300 || ret=1 1359test "$ret" -eq 0 || echo_i "failed" 1360status=$((status + ret)) 1361 1362n=$((n + 1)) 1363echo_i "Check that restart with zone changes and deleted journal works ($n)" 1364TSIG= 1365ret=0 1366dig_with_opts @10.53.0.8 example SOA >dig.out.ns8.test$n.soa1 || ret=1 1367stop_server --use-rndc --port ${CONTROLPORT} ns8 || ret=1 1368# TTL of all records change from 300 to 400 1369cp ns8/example3.db.in ns8/example.db || ret=1 1370rm -f ns8/example.db.jnl 1371nextpart ns8/named.run >/dev/null 1372start_server --noclean --restart --port ${PORT} ns8 || ret=1 1373wait_for_log 3 "all zones loaded" ns8/named.run 1374sleep 1 1375dig_with_opts @10.53.0.8 example SOA >dig.out.ns8.test$n.soa2 || ret=1 1376soa1=$(awk '$4 == "SOA" { print $7 }' dig.out.ns8.test$n.soa1) 1377soa2=$(awk '$4 == "SOA" { print $7 }' dig.out.ns8.test$n.soa2) 1378ttl1=$(awk '$4 == "SOA" { print $2 }' dig.out.ns8.test$n.soa1) 1379ttl2=$(awk '$4 == "SOA" { print $2 }' dig.out.ns8.test$n.soa2) 1380test ${soa1:-1000} -lt ${soa2:-0} || ret=1 1381test ${ttl1:-0} -eq 300 || ret=1 1382test ${ttl2:-0} -eq 400 || ret=1 1383test "$ret" -eq 0 || echo_i "failed" 1384status=$((status + ret)) 1385 1386echo_i "exit status: $status" 1387[ $status -eq 0 ] || exit 1 1388