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 14SYSTEMTESTTOP=.. 15. $SYSTEMTESTTOP/conf.sh 16 17status=0 18n=0 19 20DIGOPTS="+tcp +noadd +nosea +nostat +nocmd +dnssec -p ${PORT}" 21RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s" 22 23# convert private-type records to readable form 24showprivate () { 25 echo "-- $@ --" 26 $DIG $DIGOPTS +nodnssec +short @$2 -t type65534 $1 | cut -f3 -d' ' | 27 while read record; do 28 $PERL -e 'my $rdata = pack("H*", @ARGV[0]); 29 die "invalid record" unless length($rdata) == 5; 30 my ($alg, $key, $remove, $complete) = unpack("CnCC", $rdata); 31 my $action = "signing"; 32 $action = "removing" if $remove; 33 my $state = " (incomplete)"; 34 $state = " (complete)" if $complete; 35 print ("$action: alg: $alg, key: $key$state\n");' $record 36 done 37} 38 39# check that signing records are marked as complete 40checkprivate () { 41 _ret=0 42 expected="${3:-0}" 43 x=$(showprivate "$@") 44 echo $x | grep incomplete > /dev/null && _ret=1 45 46 if [ $_ret = $expected ]; then 47 return 0 48 fi 49 50 echo "$x" 51 echo_i "failed" 52 return 1 53} 54 55# wait until notifies for zone $1 are sent by server $2. This is an indication 56# that the zone is signed with the active keys, and the changes have been 57# committed. 58wait_for_notifies () { 59 wait_for_log 10 "zone ${1}/IN: sending notifies" "${2}/named.run" || return 1 60} 61 62freq() { 63 _file=$1 64 # remove first and last line that has incomplete set and skews the distribution 65 awk '$4 == "RRSIG" {print substr($9,1,8)}' < "$_file" | sort | uniq -c | sed '1d;$d' 66} 67# Check the signatures expiration times. First check how many signatures 68# there are in total ($rrsigs). Then see what the distribution of signature 69# expiration times is ($expiretimes). Ignore the time part for a better 70# modelled distribution. 71checkjitter () { 72 _file=$1 73 _ret=0 74 75 if ! command -v bc >/dev/null 2>&1; then 76 echo_i "skip: bc not available" 77 return 0 78 fi 79 80 freq "$_file" | cat_i 81 _expiretimes=$(freq "$_file" | awk '{print $1}') 82 83 _count=0 84 # Check if we have at least 4 days 85 # This number has been tuned for `sig-validity-interval 10 2`, as 86 # 1 signature expiration dates should be spread out across at most 8 (10-2) days 87 # 2. we remove first and last day to remove frequency outlier, we are left with 6 (8-2) days 88 # 3. we subtract two more days to allow test pass on day boundaries, etc. leaving us with 4 (6-2) 89 for _num in $_expiretimes 90 do 91 _count=$((_count+1)) 92 done 93 if [ "$_count" -lt 4 ]; then 94 echo_i "error: not enough categories" 95 return 1 96 fi 97 98 # Calculate mean 99 _total=0 100 for _num in $_expiretimes 101 do 102 _total=$((_total+_num)) 103 done 104 _mean=$(($_total / $_count)) 105 106 # Calculate stddev 107 _stddev=0 108 for _num in $_expiretimes 109 do 110 _stddev=$(echo "$_stddev + (($_num - $_mean) * ($_num - $_mean))" | bc) 111 done 112 _stddev=$(echo "sqrt($_stddev/$_count)" | bc) 113 114 # We expect the number of signatures not to exceed the mean +- 3 * stddev. 115 _limit=$((_stddev*3)) 116 _low=$((_mean-_limit)) 117 _high=$((_mean+_limit)) 118 # Find outliers. 119 echo_i "checking whether all frequencies fall into <$_low;$_high> range" 120 for _num in $_expiretimes 121 do 122 if [ $_num -gt $_high ]; then 123 echo_i "error: too many RRSIG records ($_num) in expiration bucket" 124 _ret=1 125 fi 126 if [ $_num -lt $_low ]; then 127 echo_i "error: too few RRSIG records ($_num) in expiration bucket" 128 _ret=1 129 fi 130 done 131 132 return $_ret 133} 134 135# 136# The NSEC record at the apex of the zone and its RRSIG records are 137# added as part of the last step in signing a zone. We wait for the 138# NSEC records to appear before proceeding with a counter to prevent 139# infinite loops if there is a error. 140# 141echo_i "waiting for autosign changes to take effect" 142i=0 143while [ $i -lt 30 ] 144do 145 ret=0 146 # 147 # Wait for the root DNSKEY RRset to be fully signed. 148 # 149 $DIG $DIGOPTS . @10.53.0.1 dnskey > dig.out.ns1.test$n || ret=1 150 grep "ANSWER: 10," dig.out.ns1.test$n > /dev/null || ret=1 151 for z in . 152 do 153 $DIG $DIGOPTS $z @10.53.0.1 nsec > dig.out.ns1.test$n || ret=1 154 grep "NS SOA" dig.out.ns1.test$n > /dev/null || ret=1 155 done 156 for z in bar. example. private.secure.example. optout-with-ent. 157 do 158 $DIG $DIGOPTS $z @10.53.0.2 nsec > dig.out.ns2.test$n || ret=1 159 grep "NS SOA" dig.out.ns2.test$n > /dev/null || ret=1 160 done 161 for z in bar. example. inacksk2.example. inacksk3.example \ 162 inaczsk2.example. inaczsk3.example noksk.example nozsk.example 163 do 164 $DIG $DIGOPTS $z @10.53.0.3 nsec > dig.out.ns3.test$n || ret=1 165 grep "NS SOA" dig.out.ns3.test$n > /dev/null || ret=1 166 done 167 i=$((i + 1)) 168 if [ $ret = 0 ]; then break; fi 169 echo_i "waiting ... ($i)" 170 sleep 2 171done 172n=$((n + 1)) 173if [ $ret != 0 ]; then echo_i "done"; fi 174status=$((status + ret)) 175 176echo_i "Convert optout-with-ent from nsec to nsec3" 177($RNDCCMD 10.53.0.2 signing -nsec3param 1 1 1 - optout-with-ent 2>&1 | sed 's/^/ns2 /' | cat_i) || ret=1 178 179echo_i "Initial counts of RRSIG expiry fields values for auto signed zones" 180for z in . 181do 182 echo_i zone $z 183 $DIG $DIGOPTS $z @10.53.0.1 axfr | awk '$4 == "RRSIG" {print $9}' | sort | uniq -c | cat_i 184done 185for z in bar. example. private.secure.example. 186do 187 echo_i zone $z 188 $DIG $DIGOPTS $z @10.53.0.2 axfr | awk '$4 == "RRSIG" {print $9}' | sort | uniq -c | cat_i 189done 190for z in inacksk2.example. inacksk3.example inaczsk2.example. inaczsk3.example 191do 192 echo_i zone $z 193 $DIG $DIGOPTS $z @10.53.0.3 axfr | awk '$4 == "RRSIG" {print $9}' | sort | uniq -c | cat_i 194done 195 196# Set logfile offset for wait_for_log usage. 197nextpartreset ns3/named.run 198 199# 200# Check that DNSKEY is initially signed with a KSK and not a ZSK. 201# 202echo_i "check that zone with active and inactive KSK and active ZSK is properly" 203echo_ic "resigned after the active KSK is deleted - stage 1: Verify that DNSKEY" 204echo_ic "is initially signed with a KSK and not a ZSK. ($n)" 205ret=0 206 207$DIG $DIGOPTS @10.53.0.3 axfr inacksk3.example > dig.out.ns3.test$n 208 209zskid=$(awk '$4 == "DNSKEY" && $5 == 256 { print }' dig.out.ns3.test$n | 210 $DSFROMKEY -A -2 -f - inacksk3.example | awk '{ print $4}') 211grep "DNSKEY ${DEFAULT_ALGORITHM_NUMBER} 2 " dig.out.ns3.test$n > /dev/null || ret=1 212 213pattern="DNSKEY ${DEFAULT_ALGORITHM_NUMBER} 2 [0-9]* [0-9]* [0-9]* ${zskid} " 214grep "${pattern}" dig.out.ns3.test$n > /dev/null && ret=1 215 216count=$(awk 'BEGIN { count = 0 } 217 $4 == "RRSIG" && $5 == "DNSKEY" { count++ } 218 END {print count}' dig.out.ns3.test$n) 219test $count -eq 1 || ret=1 220 221count=$(awk 'BEGIN { count = 0 } 222 $4 == "DNSKEY" { count++ } 223 END {print count}' dig.out.ns3.test$n) 224test $count -eq 3 || ret=1 225 226awk='$4 == "RRSIG" && $5 == "DNSKEY" { printf "%05u\n", $11 }' 227id=$(awk "${awk}" dig.out.ns3.test$n) 228 229keyfile=$(printf "ns3/Kinacksk3.example.+%03u+%s" "${DEFAULT_ALGORITHM_NUMBER}" "${id}") 230$SETTIME -D now+5 "${keyfile}" > settime.out.test$n || ret=1 231($RNDCCMD 10.53.0.3 loadkeys inacksk3.example 2>&1 | sed 's/^/ns3 /' | cat_i) || ret=1 232 233n=$((n + 1)) 234if [ $ret != 0 ]; then echo_i "failed"; fi 235status=$((status + ret)) 236 237# 238# Check that zone is initially signed with a ZSK and not a KSK. 239# 240echo_i "check that zone with active and inactive ZSK and active KSK is properly" 241echo_ic "resigned after the active ZSK is deleted - stage 1: Verify that zone" 242echo_ic "is initially signed with a ZSK and not a KSK. ($n)" 243ret=0 244$DIG $DIGOPTS @10.53.0.3 axfr inaczsk3.example > dig.out.ns3.test$n 245kskid=$(awk '$4 == "DNSKEY" && $5 == 257 { print }' dig.out.ns3.test$n | 246 $DSFROMKEY -2 -f - inaczsk3.example | awk '{ print $4}' ) 247grep "CNAME ${DEFAULT_ALGORITHM_NUMBER} 3 " dig.out.ns3.test$n > /dev/null || ret=1 248grep "CNAME ${DEFAULT_ALGORITHM_NUMBER} 3 [0-9]* [0-9]* [0-9]* ${kskid} " dig.out.ns3.test$n > /dev/null && ret=1 249count=$(awk 'BEGIN { count = 0 } 250 $4 == "RRSIG" && $5 == "CNAME" { count++ } 251 END {print count}' dig.out.ns3.test$n) 252test $count -eq 1 || ret=1 253count=$(awk 'BEGIN { count = 0 } 254 $4 == "DNSKEY" { count++ } 255 END {print count}' dig.out.ns3.test$n) 256test $count -eq 3 || ret=1 257id=$(awk '$4 == "RRSIG" && $5 == "CNAME" { printf "%05u\n", $11 }' dig.out.ns3.test$n) 258 259keyfile=$(printf "ns3/Kinaczsk3.example.+%03u+%s" "${DEFAULT_ALGORITHM_NUMBER}" "${id}") 260$SETTIME -D now+5 "${keyfile}" > settime.out.test$n || ret=1 261($RNDCCMD 10.53.0.3 loadkeys inaczsk3.example 2>&1 | sed 's/^/ns3 /' | cat_i) || ret=1 262n=$((n + 1)) 263if [ $ret != 0 ]; then echo_i "failed"; fi 264status=$((status + ret)) 265 266echo_i "checking NSEC->NSEC3 conversion prerequisites ($n)" 267ret=0 268# these commands should result in an empty file: 269$DIG $DIGOPTS +noall +answer nsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.1.test$n || ret=1 270grep "NSEC3PARAM" dig.out.ns3.1.test$n > /dev/null && ret=1 271$DIG $DIGOPTS +noall +answer autonsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.2.test$n || ret=1 272grep "NSEC3PARAM" dig.out.ns3.2.test$n > /dev/null && ret=1 273n=$((n + 1)) 274if [ $ret != 0 ]; then echo_i "failed"; fi 275status=$((status + ret)) 276 277echo_i "checking NSEC3->NSEC conversion prerequisites ($n)" 278ret=0 279$DIG $DIGOPTS +noall +answer nsec3-to-nsec.example. nsec3param @10.53.0.3 > dig.out.ns3.test$n || ret=1 280grep "NSEC3PARAM" dig.out.ns3.test$n > /dev/null || ret=1 281n=$((n + 1)) 282if [ $ret != 0 ]; then echo_i "failed"; fi 283status=$((status + ret)) 284 285echo_i "converting zones from nsec to nsec3" 286$NSUPDATE > /dev/null 2>&1 <<END || status=1 287server 10.53.0.3 ${PORT} 288zone nsec3.nsec3.example. 289update add nsec3.nsec3.example. 3600 NSEC3PARAM 1 0 10 BEEF 290send 291zone optout.nsec3.example. 292update add optout.nsec3.example. 3600 NSEC3PARAM 1 1 10 BEEF 293send 294zone nsec3.example. 295update add nsec3.example. 3600 NSEC3PARAM 1 0 10 BEEF 296send 297zone autonsec3.example. 298update add autonsec3.example. 3600 NSEC3PARAM 1 0 20 DEAF 299send 300zone nsec3.optout.example. 301update add nsec3.optout.example. 3600 NSEC3PARAM 1 0 10 BEEF 302send 303zone optout.optout.example. 304update add optout.optout.example. 3600 NSEC3PARAM 1 1 10 BEEF 305send 306zone optout.example. 307update add optout.example. 3600 NSEC3PARAM 1 1 10 BEEF 308send 309END 310 311if $SHELL ../testcrypto.sh -q RSASHA1 312then 313 # try to convert nsec-only.example; this should fail due to 314 # non-NSEC3 compatible keys 315 echo_i "preset nsec3param in unsigned zone via nsupdate ($n)" 316 $NSUPDATE > nsupdate.out 2>&1 <<END 317server 10.53.0.3 ${PORT} 318zone nsec-only.example. 319update add nsec-only.example. 3600 NSEC3PARAM 1 0 10 BEEF 320send 321END 322fi 323 324echo_i "checking for nsec3param in unsigned zone ($n)" 325ret=0 326$DIG $DIGOPTS +noall +answer autonsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.test$n || ret=1 327grep "NSEC3PARAM" dig.out.ns3.test$n > /dev/null && ret=1 328n=$((n + 1)) 329if [ $ret != 0 ]; then echo_i "failed"; fi 330status=$((status + ret)) 331 332echo_i "checking for nsec3param signing record ($n)" 333ret=0 334$RNDCCMD 10.53.0.3 signing -list autonsec3.example. > signing.out.test$n 2>&1 335grep "Pending NSEC3 chain 1 0 20 DEAF" signing.out.test$n > /dev/null || ret=1 336n=$((n + 1)) 337if [ $ret != 0 ]; then echo_i "failed"; fi 338status=$((status + ret)) 339 340echo_i "resetting nsec3param via rndc signing ($n)" 341ret=0 342$RNDCCMD 10.53.0.3 signing -clear all autonsec3.example. > /dev/null 2>&1 343$RNDCCMD 10.53.0.3 signing -nsec3param 1 1 10 beef autonsec3.example. > /dev/null 2>&1 344for i in 0 1 2 3 4 5 6 7 8 9; do 345 ret=0 346 $RNDCCMD 10.53.0.3 signing -list autonsec3.example. > signing.out.test$n 2>&1 347 grep "Pending NSEC3 chain 1 1 10 BEEF" signing.out.test$n > /dev/null || ret=1 348 num=$(grep "Pending " signing.out.test$n | wc -l) 349 [ $num -eq 1 ] || ret=1 350 [ $ret -eq 0 ] && break 351 echo_i "waiting ... ($i)" 352 sleep 2 353done 354n=$((n + 1)) 355if [ $ret != 0 ]; then echo_i "failed"; fi 356status=$((status + ret)) 357 358echo_i "signing preset nsec3 zone" 359zsk=$(cat autozsk.key) 360ksk=$(cat autoksk.key) 361$SETTIME -K ns3 -P now -A now $zsk > settime.out.test$n.zsk || ret=1 362$SETTIME -K ns3 -P now -A now $ksk > settime.out.test$n.ksk || ret=1 363($RNDCCMD 10.53.0.3 loadkeys autonsec3.example. 2>&1 | sed 's/^/ns3 /' | cat_i) || ret=1 364 365echo_i "waiting for changes to take effect" 366sleep 3 367 368echo_i "converting zone from nsec3 to nsec" 369$NSUPDATE > /dev/null 2>&1 << END || status=1 370server 10.53.0.3 ${PORT} 371zone nsec3-to-nsec.example. 372update delete nsec3-to-nsec.example. NSEC3PARAM 373send 374END 375 376echo_i "waiting for change to take effect" 377sleep 3 378 379missing=$(keyfile_to_key_id "$(cat noksk-ksk.key)") 380echo_i "checking that expired RRSIGs from missing KSK $missing are not deleted ($n)" 381ret=0 382$JOURNALPRINT ns3/noksk.example.db.jnl | \ 383 awk '{if ($1 == "del" && $5 == "RRSIG" && $12 == id) {error=1}} END {exit error}' id=$missing || ret=1 384n=$((n + 1)) 385if [ $ret != 0 ]; then echo_i "failed"; fi 386status=$((status + ret)) 387 388missing=$(keyfile_to_key_id "$(cat nozsk-zsk.key)") 389ksk=$(keyfile_to_key_id "$(cat nozsk-ksk.key)") 390echo_i "checking that expired RRSIGs from missing ZSK $missing are replaced ($n)" 391ret=0 392$JOURNALPRINT ns3/nozsk.example.db.jnl | \ 393 awk '{if ($1 == "del" && $5 == "RRSIG" && $12 == id) {ok=1}} END {exit ok?0:1}' id=$missing || ret=1 394$JOURNALPRINT ns3/nozsk.example.db.jnl | \ 395 awk '{if ($1 == "add" && $5 == "RRSIG" && $12 == id) {ok=1}} END {exit ok?0:1}' id=$ksk || ret=1 396n=$((n + 1)) 397if [ $ret != 0 ]; then echo_i "failed"; fi 398status=$((status + ret)) 399 400inactive=$(keyfile_to_key_id "$(cat inaczsk-zsk.key)") 401ksk=$(keyfile_to_key_id "$(cat inaczsk-ksk.key)") 402echo_i "checking that expired RRSIGs from inactive ZSK $inactive are replaced ($n)" 403ret=0 404$JOURNALPRINT ns3/inaczsk.example.db.jnl | \ 405 awk '{if ($1 == "del" && $5 == "RRSIG" && $12 == id) {ok=1}} END {exit ok?0:1}' id=$inactive || ret=1 406$JOURNALPRINT ns3/inaczsk.example.db.jnl | \ 407 awk '{if ($1 == "add" && $5 == "RRSIG" && $12 == id) {ok=1}} END {exit ok?0:1}' id=$ksk || ret=1 408n=$((n + 1)) 409if [ $ret != 0 ]; then echo_i "failed"; fi 410status=$((status + ret)) 411 412echo_i "checking that replaced RRSIGs are not logged (missing ZSK private key) ($n)" 413ret=0 414loglines=$(grep "Key nozsk.example/$DEFAULT_ALGORITHM/$missing .* retaining signatures" ns3/named.run | wc -l) 415[ "$loglines" -eq 0 ] || ret=1 416n=$((n + 1)) 417if [ $ret != 0 ]; then echo_i "failed"; fi 418status=$((status + ret)) 419 420echo_i "checking that replaced RRSIGs are not logged (inactive ZSK private key) ($n)" 421ret=0 422loglines=$(grep "Key inaczsk.example/$DEFAULT_ALGORITHM/$inactive .* retaining signatures" ns3/named.run | wc -l) 423[ "$loglines" -eq 0 ] || ret=1 424n=$((n + 1)) 425if [ $ret != 0 ]; then echo_i "failed"; fi 426status=$((status + ret)) 427 428# Send rndc sync command to ns1, ns2 and ns3, to force the dynamically 429# signed zones to be dumped to their zone files 430echo_i "dumping zone files" 431($RNDCCMD 10.53.0.1 sync 2>&1 | sed 's/^/ns1 /' | cat_i) || ret=1 432($RNDCCMD 10.53.0.2 sync 2>&1 | sed 's/^/ns2 /' | cat_i) || ret=1 433($RNDCCMD 10.53.0.3 sync 2>&1 | sed 's/^/ns3 /' | cat_i) || ret=1 434 435now="$(TZ=UTC date +%Y%m%d%H%M%S)" 436check_expiry() ( 437 $DIG $DIGOPTS AXFR oldsigs.example @10.53.0.3 > dig.out.test$n 438 nearest_expiration="$(awk '$4 == "RRSIG" { print $9 }' < dig.out.test$n | sort -n | head -1)" 439 if [ "$nearest_expiration" -le "$now" ]; then 440 echo_i "failed: $nearest_expiration <= $now" 441 return 1 442 fi 443) 444 445echo_i "checking expired signatures were updated ($n)" 446retry 10 check_expiry || ret=1 447$DIG $DIGOPTS +noauth a.oldsigs.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 448$DIG $DIGOPTS +noauth a.oldsigs.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 449digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 450grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 451n=$((n + 1)) 452if [ $ret != 0 ]; then echo_i "failed"; fi 453status=$((status + ret)) 454 455# Check jitter distribution. 456echo_i "checking expired signatures were jittered correctly ($n)" 457ret=0 458$DIG $DIGOPTS axfr oldsigs.example @10.53.0.3 > dig.out.ns3.test$n || ret=1 459checkjitter dig.out.ns3.test$n || ret=1 460n=$((n + 1)) 461if [ $ret != 0 ]; then echo_i "failed"; fi 462status=$((status + ret)) 463 464echo_i "checking NSEC->NSEC3 conversion succeeded ($n)" 465ret=0 466$DIG $DIGOPTS nsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.ok.test$n || ret=1 467grep "status: NOERROR" dig.out.ns3.ok.test$n > /dev/null || ret=1 468$DIG $DIGOPTS +noauth q.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 469$DIG $DIGOPTS +noauth q.nsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 470digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 471grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 472grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 473n=$((n + 1)) 474if [ $ret != 0 ]; then echo_i "failed"; fi 475status=$((status + ret)) 476 477echo_i "checking direct NSEC3 autosigning succeeded ($n)" 478ret=0 479$DIG $DIGOPTS +noall +answer autonsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.ok.test$n || ret=1 480[ -s dig.out.ns3.ok.test$n ] || ret=1 481grep "NSEC3PARAM" dig.out.ns3.ok.test$n > /dev/null || ret=1 482$DIG $DIGOPTS +noauth q.autonsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 483$DIG $DIGOPTS +noauth q.autonsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 484digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 485grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 486grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 487n=$((n + 1)) 488if [ $ret != 0 ]; then echo_i "failed"; fi 489status=$((status + ret)) 490 491echo_i "checking NSEC->NSEC3 conversion failed with NSEC-only key ($n)" 492ret=0 493if $SHELL ../testcrypto.sh -q RSASHA1 494then 495 grep "failed: REFUSED" nsupdate.out > /dev/null || ret=1 496else 497 echo_i "skip: RSASHA1 not supported" 498fi 499n=$((n + 1)) 500if [ $ret != 0 ]; then echo_i "failed"; fi 501status=$((status + ret)) 502 503echo_i "checking NSEC3->NSEC conversion succeeded ($n)" 504ret=0 505# this command should result in an empty file: 506$DIG $DIGOPTS +noall +answer nsec3-to-nsec.example. nsec3param @10.53.0.3 > dig.out.ns3.nx.test$n || ret=1 507grep "NSEC3PARAM" dig.out.ns3.nx.test$n > /dev/null && ret=1 508$DIG $DIGOPTS +noauth q.nsec3-to-nsec.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 509$DIG $DIGOPTS +noauth q.nsec3-to-nsec.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 510digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 511grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 512grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 513n=$((n + 1)) 514if [ $ret != 0 ]; then echo_i "failed"; fi 515status=$((status + ret)) 516 517echo_i "checking NSEC3->NSEC conversion with 'rndc signing -nsec3param none' ($n)" 518ret=0 519$RNDCCMD 10.53.0.3 signing -nsec3param none autonsec3.example. > /dev/null 2>&1 520# this command should result in an empty file: 521no_nsec3param() ( 522 $DIG $DIGOPTS +noall +answer autonsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.nx.test$n || return 1 523 grep "NSEC3PARAM" dig.out.ns3.nx.test$n > /dev/null && return 1 524 return 0 525) 526retry_quiet 10 no_nsec3param || ret=1 527$DIG $DIGOPTS +noauth q.autonsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 528$DIG $DIGOPTS +noauth q.autonsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 529digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 530grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 531grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 532n=$((n + 1)) 533if [ $ret != 0 ]; then echo_i "failed"; fi 534status=$((status + ret)) 535 536echo_i "checking TTLs of imported DNSKEYs (no default) ($n)" 537ret=0 538$DIG $DIGOPTS +tcp +noall +answer dnskey ttl1.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 539[ -s dig.out.ns3.test$n ] || ret=1 540(awk 'BEGIN {r=0} $2 != 300 {r=1; print "found TTL " $2} END {exit r}' dig.out.ns3.test$n | cat_i) || ret=1 541n=$((n + 1)) 542if [ $ret != 0 ]; then echo_i "failed"; fi 543status=$((status + ret)) 544 545echo_i "checking TTLs of imported DNSKEYs (with default) ($n)" 546ret=0 547$DIG $DIGOPTS +tcp +noall +answer dnskey ttl2.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 548[ -s dig.out.ns3.test$n ] || ret=1 549(awk 'BEGIN {r=0} $2 != 60 {r=1; print "found TTL " $2} END {exit r}' dig.out.ns3.test$n | cat_i) || ret=1 550n=$((n + 1)) 551if [ $ret != 0 ]; then echo_i "failed"; fi 552status=$((status + ret)) 553 554echo_i "checking TTLs of imported DNSKEYs (mismatched) ($n)" 555ret=0 556$DIG $DIGOPTS +tcp +noall +answer dnskey ttl3.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 557[ -s dig.out.ns3.test$n ] || ret=1 558(awk 'BEGIN {r=0} $2 != 30 {r=1; print "found TTL " $2} END {exit r}' dig.out.ns3.test$n | cat_i) || ret=1 559n=$((n + 1)) 560if [ $ret != 0 ]; then echo_i "failed"; fi 561status=$((status + ret)) 562 563echo_i "checking TTLs of imported DNSKEYs (existing RRset) ($n)" 564ret=0 565$DIG $DIGOPTS +tcp +noall +answer dnskey ttl4.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 566[ -s dig.out.ns3.test$n ] || ret=1 567(awk 'BEGIN {r=0} $2 != 30 {r=1; print "found TTL " $2} END {exit r}' dig.out.ns3.test$n | cat_i) || ret=1 568n=$((n + 1)) 569if [ $ret != 0 ]; then echo_i "failed"; fi 570status=$((status + ret)) 571 572echo_i "checking positive validation NSEC ($n)" 573ret=0 574$DIG $DIGOPTS +noauth a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 575$DIG $DIGOPTS +noauth a.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 576digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 577grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 578n=$((n + 1)) 579if [ $ret != 0 ]; then echo_i "failed"; fi 580status=$((status + ret)) 581 582echo_i "checking positive validation NSEC3 ($n)" 583ret=0 584$DIG $DIGOPTS +noauth a.nsec3.example. \ 585 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 586$DIG $DIGOPTS +noauth a.nsec3.example. \ 587 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 588digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 589grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 590n=$((n + 1)) 591if [ $ret != 0 ]; then echo_i "failed"; fi 592status=$((status + ret)) 593 594echo_i "checking positive validation OPTOUT ($n)" 595ret=0 596$DIG $DIGOPTS +noauth a.optout.example. \ 597 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 598$DIG $DIGOPTS +noauth a.optout.example. \ 599 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 600digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 601grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 602n=$((n + 1)) 603if [ $ret != 0 ]; then echo_i "failed"; fi 604status=$((status + ret)) 605 606echo_i "checking negative validation NXDOMAIN NSEC ($n)" 607ret=0 608$DIG $DIGOPTS +noauth q.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 609$DIG $DIGOPTS +noauth q.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 610digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 611grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 612grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 613n=$((n + 1)) 614if [ $ret != 0 ]; then echo_i "failed"; fi 615status=$((status + ret)) 616 617echo_i "checking negative validation NXDOMAIN NSEC3 ($n)" 618ret=0 619$DIG $DIGOPTS +noauth q.nsec3.example. \ 620 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 621$DIG $DIGOPTS +noauth q.nsec3.example. \ 622 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 623digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 624grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 625grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 626n=$((n + 1)) 627if [ $ret != 0 ]; then echo_i "failed"; fi 628status=$((status + ret)) 629 630echo_i "checking negative validation NXDOMAIN OPTOUT ($n)" 631ret=0 632$DIG $DIGOPTS +noauth q.optout.example. \ 633 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 634$DIG $DIGOPTS +noauth q.optout.example. \ 635 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 636digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 637grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 638# Note - this is looking for failure, hence the && 639grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 640n=$((n + 1)) 641if [ $ret != 0 ]; then echo_i "failed"; fi 642status=$((status + ret)) 643 644echo_i "checking negative validation NODATA NSEC ($n)" 645ret=0 646$DIG $DIGOPTS +noauth a.example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1 647$DIG $DIGOPTS +noauth a.example. @10.53.0.4 txt > dig.out.ns4.test$n || ret=1 648digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 649grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 650grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 651grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1 652n=$((n + 1)) 653if [ $ret != 0 ]; then echo_i "failed"; fi 654status=$((status + ret)) 655 656echo_i "checking negative validation NODATA NSEC3 ($n)" 657ret=0 658$DIG $DIGOPTS +noauth a.nsec3.example. \ 659 @10.53.0.3 txt > dig.out.ns3.test$n || ret=1 660$DIG $DIGOPTS +noauth a.nsec3.example. \ 661 @10.53.0.4 txt > dig.out.ns4.test$n || ret=1 662digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 663grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 664grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 665grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1 666n=$((n + 1)) 667if [ $ret != 0 ]; then echo_i "failed"; fi 668status=$((status + ret)) 669 670echo_i "checking negative validation NODATA OPTOUT ($n)" 671ret=0 672$DIG $DIGOPTS +noauth a.optout.example. \ 673 @10.53.0.3 txt > dig.out.ns3.test$n || ret=1 674$DIG $DIGOPTS +noauth a.optout.example. \ 675 @10.53.0.4 txt > dig.out.ns4.test$n || ret=1 676digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 677grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 678grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 679grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1 680n=$((n + 1)) 681if [ $ret != 0 ]; then echo_i "failed"; fi 682status=$((status + ret)) 683 684# Check the insecure.example domain 685 686echo_i "checking 1-server insecurity proof NSEC ($n)" 687ret=0 688$DIG $DIGOPTS +noauth a.insecure.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 689$DIG $DIGOPTS +noauth a.insecure.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 690digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 691grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 692# Note - this is looking for failure, hence the && 693grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 694n=$((n + 1)) 695if [ $ret != 0 ]; then echo_i "failed"; fi 696status=$((status + ret)) 697 698echo_i "checking 1-server negative insecurity proof NSEC ($n)" 699ret=0 700$DIG $DIGOPTS q.insecure.example. a @10.53.0.3 \ 701 > dig.out.ns3.test$n || ret=1 702$DIG $DIGOPTS q.insecure.example. a @10.53.0.4 \ 703 > dig.out.ns4.test$n || ret=1 704digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 705grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 706# Note - this is looking for failure, hence the && 707grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 708n=$((n + 1)) 709if [ $ret != 0 ]; then echo_i "failed"; fi 710status=$((status + ret)) 711 712# Check the secure.example domain 713 714echo_i "checking multi-stage positive validation NSEC/NSEC ($n)" 715ret=0 716$DIG $DIGOPTS +noauth a.secure.example. \ 717 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 718$DIG $DIGOPTS +noauth a.secure.example. \ 719 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 720digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 721grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 722grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 723n=$((n + 1)) 724if [ $ret != 0 ]; then echo_i "failed"; fi 725status=$((status + ret)) 726 727echo_i "checking multi-stage positive validation NSEC/NSEC3 ($n)" 728ret=0 729$DIG $DIGOPTS +noauth a.nsec3.example. \ 730 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 731$DIG $DIGOPTS +noauth a.nsec3.example. \ 732 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 733digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 734grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 735grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 736n=$((n + 1)) 737if [ $ret != 0 ]; then echo_i "failed"; fi 738status=$((status + ret)) 739 740echo_i "checking multi-stage positive validation NSEC/OPTOUT ($n)" 741ret=0 742$DIG $DIGOPTS +noauth a.optout.example. \ 743 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 744$DIG $DIGOPTS +noauth a.optout.example. \ 745 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 746digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 747grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 748grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 749n=$((n + 1)) 750if [ $ret != 0 ]; then echo_i "failed"; fi 751status=$((status + ret)) 752 753echo_i "checking multi-stage positive validation NSEC3/NSEC ($n)" 754ret=0 755$DIG $DIGOPTS +noauth a.secure.nsec3.example. \ 756 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 757$DIG $DIGOPTS +noauth a.secure.nsec3.example. \ 758 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 759digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 760grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 761grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 762n=$((n + 1)) 763if [ $ret != 0 ]; then echo_i "failed"; fi 764status=$((status + ret)) 765 766echo_i "checking multi-stage positive validation NSEC3/NSEC3 ($n)" 767ret=0 768$DIG $DIGOPTS +noauth a.nsec3.nsec3.example. \ 769 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 770$DIG $DIGOPTS +noauth a.nsec3.nsec3.example. \ 771 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 772digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 773grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 774grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 775n=$((n + 1)) 776if [ $ret != 0 ]; then echo_i "failed"; fi 777status=$((status + ret)) 778 779echo_i "checking multi-stage positive validation NSEC3/OPTOUT ($n)" 780ret=0 781$DIG $DIGOPTS +noauth a.optout.nsec3.example. \ 782 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 783$DIG $DIGOPTS +noauth a.optout.nsec3.example. \ 784 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 785digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 786grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 787grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 788n=$((n + 1)) 789if [ $ret != 0 ]; then echo_i "failed"; fi 790status=$((status + ret)) 791 792echo_i "checking multi-stage positive validation OPTOUT/NSEC ($n)" 793ret=0 794$DIG $DIGOPTS +noauth a.secure.optout.example. \ 795 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 796$DIG $DIGOPTS +noauth a.secure.optout.example. \ 797 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 798digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 799grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 800grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 801n=$((n + 1)) 802if [ $ret != 0 ]; then echo_i "failed"; fi 803status=$((status + ret)) 804 805echo_i "checking multi-stage positive validation OPTOUT/NSEC3 ($n)" 806ret=0 807$DIG $DIGOPTS +noauth a.nsec3.optout.example. \ 808 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 809$DIG $DIGOPTS +noauth a.nsec3.optout.example. \ 810 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 811digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 812grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 813grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 814n=$((n + 1)) 815if [ $ret != 0 ]; then echo_i "failed"; fi 816status=$((status + ret)) 817 818echo_i "checking multi-stage positive validation OPTOUT/OPTOUT ($n)" 819ret=0 820$DIG $DIGOPTS +noauth a.optout.optout.example. \ 821 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 822$DIG $DIGOPTS +noauth a.optout.optout.example. \ 823 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 824digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 825grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 826grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 827n=$((n + 1)) 828if [ $ret != 0 ]; then echo_i "failed"; fi 829status=$((status + ret)) 830 831echo_i "checking empty NODATA OPTOUT ($n)" 832ret=0 833$DIG $DIGOPTS +noauth empty.optout.example. \ 834 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 835$DIG $DIGOPTS +noauth empty.optout.example. \ 836 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 837digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 838grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 839#grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 840n=$((n + 1)) 841if [ $ret != 0 ]; then echo_i "failed"; fi 842status=$((status + ret)) 843 844# Check the insecure.secure.example domain (insecurity proof) 845 846echo_i "checking 2-server insecurity proof ($n)" 847ret=0 848$DIG $DIGOPTS +noauth a.insecure.secure.example. @10.53.0.2 a \ 849 > dig.out.ns2.test$n || ret=1 850$DIG $DIGOPTS +noauth a.insecure.secure.example. @10.53.0.4 a \ 851 > dig.out.ns4.test$n || ret=1 852digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 853grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 854# Note - this is looking for failure, hence the && 855grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 856n=$((n + 1)) 857if [ $ret != 0 ]; then echo_i "failed"; fi 858status=$((status + ret)) 859 860# Check a negative response in insecure.secure.example 861 862echo_i "checking 2-server insecurity proof with a negative answer ($n)" 863ret=0 864$DIG $DIGOPTS q.insecure.secure.example. @10.53.0.2 a > dig.out.ns2.test$n \ 865 || ret=1 866$DIG $DIGOPTS q.insecure.secure.example. @10.53.0.4 a > dig.out.ns4.test$n \ 867 || ret=1 868digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 869grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 870# Note - this is looking for failure, hence the && 871grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 872n=$((n + 1)) 873if [ $ret != 0 ]; then echo_i "failed"; fi 874status=$((status + ret)) 875 876echo_i "checking security root query ($n)" 877ret=0 878$DIG $DIGOPTS . @10.53.0.4 key > dig.out.ns4.test$n || ret=1 879grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 880grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 881n=$((n + 1)) 882if [ $ret != 0 ]; then echo_i "failed"; fi 883status=$((status + ret)) 884 885echo_i "checking positive validation RSASHA256 NSEC ($n)" 886ret=0 887$DIG $DIGOPTS +noauth a.rsasha256.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 888$DIG $DIGOPTS +noauth a.rsasha256.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 889digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 890grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 891n=$((n + 1)) 892if [ $ret != 0 ]; then echo_i "failed"; fi 893status=$((status + ret)) 894 895echo_i "checking positive validation RSASHA512 NSEC ($n)" 896ret=0 897$DIG $DIGOPTS +noauth a.rsasha512.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 898$DIG $DIGOPTS +noauth a.rsasha512.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 899digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 900grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 901n=$((n + 1)) 902if [ $ret != 0 ]; then echo_i "failed"; fi 903status=$((status + ret)) 904 905echo_i "checking that positive validation in a privately secure zone works ($n)" 906ret=0 907$DIG $DIGOPTS +noauth a.private.secure.example. a @10.53.0.2 \ 908 > dig.out.ns2.test$n || ret=1 909$DIG $DIGOPTS +noauth a.private.secure.example. a @10.53.0.4 \ 910 > dig.out.ns4.test$n || ret=1 911digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 912grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 913grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 914n=$((n + 1)) 915if [ $ret != 0 ]; then echo_i "failed"; fi 916status=$((status + ret)) 917 918echo_i "checking that negative validation in a privately secure zone works ($n)" 919ret=0 920$DIG $DIGOPTS +noauth q.private.secure.example. a @10.53.0.2 \ 921 > dig.out.ns2.test$n || ret=1 922$DIG $DIGOPTS +noauth q.private.secure.example. a @10.53.0.4 \ 923 > dig.out.ns4.test$n || ret=1 924digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 925grep "NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 926# Note - this is looking for failure, hence the && 927grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 928n=$((n + 1)) 929if [ $ret != 0 ]; then echo_i "failed"; fi 930status=$((status + ret)) 931 932echo_i "checking privately secure to nxdomain works ($n)" 933ret=0 934$DIG $DIGOPTS +noauth private2secure-nxdomain.private.secure.example. SOA @10.53.0.4 > dig.out.ns4.test$n || ret=1 935grep "NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 936grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 937n=$((n + 1)) 938if [ $ret != 0 ]; then echo_i "failed"; fi 939status=$((status + ret)) 940 941# Try validating with a revoked trusted key. 942# This should fail. 943 944echo_i "checking that validation returns insecure due to revoked trusted key ($n)" 945ret=0 946$DIG $DIGOPTS example. soa @10.53.0.5 > dig.out.ns5.test$n || ret=1 947grep "flags:.*; QUERY" dig.out.ns5.test$n > /dev/null || ret=1 948grep "flags:.* ad.*; QUERY" dig.out.ns5.test$n > /dev/null && ret=1 949n=$((n + 1)) 950if [ $ret != 0 ]; then echo_i "failed"; fi 951status=$((status + ret)) 952 953echo_i "checking that revoked key is present ($n)" 954ret=0 955id=$(cat rev.key) 956$DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 957grep '; key id = '"$id"'$' dig.out.ns1.test$n > /dev/null || ret=1 958n=$((n + 1)) 959if [ $ret != 0 ]; then echo_i "failed"; fi 960status=$((status + ret)) 961 962echo_i "checking that revoked key self-signs ($n)" 963ret=0 964id=$(cat rev.key) 965$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 966grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null || ret=1 967n=$((n + 1)) 968if [ $ret != 0 ]; then echo_i "failed"; fi 969status=$((status + ret)) 970 971echo_i "checking for unpublished key ($n)" 972ret=0 973id=$(keyfile_to_key_id "$(cat unpub.key)") 974$DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 975grep '; key id = '"$id"'$' dig.out.ns1.test$n > /dev/null && ret=1 976n=$((n + 1)) 977if [ $ret != 0 ]; then echo_i "failed"; fi 978status=$((status + ret)) 979 980echo_i "checking for activated but unpublished key ($n)" 981ret=0 982id=$(keyfile_to_key_id "$(cat activate-now-publish-1day.key)") 983$DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 984grep '; key id = '"$id"'$' dig.out.ns1.test$n > /dev/null && ret=1 985n=$((n + 1)) 986if [ $ret != 0 ]; then echo_i "failed"; fi 987status=$((status + ret)) 988 989echo_i "checking that standby key does not sign records ($n)" 990ret=0 991id=$(keyfile_to_key_id "$(cat standby.key)") 992$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 993grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null && ret=1 994n=$((n + 1)) 995if [ $ret != 0 ]; then echo_i "failed"; fi 996status=$((status + ret)) 997 998echo_i "checking that deactivated key does not sign records ($n)" 999ret=0 1000id=$(keyfile_to_key_id "$(cat inact.key)") 1001$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 1002grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null && ret=1 1003n=$((n + 1)) 1004if [ $ret != 0 ]; then echo_i "failed"; fi 1005status=$((status + ret)) 1006 1007echo_i "checking insertion of public-only key ($n)" 1008ret=0 1009id=$(keyfile_to_key_id "$(cat nopriv.key)") 1010file="ns1/$(cat nopriv.key).key" 1011keydata=$(grep DNSKEY $file) 1012$NSUPDATE > /dev/null 2>&1 <<END || status=1 1013server 10.53.0.1 ${PORT} 1014zone . 1015ttl 3600 1016update add $keydata 1017send 1018END 1019sleep 1 1020$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 1021grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null && ret=1 1022n=$((n + 1)) 1023if [ $ret != 0 ]; then echo_i "failed"; fi 1024status=$((status + ret)) 1025 1026echo_i "checking key deletion ($n)" 1027ret=0 1028id=$(keyfile_to_key_id "$(cat del.key)") 1029$DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 1030grep '; key id = '"$id"'$' dig.out.ns1.test$n > /dev/null && ret=1 1031n=$((n + 1)) 1032if [ $ret != 0 ]; then echo_i "failed"; fi 1033status=$((status + ret)) 1034 1035echo_i "checking secure-to-insecure transition, nsupdate ($n)" 1036ret=0 1037$NSUPDATE > /dev/null 2>&1 <<END || status=1 1038server 10.53.0.3 ${PORT} 1039zone secure-to-insecure.example 1040update delete secure-to-insecure.example dnskey 1041send 1042END 1043for i in 0 1 2 3 4 5 6 7 8 9; do 1044 ret=0 1045 $DIG $DIGOPTS axfr secure-to-insecure.example @10.53.0.3 > dig.out.ns3.test$n || ret=1 1046 grep -E '(RRSIG|DNSKEY|NSEC)' dig.out.ns3.test$n > /dev/null && ret=1 1047 [ $ret -eq 0 ] && break 1048 echo_i "waiting ... ($i)" 1049 sleep 2 1050done 1051n=$((n + 1)) 1052if [ $ret != 0 ]; then echo_i "failed"; fi 1053status=$((status + ret)) 1054 1055echo_i "checking secure-to-insecure transition, scheduled ($n)" 1056ret=0 1057file="ns3/$(cat del1.key).key" 1058$SETTIME -I now -D now $file > settime.out.test$n.1 || ret=1 1059file="ns3/$(cat del2.key).key" 1060$SETTIME -I now -D now $file > settime.out.test$n.2 || ret=1 1061($RNDCCMD 10.53.0.3 sign secure-to-insecure2.example. 2>&1 | sed 's/^/ns3 /' | cat_i) || ret=1 1062for i in 0 1 2 3 4 5 6 7 8 9; do 1063 ret=0 1064 $DIG $DIGOPTS axfr secure-to-insecure2.example @10.53.0.3 > dig.out.ns3.test$n || ret=1 1065 grep -E '(RRSIG|DNSKEY|NSEC3)' dig.out.ns3.test$n > /dev/null && ret=1 1066 [ $ret -eq 0 ] && break 1067 echo_i "waiting ... ($i)" 1068 sleep 2 1069done 1070n=$((n + 1)) 1071if [ $ret != 0 ]; then echo_i "failed"; fi 1072status=$((status + ret)) 1073 1074echo_i "checking jitter in a newly signed NSEC3 zone ($n)" 1075ret=0 1076# Use DNS UPDATE to add an NSEC3PARAM record into the zone. 1077$NSUPDATE > nsupdate.out.test$n 2>&1 <<END || ret=1 1078server 10.53.0.3 ${PORT} 1079zone jitter.nsec3.example. 1080update add jitter.nsec3.example. 3600 NSEC3PARAM 1 0 10 BEEF 1081send 1082END 1083[ $ret != 0 ] && echo_i "error: dynamic update add NSEC3PARAM failed" 1084# Create DNSSEC keys in the zone directory. 1085$KEYGEN -a $DEFAULT_ALGORITHM -3 -q -K ns3 jitter.nsec3.example > /dev/null 1086# Trigger zone signing. 1087($RNDCCMD 10.53.0.3 sign jitter.nsec3.example. 2>&1 | sed 's/^/ns3 /' | cat_i) || ret=1 1088# Wait until zone has been signed. 1089check_if_nsec3param_exists() { 1090 $DIG $DIGOPTS NSEC3PARAM jitter.nsec3.example @10.53.0.3 > dig.out.ns3.1.test$n || return 1 1091 grep -q "^jitter\.nsec3\.example\..*NSEC3PARAM" dig.out.ns3.1.test$n || return 1 1092} 1093retry_quiet 40 check_if_nsec3param_exists || { 1094 echo_i "error: NSEC3PARAM not present yet" 1095 ret=1 1096} 1097$DIG $DIGOPTS AXFR jitter.nsec3.example @10.53.0.3 > dig.out.ns3.2.test$n || ret=1 1098# Check jitter distribution. 1099checkjitter dig.out.ns3.2.test$n || ret=1 1100n=$((n + 1)) 1101if [ $ret != 0 ]; then echo_i "failed"; fi 1102status=$((status + ret)) 1103 1104echo_i "checking that serial number and RRSIGs are both updated (rt21045) ($n)" 1105ret=0 1106oldserial=$($DIG $DIGOPTS +short soa prepub.example @10.53.0.3 | awk '$0 !~ /SOA/ {print $3}') 1107oldinception=$($DIG $DIGOPTS +short soa prepub.example @10.53.0.3 | awk '/SOA/ {print $6}' | sort -u) 1108 1109$KEYGEN -a $DEFAULT_ALGORITHM -3 -q -K ns3 -P 0 -A +6d -I +38d -D +45d prepub.example > /dev/null 1110 1111($RNDCCMD 10.53.0.3 sign prepub.example 2>&1 | sed 's/^/ns1 /' | cat_i) || ret=1 1112newserial=$oldserial 1113try=0 1114while [ $oldserial -eq $newserial -a $try -lt 42 ] 1115do 1116 newserial=$($DIG $DIGOPTS +short soa prepub.example @10.53.0.3 | 1117 awk '$0 !~ /SOA/ {print $3}') 1118 sleep 1 1119 try=$((try + 1)) 1120done 1121newinception=$($DIG $DIGOPTS +short soa prepub.example @10.53.0.3 | awk '/SOA/ {print $6}' | sort -u) 1122#echo "$oldserial : $newserial" 1123#echo "$oldinception : $newinception" 1124 1125[ "$oldserial" = "$newserial" ] && ret=1 1126[ "$oldinception" = "$newinception" ] && ret=1 1127n=$((n + 1)) 1128if [ $ret != 0 ]; then echo_i "failed"; fi 1129status=$((status + ret)) 1130 1131echo_i "preparing to test key change corner cases" 1132echo_i "removing a private key file" 1133file="ns1/$(cat vanishing.key).private" 1134rm -f $file 1135 1136echo_i "preparing ZSK roll" 1137starttime=$($PERL -e 'print time(), "\n";') 1138oldfile=$(cat active.key) 1139oldid=$(keyfile_to_key_id "$(cat active.key)") 1140newfile=$(cat standby.key) 1141newid=$(keyfile_to_key_id "$(cat standby.key)") 1142$SETTIME -K ns1 -I now+2s -D now+25 $oldfile > settime.out.test$n.1 || ret=1 1143$SETTIME -K ns1 -i 0 -S $oldfile $newfile > settime.out.test$n.2 || ret=1 1144 1145# note previous zone serial number 1146oldserial=$($DIG $DIGOPTS +short soa . @10.53.0.1 | awk '{print $3}') 1147 1148($RNDCCMD 10.53.0.1 loadkeys . 2>&1 | sed 's/^/ns1 /' | cat_i) || ret=1 1149sleep 4 1150 1151echo_i "revoking key to duplicated key ID" 1152$SETTIME -R now -K ns2 Kbar.+013+59973.key > settime.out.test$n.3 || ret=1 1153 1154($RNDCCMD 10.53.0.2 loadkeys bar. 2>&1 | sed 's/^/ns2 /' | cat_i) || ret=1 1155 1156echo_i "waiting for changes to take effect" 1157sleep 5 1158 1159echo_i "checking former standby key $newid is now active ($n)" 1160ret=0 1161$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 1162grep 'RRSIG.*'" $newid "'\. ' dig.out.ns1.test$n > /dev/null || ret=1 1163n=$((n + 1)) 1164if [ $ret != 0 ]; then echo_i "failed"; fi 1165status=$((status + ret)) 1166 1167echo_i "checking former standby key has only signed incrementally ($n)" 1168ret=0 1169$DIG $DIGOPTS txt . @10.53.0.1 > dig.out.ns1.test$n || ret=1 1170grep 'RRSIG.*'" $newid "'\. ' dig.out.ns1.test$n > /dev/null && ret=1 1171grep 'RRSIG.*'" $oldid "'\. ' dig.out.ns1.test$n > /dev/null || ret=1 1172n=$((n + 1)) 1173if [ $ret != 0 ]; then echo_i "failed"; fi 1174status=$((status + ret)) 1175 1176echo_i "checking that signing records have been marked as complete ($n)" 1177ret=0 1178checkprivate . 10.53.0.1 || ret=1 1179checkprivate bar 10.53.0.2 || ret=1 1180checkprivate example 10.53.0.2 || ret=1 1181checkprivate private.secure.example 10.53.0.3 || ret=1 1182checkprivate nsec3.example 10.53.0.3 || ret=1 1183checkprivate nsec3.nsec3.example 10.53.0.3 || ret=1 1184checkprivate nsec3.optout.example 10.53.0.3 || ret=1 1185checkprivate nsec3-to-nsec.example 10.53.0.3 || ret=1 1186if $SHELL ../testcrypto.sh -q RSASHA1 1187then 1188 checkprivate nsec-only.example 10.53.0.3 || ret=1 1189fi 1190checkprivate oldsigs.example 10.53.0.3 || ret=1 1191checkprivate optout.example 10.53.0.3 || ret=1 1192checkprivate optout.nsec3.example 10.53.0.3 || ret=1 1193checkprivate optout.optout.example 10.53.0.3 || ret=1 1194checkprivate prepub.example 10.53.0.3 1 || ret=1 1195checkprivate rsasha256.example 10.53.0.3 || ret=1 1196checkprivate rsasha512.example 10.53.0.3 || ret=1 1197checkprivate secure.example 10.53.0.3 || ret=1 1198checkprivate secure.nsec3.example 10.53.0.3 || ret=1 1199checkprivate secure.optout.example 10.53.0.3 || ret=1 1200checkprivate secure-to-insecure2.example 10.53.0.3 || ret=1 1201checkprivate secure-to-insecure.example 10.53.0.3 || ret=1 1202checkprivate ttl1.example 10.53.0.3 || ret=1 1203checkprivate ttl2.example 10.53.0.3 || ret=1 1204checkprivate ttl3.example 10.53.0.3 || ret=1 1205checkprivate ttl4.example 10.53.0.3 || ret=1 1206n=$((n + 1)) 1207status=$((status + ret)) 1208 1209echo_i "forcing full sign" 1210($RNDCCMD 10.53.0.1 sign . 2>&1 | sed 's/^/ns1 /' | cat_i) || ret=1 1211 1212echo_i "waiting for change to take effect" 1213sleep 5 1214 1215echo_i "checking former standby key has now signed fully ($n)" 1216ret=0 1217$DIG $DIGOPTS txt . @10.53.0.1 > dig.out.ns1.test$n || ret=1 1218grep 'RRSIG.*'" $newid "'\. ' dig.out.ns1.test$n > /dev/null || ret=1 1219n=$((n + 1)) 1220if [ $ret != 0 ]; then echo_i "failed"; fi 1221status=$((status + ret)) 1222 1223echo_i "checking SOA serial number has been incremented ($n)" 1224ret=0 1225newserial=$($DIG $DIGOPTS +short soa . @10.53.0.1 | awk '{print $3}') 1226[ "$newserial" != "$oldserial" ] || ret=1 1227n=$((n + 1)) 1228if [ $ret != 0 ]; then echo_i "failed"; fi 1229status=$((status + ret)) 1230 1231echo_i "checking delayed key publication/activation ($n)" 1232ret=0 1233zsk=$(cat delayzsk.key) 1234ksk=$(cat delayksk.key) 1235# publication and activation times should be unset 1236$SETTIME -K ns3 -pA -pP $zsk > settime.out.test$n.zsk || ret=1 1237grep -v UNSET settime.out.test$n.zsk >/dev/null && ret=1 1238$SETTIME -K ns3 -pA -pP $ksk > settime.out.test$n.ksk || ret=1 1239grep -v UNSET settime.out.test$n.ksk >/dev/null && ret=1 1240$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 1241# DNSKEY not expected: 1242awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.test$n && ret=1 1243n=$((n + 1)) 1244if [ $ret != 0 ]; then echo_i "failed"; fi 1245status=$((status + ret)) 1246 1247echo_i "checking scheduled key publication, not activation ($n)" 1248ret=0 1249# Ensure initial zone is loaded. 1250wait_for_notifies "delay.example" "ns3" || ret=1 1251$SETTIME -K ns3 -P now+3s -A none $zsk > settime.out.test$n.zsk || ret=1 1252$SETTIME -K ns3 -P now+3s -A none $ksk > settime.out.test$n.ksk || ret=1 1253($RNDCCMD 10.53.0.3 loadkeys delay.example. 2>&1 | sed 's/^/ns2 /' | cat_i) || ret=1 1254echo_i "waiting for changes to take effect" 1255sleep 3 1256wait_for_notifies "delay.example" "ns3" || ret=1 1257 1258$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 1259# DNSKEY expected: 1260awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.test$n || ret=1 1261# RRSIG not expected: 1262awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.test$n && ret=1 1263n=$((n + 1)) 1264if [ $ret != 0 ]; then echo_i "failed"; fi 1265status=$((status + ret)) 1266 1267echo_i "checking scheduled key activation ($n)" 1268ret=0 1269$SETTIME -K ns3 -A now+3s $zsk > settime.out.test$n.zsk || ret=1 1270$SETTIME -K ns3 -A now+3s $ksk > settime.out.test$n.ksk || ret=1 1271($RNDCCMD 10.53.0.3 loadkeys delay.example. 2>&1 | sed 's/^/ns2 /' | cat_i) || ret=1 1272echo_i "waiting for changes to take effect" 1273sleep 3 1274wait_for_log 10 "add delay\.example\..*NSEC.a\.delay\.example\. NS SOA RRSIG NSEC DNSKEY" ns3/named.run 1275check_is_signed() { 1276 $DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.1.test$n || return 1 1277 # DNSKEY expected: 1278 awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.1.test$n || return 1 1279 # RRSIG expected: 1280 awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.1.test$n || return 1 1281 $DIG $DIGOPTS +noall +answer a a.delay.example. @10.53.0.3 > dig.out.ns3.2.test$n || return 1 1282 # A expected: 1283 awk 'BEGIN {r=1} $4=="A" {r=0} END {exit r}' dig.out.ns3.2.test$n || return 1 1284 # RRSIG expected: 1285 awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.2.test$n || return 1 1286 return 0 1287} 1288retry_quiet 5 check_is_signed || ret=1 1289n=$((n + 1)) 1290if [ $ret != 0 ]; then echo_i "failed"; fi 1291status=$((status + ret)) 1292 1293echo_i "checking former active key was removed ($n)" 1294# 1295# Work out how long we need to sleep. Allow 4 seconds for the records 1296# to be removed. 1297# 1298now=$($PERL -e 'print time(), "\n";') 1299sleep=$((starttime + 29 - now)) 1300case $sleep in 1301-*|0);; 1302*) echo_i "waiting for timer to have activated"; sleep $sleep;; 1303esac 1304ret=0 1305$DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 1306grep '; key id = '"$oldid"'$' dig.out.ns1.test$n > /dev/null && ret=1 1307n=$((n + 1)) 1308if [ $ret != 0 ]; then echo_i "failed"; fi 1309status=$((status + ret)) 1310 1311echo_i "checking private key file removal caused no immediate harm ($n)" 1312ret=0 1313id=$(keyfile_to_key_id "$(cat vanishing.key)") 1314$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 1315grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null || ret=1 1316n=$((n + 1)) 1317if [ $ret != 0 ]; then echo_i "failed"; fi 1318status=$((status + ret)) 1319 1320echo_i "checking revoked key with duplicate key ID ($n)" 1321ret=0 1322id=59973 1323rid=60101 1324$DIG $DIGOPTS +multi dnskey bar @10.53.0.2 > dig.out.ns2.test$n || ret=1 1325grep '; key id = '"$id"'$' dig.out.ns2.test$n > /dev/null && ret=1 1326keys=$(grep '; key id = '"$rid"'$' dig.out.ns2.test$n | wc -l) 1327test $keys -eq 2 || ret=1 1328$DIG $DIGOPTS dnskey bar @10.53.0.4 > dig.out.ns4.test$n || ret=1 1329grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 1330n=$((n + 1)) 1331if [ $ret != 0 ]; then echo_i "failed"; fi 1332status=$((status + ret)) 1333 1334echo_i "checking key event timers are always set ($n)" 1335ret=0 1336# this is a regression test for a bug in which the next key event could 1337# be scheduled for the present moment, and then never fire. check for 1338# visible evidence of this error in the logs: 1339awk '/next key event/ {if ($1 == $8 && $2 == $9) exit 1}' */named.run || ret=1 1340n=$((n + 1)) 1341if [ $ret != 0 ]; then echo_i "failed"; fi 1342status=$((status + ret)) 1343 1344# this confirms that key events are never scheduled more than 1345# 'dnssec-loadkeys-interval' minutes in the future, and that the 1346# event scheduled is within 10 seconds of expected interval. 1347check_interval () { 1348 awk '/next key event/ {print $2 ":" $9}' $1/named.run | 1349 sed -e 's/\.//g' -e 's/:0\{1,4\}/:/g' | 1350 awk -F: ' 1351 { 1352 x = ($6+ $5*60000 + $4*3600000) - ($3+ $2*60000 + $1*3600000); 1353 # abs(x) < 1000 ms treat as 'now' 1354 if (x < 1000 && x > -1000) 1355 x = 0; 1356 # convert to seconds 1357 x = x/1000; 1358 # handle end of day roll over 1359 if (x < 0) 1360 x = x + 24*3600; 1361 # handle log timestamp being a few milliseconds later 1362 if (x != int(x)) 1363 x = int(x + 1); 1364 if (int(x) > int(interval)) 1365 exit (1); 1366 } 1367 END { if (int(x) > int(interval) || int(x) < int(interval-10)) exit(1) }' interval=$2 1368 return $? 1369} 1370 1371echo_i "checking automatic key reloading interval ($n)" 1372ret=0 1373check_interval ns1 3600 || ret=1 1374check_interval ns2 1800 || ret=1 1375check_interval ns3 600 || ret=1 1376n=$((n + 1)) 1377if [ $ret != 0 ]; then echo_i "failed"; fi 1378status=$((status + ret)) 1379 1380echo_i "checking for key reloading loops ($n)" 1381ret=0 1382# every key event should schedule a successor, so these should be equal 1383rekey_calls=$(grep "reconfiguring zone keys" ns*/named.run | wc -l) 1384rekey_events=$(grep "next key event" ns*/named.run | wc -l) 1385[ "$rekey_calls" = "$rekey_events" ] || ret=1 1386n=$((n + 1)) 1387if [ $ret != 0 ]; then echo_i "failed"; fi 1388status=$((status + ret)) 1389 1390echo_i "forcing full sign with unreadable keys ($n)" 1391ret=0 1392chmod 0 ns1/K.+*+*.key ns1/K.+*+*.private || ret=1 1393($RNDCCMD 10.53.0.1 sign . 2>&1 | sed 's/^/ns1 /' | cat_i) || ret=1 1394$DIG $DIGOPTS . @10.53.0.1 dnskey > dig.out.ns1.test$n || ret=1 1395grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 1396n=$((n + 1)) 1397if [ $ret != 0 ]; then echo_i "failed"; fi 1398status=$((status + ret)) 1399 1400echo_i "test turning on auto-dnssec during reconfig ($n)" 1401ret=0 1402# first create a zone that doesn't have auto-dnssec 1403($RNDCCMD 10.53.0.3 addzone reconf.example '{ type primary; file "reconf.example.db"; };' 2>&1 | sed 's/^/ns3 /' | cat_i) || ret=1 1404rekey_calls=$(grep "zone reconf.example.*next key event" ns3/named.run | wc -l) 1405[ "$rekey_calls" -eq 0 ] || ret=1 1406# ...then we add auto-dnssec and reconfigure 1407($RNDCCMD 10.53.0.3 modzone reconf.example '{ type primary; file "reconf.example.db"; allow-update { any; }; auto-dnssec maintain; };' 2>&1 | sed 's/^/ns3 /' | cat_i) || ret=1 1408rndc_reconfig ns3 10.53.0.3 1409for i in 0 1 2 3 4 5 6 7 8 9; do 1410 lret=0 1411 rekey_calls=$(grep "zone reconf.example.*next key event" ns3/named.run | wc -l) 1412 [ "$rekey_calls" -gt 0 ] || lret=1 1413 if [ "$lret" -eq 0 ]; then break; fi 1414 echo_i "waiting ... ($i)" 1415 sleep 1 1416done 1417n=$((n + 1)) 1418if [ "$lret" != 0 ]; then ret=$lret; fi 1419if [ $ret != 0 ]; then echo_i "failed"; fi 1420status=$((status + ret)) 1421 1422echo_i "test CDS and CDNSKEY auto generation ($n)" 1423ret=0 1424$DIG $DIGOPTS @10.53.0.3 sync.example cds > dig.out.ns3.cdstest$n 1425$DIG $DIGOPTS @10.53.0.3 sync.example cdnskey > dig.out.ns3.cdnskeytest$n 1426grep -i "sync.example.*in.cds.*[1-9][0-9]* " dig.out.ns3.cdstest$n > /dev/null || ret=1 1427grep -i "sync.example.*in.cdnskey.*257 " dig.out.ns3.cdnskeytest$n > /dev/null || ret=1 1428n=$((n + 1)) 1429if [ $ret != 0 ]; then echo_i "failed"; fi 1430status=$((status + ret)) 1431 1432echo_i "test 'dnssec-dnskey-kskonly no' affects DNSKEY/CDS/CDNSKEY ($n)" 1433ret=0 1434$DIG $DIGOPTS @10.53.0.3 sync.example dnskey > dig.out.ns3.dnskeytest$n 1435$DIG $DIGOPTS @10.53.0.3 sync.example cdnskey > dig.out.ns3.cdnskeytest$n 1436$DIG $DIGOPTS @10.53.0.3 sync.example cds > dig.out.ns3.cdstest$n 1437lines=$(awk '$4 == "RRSIG" && $5 == "DNSKEY" {print}' dig.out.ns3.dnskeytest$n | wc -l) 1438test ${lines:-0} -eq 2 || ret=1 1439lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.ns3.cdnskeytest$n | wc -l) 1440test ${lines:-0} -eq 2 || ret=1 1441lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.ns3.cdstest$n | wc -l) 1442test ${lines:-0} -eq 2 || ret=1 1443n=$((n + 1)) 1444if [ $ret != 0 ]; then echo_i "failed"; fi 1445status=$((status + ret)) 1446 1447echo_i "test 'dnssec-dnskey-kskonly yes' affects DNSKEY/CDS/CDNSKEY ($n)" 1448ret=0 1449$DIG $DIGOPTS @10.53.0.3 kskonly.example dnskey > dig.out.ns3.dnskeytest$n 1450$DIG $DIGOPTS @10.53.0.3 kskonly.example cdnskey > dig.out.ns3.cdnskeytest$n 1451$DIG $DIGOPTS @10.53.0.3 kskonly.example cds > dig.out.ns3.cdstest$n 1452lines=$(awk '$4 == "RRSIG" && $5 == "DNSKEY" {print}' dig.out.ns3.dnskeytest$n | wc -l) 1453test ${lines:-0} -eq 1 || ret=1 1454lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.ns3.cdnskeytest$n | wc -l) 1455test ${lines:-0} -eq 1 || ret=1 1456lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.ns3.cdstest$n | wc -l) 1457test ${lines:-0} -eq 1 || ret=1 1458n=$((n + 1)) 1459if [ $ret != 0 ]; then echo_i "failed"; fi 1460status=$((status + ret)) 1461 1462echo_i "setting CDS and CDNSKEY deletion times and calling 'rndc loadkeys'" 1463$SETTIME -D sync now $(cat sync.key) > settime.out.test$n || ret=1 1464($RNDCCMD 10.53.0.3 loadkeys sync.example | sed 's/^/ns3 /' | cat_i) || ret=1 1465 1466echo_i "checking that the CDS and CDNSKEY are deleted ($n)" 1467ret=0 1468ensure_cds_and_cdnskey_are_deleted() { 1469 $DIG $DIGOPTS @10.53.0.3 sync.example. CDS > dig.out.ns3.cdstest$n || return 1 1470 awk '$1 == "sync.example." && $4 == "CDS" { exit 1; }' dig.out.ns3.cdstest$n || return 1 1471 $DIG $DIGOPTS @10.53.0.3 sync.example. CDNSKEY > dig.out.ns3.cdnskeytest$n || return 1 1472 awk '$1 == "sync.example." && $4 == "CDNSKEY" { exit 1; }' dig.out.ns3.cdnskeytest$n || return 1 1473} 1474retry 10 ensure_cds_and_cdnskey_are_deleted || ret=1 1475n=$((n + 1)) 1476if [ $ret != 0 ]; then echo_i "failed"; fi 1477status=$((status + ret)) 1478 1479echo_i "check that dnssec-settime -p Dsync works ($n)" 1480ret=0 1481$SETTIME -p Dsync $(cat sync.key) > settime.out.test$n || ret=1 1482grep "SYNC Delete:" settime.out.test$n >/dev/null || ret=1 1483n=$((n + 1)) 1484if [ $ret != 0 ]; then echo_i "failed"; fi 1485status=$((status + ret)) 1486 1487echo_i "check that dnssec-settime -p Psync works ($n)" 1488ret=0 1489$SETTIME -p Psync $(cat sync.key) > settime.out.test$n || ret=1 1490grep "SYNC Publish:" settime.out.test$n >/dev/null || ret=1 1491n=$((n + 1)) 1492if [ $ret != 0 ]; then echo_i "failed"; fi 1493status=$((status + ret)) 1494 1495echo_i "check that zone with inactive KSK and active ZSK is properly autosigned ($n)" 1496ret=0 1497$DIG $DIGOPTS @10.53.0.3 axfr inacksk2.example > dig.out.ns3.test$n 1498 1499zskid=$(awk '$4 == "DNSKEY" && $5 == 256 { print }' dig.out.ns3.test$n | 1500 $DSFROMKEY -A -2 -f - inacksk2.example | awk '{ print $4}' ) 1501pattern="DNSKEY ${DEFAULT_ALGORITHM_NUMBER} 2 [0-9]* [0-9]* [0-9]* ${zskid} " 1502grep "${pattern}" dig.out.ns3.test$n > /dev/null || ret=1 1503 1504kskid=$(awk '$4 == "DNSKEY" && $5 == 257 { print }' dig.out.ns3.test$n | 1505 $DSFROMKEY -2 -f - inacksk2.example | awk '{ print $4}' ) 1506pattern="DNSKEY ${DEFAULT_ALGORITHM_NUMBER} 2 [0-9]* [0-9]* [0-9]* ${kskid} " 1507grep "${pattern}" dig.out.ns3.test$n > /dev/null && ret=1 1508 1509n=$((n + 1)) 1510if [ $ret != 0 ]; then echo_i "failed"; fi 1511status=$((status + ret)) 1512 1513echo_i "check that zone with inactive ZSK and active KSK is properly autosigned ($n)" 1514ret=0 1515$DIG $DIGOPTS @10.53.0.3 axfr inaczsk2.example > dig.out.ns3.test$n 1516grep "SOA ${DEFAULT_ALGORITHM_NUMBER} 2" dig.out.ns3.test$n > /dev/null || ret=1 1517n=$((n + 1)) 1518if [ $ret != 0 ]; then echo_i "failed"; fi 1519status=$((status + ret)) 1520 1521# 1522# Check that DNSKEY is now signed with the ZSK. 1523# 1524echo_i "check that zone with active and inactive KSK and active ZSK is properly" 1525echo_ic "resigned after the active KSK is deleted - stage 2: Verify that DNSKEY" 1526echo_ic "is now signed with the ZSK. ($n)" 1527ret=0 1528 1529$DIG $DIGOPTS @10.53.0.3 axfr inacksk3.example > dig.out.ns3.test$n 1530 1531zskid=$(awk '$4 == "DNSKEY" && $5 == 256 { print }' dig.out.ns3.test$n | 1532 $DSFROMKEY -A -2 -f - inacksk3.example | awk '{ print $4}' ) 1533pattern="DNSKEY ${DEFAULT_ALGORITHM_NUMBER} 2 [0-9]* [0-9]* [0-9]* ${zskid} " 1534grep "${pattern}" dig.out.ns3.test$n > /dev/null || ret=1 1535 1536count=$(awk 'BEGIN { count = 0 } 1537 $4 == "RRSIG" && $5 == "DNSKEY" { count++ } 1538 END {print count}' dig.out.ns3.test$n) 1539test $count -eq 1 || ret=1 1540 1541count=$(awk 'BEGIN { count = 0 } 1542 $4 == "DNSKEY" { count++ } 1543 END {print count}' dig.out.ns3.test$n) 1544test $count -eq 2 || ret=1 1545 1546n=$((n + 1)) 1547if [ $ret != 0 ]; then echo_i "failed"; fi 1548status=$((status + ret)) 1549 1550# 1551# Check that zone is now signed with the KSK. 1552# 1553echo_i "check that zone with active and inactive ZSK and active KSK is properly" 1554echo_ic "resigned after the active ZSK is deleted - stage 2: Verify that zone" 1555echo_ic "is now signed with the KSK. ($n)" 1556ret=0 1557$DIG $DIGOPTS @10.53.0.3 axfr inaczsk3.example > dig.out.ns3.test$n 1558kskid=$(awk '$4 == "DNSKEY" && $5 == 257 { print }' dig.out.ns3.test$n | 1559 $DSFROMKEY -2 -f - inaczsk3.example | awk '{ print $4}' ) 1560grep "CNAME ${DEFAULT_ALGORITHM_NUMBER} 3 [0-9]* [0-9]* [0-9]* ${kskid} " dig.out.ns3.test$n > /dev/null || ret=1 1561count=$(awk 'BEGIN { count = 0 } 1562 $4 == "RRSIG" && $5 == "CNAME" { count++ } 1563 END {print count}' dig.out.ns3.test$n) 1564test $count -eq 1 || ret=1 1565count=$(awk 'BEGIN { count = 0 } 1566 $4 == "DNSKEY" { count++ } 1567 END {print count}' dig.out.ns3.test$n) 1568test $count -eq 2 || ret=1 1569n=$((n + 1)) 1570if [ $ret != 0 ]; then echo_i "failed"; fi 1571status=$((status + ret)) 1572 1573echo_i "checking for out-of-zone NSEC3 records after ZSK removal ($n)" 1574ret=0 1575# Switch the zone over to NSEC3 and wait until the transition is complete. 1576$RNDCCMD 10.53.0.3 signing -nsec3param 1 1 10 12345678 delzsk.example. > signing.out.1.test$n 2>&1 || ret=1 1577for i in 0 1 2 3 4 5 6 7 8 9; do 1578 _ret=1 1579 $DIG $DIGOPTS delzsk.example NSEC3PARAM @10.53.0.3 > dig.out.ns3.1.test$n 2>&1 || ret=1 1580 grep "NSEC3PARAM.*12345678" dig.out.ns3.1.test$n > /dev/null 2>&1 1581 if [ $? -eq 0 ]; then 1582 $RNDCCMD 10.53.0.3 signing -list delzsk.example > signing.out.2.test$n 2>&1 1583 grep "Creating NSEC3 chain " signing.out.2.test$n > /dev/null 2>&1 1584 if [ $? -ne 0 ]; then 1585 _ret=0 1586 break 1587 fi 1588 fi 1589 sleep 1 1590done 1591if [ $_ret -ne 0 ]; then 1592 echo_i "timed out waiting for NSEC3 chain creation" 1593 ret=1 1594fi 1595# Mark the inactive ZSK as pending removal. 1596file="ns3/$(cat delzsk.key).key" 1597$SETTIME -D now-1h $file > settime.out.test$n || ret=1 1598# Trigger removal of the inactive ZSK and wait until its completion. 1599($RNDCCMD 10.53.0.3 loadkeys delzsk.example 2>&1 | sed 's/^/ns3 /' | cat_i) || ret=1 1600for i in 0 1 2 3 4 5 6 7 8 9; do 1601 _ret=1 1602 $RNDCCMD 10.53.0.3 signing -list delzsk.example > signing.out.3.test$n 2>&1 1603 grep "Signing " signing.out.3.test$n > /dev/null 2>&1 1604 if [ $? -ne 0 ]; then 1605 if [ $(grep "Done signing " signing.out.3.test$n | wc -l) -eq 2 ]; then 1606 _ret=0 1607 break 1608 fi 1609 fi 1610 sleep 1 1611done 1612if [ $_ret -ne 0 ]; then 1613 echo_i "timed out waiting for key removal" 1614 ret=1 1615fi 1616# Check whether key removal caused NSEC3 records to be erroneously created for 1617# glue records due to a secure delegation already being signed by the active key 1618# (i.e. a key other than the one being removed but using the same algorithm). 1619# 1620# For reference: 1621# 1622# $ nsec3hash 12345678 1 10 ns.sub.delzsk.example. 1623# 589R358VSPJUFVAJU949JPVF74D9PTGH (salt=12345678, hash=1, iterations=10) 1624# 1625$DIG $DIGOPTS delzsk.example AXFR @10.53.0.3 > dig.out.ns3.3.test$n || ret=1 1626grep "589R358VSPJUFVAJU949JPVF74D9PTGH" dig.out.ns3.3.test$n > /dev/null 2>&1 && ret=1 1627n=$((n + 1)) 1628if [ $ret != 0 ]; then echo_i "failed"; fi 1629status=$((status + ret)) 1630 1631echo_i "check that DNAME at apex with NSEC3 is correctly signed (auto-dnssec maintain) ($n)" 1632ret=0 1633$DIG $DIGOPTS txt dname-at-apex-nsec3.example @10.53.0.3 > dig.out.ns3.test$n || ret=1 1634grep "RRSIG NSEC3 ${DEFAULT_ALGORITHM_NUMBER} 3 600" dig.out.ns3.test$n > /dev/null || ret=1 1635n=$((n + 1)) 1636if [ $ret != 0 ]; then echo_i "failed"; fi 1637status=$((status + ret)) 1638 1639echo_i "checking that DNAME is not treated as a delegation when signing ($n)" 1640ret=0 1641$DIG $DIGOPTS dname-and-txt.secure.example. DNAME @10.53.0.3 > dig.out.ns3.1.test$n || ret=1 1642grep "dname-and-txt.secure.example.*RRSIG.*DNAME" dig.out.ns3.1.test$n > /dev/null 2>&1 || ret=1 1643$DIG $DIGOPTS dname-and-txt.secure.example. TXT @10.53.0.3 > dig.out.ns3.2.test$n || ret=1 1644grep "dname-and-txt.secure.example.*RRSIG.*TXT" dig.out.ns3.2.test$n > /dev/null 2>&1 || ret=1 1645n=$((n + 1)) 1646if [ $ret != 0 ]; then echo_i "failed"; fi 1647status=$((status + ret)) 1648 1649echo_i "checking key maintenance events were logged correctly ($n)" 1650ret=0 1651pub=$(grep "DNSKEY .* is now published" ns1/named.run | wc -l) 1652[ "$pub" -eq 6 ] || ret=1 1653act=$(grep "DNSKEY .* is now active" ns1/named.run | wc -l) 1654[ "$act" -eq 5 ] || ret=1 1655rev=$(grep "DNSKEY .* is now revoked" ns1/named.run | wc -l) 1656[ "$rev" -eq 1 ] || ret=1 1657inac=$(grep "DNSKEY .* is now inactive" ns1/named.run | wc -l) 1658[ "$inac" -eq 1 ] || ret=1 1659del=$(grep "DNSKEY .* is now deleted" ns1/named.run | wc -l) 1660[ "$del" -eq 1 ] || ret=1 1661n=$((n + 1)) 1662if [ $ret != 0 ]; then echo_i "failed"; fi 1663status=$((status + ret)) 1664 1665echo_i "checking that CDS (DELETE) persists after zone sign ($n)" 1666echo_i "update add cds-delete.example. CDS 0 0 00" 1667ret=0 1668$NSUPDATE > nsupdate.out 2>&1 <<END 1669server 10.53.0.3 ${PORT} 1670zone cds-delete.example. 1671update add cds-delete.example. 3600 CDS 0 0 0 00 1672send 1673END 1674 1675_cds_delete() ( 1676 $DIG $DIGOPTS +noall +answer $1 cds @10.53.0.3 > dig.out.ns3.test$n || return 1 1677 grep "CDS.*0.*0.*0.*00" dig.out.ns3.test$n > /dev/null 2>&1 || return 1 1678 return 0 1679) 1680_cdnskey_delete_nx() { 1681 $DIG $DIGOPTS +noall +answer $1 cdnskey @10.53.0.3 > dig.out.ns3.test$n || return 1 1682 grep "CDNSKEY.*0.*3.*0.*AA==" dig.out.ns3.test$n > /dev/null 2>&1 && return 1 1683 return 0 1684} 1685 1686echo_i "query cds-delete.example. CDS" 1687retry_quiet 10 _cds_delete cds-delete.example. || ret=1 1688echo_i "query cds-delete.example. CDNSKEY" 1689retry_quiet 1 _cdnskey_delete_nx cds-delete.example. || ret=1 1690 1691echo_i "sign cds-delete.example." 1692nextpart ns3/named.run >/dev/null 1693$RNDCCMD 10.53.0.3 sign cds-delete.example > /dev/null 2>&1 || ret=1 1694wait_for_log 10 "zone cds-delete.example/IN: next key event" ns3/named.run 1695# The CDS (DELETE) record should still be here. 1696echo_i "query cds-delete.example. CDS" 1697retry_quiet 1 _cds_delete cds-delete.example. || ret=1 1698# The CDNSKEY (DELETE) record should still not be added. 1699echo_i "query cds-delete.example. CDNSKEY" 1700retry_quiet 1 _cdnskey_delete_nx cds-delete.example. || ret=1 1701 1702n=$((n + 1)) 1703if [ $ret != 0 ]; then echo_i "failed"; fi 1704status=$((status + ret)) 1705 1706echo_i "checking that CDNSKEY (DELETE) persists after zone sign ($n)" 1707echo_i "update add cdnskey-delete.example. CDNSKEY 0 3 0 AA==" 1708ret=0 1709$NSUPDATE > nsupdate.out 2>&1 <<END 1710server 10.53.0.3 ${PORT} 1711zone cdnskey-delete.example. 1712update add cdnskey-delete.example. 3600 CDNSKEY 0 3 0 AA== 1713send 1714END 1715 1716_cds_delete_nx() ( 1717 $DIG $DIGOPTS +noall +answer $1 cds @10.53.0.3 > dig.out.ns3.test$n || return 1 1718 grep "CDS.*0.*0.*0.*00" dig.out.ns3.test$n > /dev/null 2>&1 && return 1 1719 return 0 1720) 1721_cdnskey_delete() { 1722 $DIG $DIGOPTS +noall +answer $1 cdnskey @10.53.0.3 > dig.out.ns3.test$n || return 1 1723 grep "CDNSKEY.*0.*3.*0.*AA==" dig.out.ns3.test$n > /dev/null 2>&1 || return 1 1724 return 0 1725} 1726 1727echo_i "query cdnskey-delete.example. CDNSKEY" 1728retry_quiet 10 _cdnskey_delete cdnskey-delete.example. || ret=1 1729echo_i "query cdnskey-delete.example. CDS" 1730retry_quiet 1 _cds_delete_nx cdnskey-delete.example. || ret=1 1731 1732echo_i "sign cdsnskey-delete.example." 1733nextpart ns3/named.run >/dev/null 1734$RNDCCMD 10.53.0.3 sign cdnskey-delete.example > /dev/null 2>&1 || ret=1 1735wait_for_log 10 "zone cdnskey-delete.example/IN: next key event" ns3/named.run 1736# The CDNSKEY (DELETE) record should still be here. 1737echo_i "query cdnskey-delete.example. CDNSKEY" 1738retry_quiet 1 _cdnskey_delete cdnskey-delete.example. || ret=1 1739# The CDS (DELETE) record should still not be added. 1740echo_i "query cdnskey-delete.example. CDS" 1741retry_quiet 1 _cds_delete_nx cdnskey-delete.example. || ret=1 1742 1743n=$((n + 1)) 1744if [ $ret != 0 ]; then echo_i "failed"; fi 1745status=$((status + ret)) 1746 1747echo_i "check removal of ENT NSEC3 records when opt out delegations are removed ($n)" 1748ret=0 1749zone=optout-with-ent 1750hash=JTR8R6AVFULU0DQH9I6HNN2KUK5956EL 1751# check that NSEC3 for ENT is present 1752$DIG $DIGOPTS @10.53.0.2 a "ent.${zone}" > dig.out.pre.ns2.test$n 1753grep "status: NOERROR" dig.out.pre.ns2.test$n >/dev/null || ret=1 1754grep "ANSWER: 0, AUTHORITY: 4, " dig.out.pre.ns2.test$n > /dev/null || ret=1 1755grep "^${hash}.${zone}." dig.out.pre.ns2.test$n > /dev/null || ret=1 1756# remove first delegation of two delegations, NSEC3 for ENT should remain. 1757( 1758echo zone $zone 1759echo server 10.53.0.2 "$PORT" 1760echo update del sub1.ent.$zone NS 1761echo send 1762) | $NSUPDATE 1763# check that NSEC3 for ENT is still present 1764$DIG $DIGOPTS @10.53.0.2 a "ent.${zone}" > dig.out.pre.ns2.test$n 1765$DIG $DIGOPTS @10.53.0.2 a "ent.${zone}" > dig.out.mid.ns2.test$n 1766grep "status: NOERROR" dig.out.mid.ns2.test$n >/dev/null || ret=1 1767grep "ANSWER: 0, AUTHORITY: 4, " dig.out.mid.ns2.test$n > /dev/null || ret=1 1768grep "^${hash}.${zone}." dig.out.mid.ns2.test$n > /dev/null || ret=1 1769# remove second delegation of two delegations, NSEC3 for ENT should be deleted. 1770( 1771echo zone $zone 1772echo server 10.53.0.2 "$PORT" 1773echo update del sub2.ent.$zone NS 1774echo send 1775) | $NSUPDATE 1776# check that NSEC3 for ENT is gone present 1777$DIG $DIGOPTS @10.53.0.2 a "ent.${zone}" > dig.out.post.ns2.test$n 1778grep "status: NXDOMAIN" dig.out.post.ns2.test$n >/dev/null || ret=1 1779grep "ANSWER: 0, AUTHORITY: 4, " dig.out.post.ns2.test$n > /dev/null || ret=1 1780grep "^${hash}.${zone}." dig.out.post.ns2.test$n > /dev/null && ret=1 1781$DIG $DIGOPTS @10.53.0.2 axfr "${zone}" > dig.out.axfr.ns2.test$n 1782grep "^${hash}.${zone}." dig.out.axfr.ns2.test$n > /dev/null && ret=1 1783n=$((n+1)) 1784if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 1785status=$((status+ret)) 1786 1787echo_i "exit status: $status" 1788[ $status -eq 0 ] || exit 1 1789