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