1#!/bin/sh 2# 3# Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC") 4# 5# Permission to use, copy, modify, and/or distribute this software for any 6# purpose with or without fee is hereby granted, provided that the above 7# copyright notice and this permission notice appear in all copies. 8# 9# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15# PERFORMANCE OF THIS SOFTWARE. 16 17# Id 18 19SYSTEMTESTTOP=.. 20. $SYSTEMTESTTOP/conf.sh 21 22RANDFILE=random.data 23 24status=0 25n=0 26 27DIGOPTS="+tcp +noadd +nosea +nostat +nocmd +dnssec -p 5300" 28 29# convert private-type records to readable form 30showprivate () { 31 echo "-- $@ --" 32 $DIG $DIGOPTS +nodnssec +short @$2 -t type65534 $1 | cut -f3 -d' ' | 33 while read record; do 34 perl -e 'my $rdata = pack("H*", @ARGV[0]); 35 die "invalid record" unless length($rdata) == 5; 36 my ($alg, $key, $remove, $complete) = unpack("CnCC", $rdata); 37 my $action = "signing"; 38 $action = "removing" if $remove; 39 my $state = " (incomplete)"; 40 $state = " (complete)" if $complete; 41 print ("$action: alg: $alg, key: $key$state\n");' $record 42 done 43} 44 45# check that signing records are marked as complete 46checkprivate () { 47 ret=0 48 x=`showprivate "$@"` 49 echo $x | grep incomplete >&- 2>&- && ret=1 50 [ $ret = 1 ] && { 51 echo "$x" 52 echo "I:failed" 53 } 54 return $ret 55} 56 57# 58# The NSEC record at the apex of the zone and its RRSIG records are 59# added as part of the last step in signing a zone. We wait for the 60# NSEC records to appear before proceeding with a counter to prevent 61# infinite loops if there is a error. 62# 63echo "I:waiting for autosign changes to take effect" 64i=0 65while [ $i -lt 30 ] 66do 67 ret=0 68 # 69 # Wait for the root DNSKEY RRset to be fully signed. 70 # 71 $DIG $DIGOPTS . @10.53.0.1 dnskey > dig.out.ns1.test$n || ret=1 72 grep "ANSWER: 10," dig.out.ns1.test$n > /dev/null || ret=1 73 for z in . 74 do 75 $DIG $DIGOPTS $z @10.53.0.1 nsec > dig.out.ns1.test$n || ret=1 76 grep "NS SOA" dig.out.ns1.test$n > /dev/null || ret=1 77 done 78 for z in bar. example. private.secure.example. 79 do 80 $DIG $DIGOPTS $z @10.53.0.2 nsec > dig.out.ns2.test$n || ret=1 81 grep "NS SOA" dig.out.ns2.test$n > /dev/null || ret=1 82 done 83 for z in bar. example. 84 do 85 $DIG $DIGOPTS $z @10.53.0.3 nsec > dig.out.ns3.test$n || ret=1 86 grep "NS SOA" dig.out.ns3.test$n > /dev/null || ret=1 87 done 88 i=`expr $i + 1` 89 if [ $ret = 0 ]; then break; fi 90 echo "I:waiting ... ($i)" 91 sleep 2 92done 93n=`expr $n + 1` 94if [ $ret != 0 ]; then echo "I:failed"; else echo "I:done"; fi 95status=`expr $status + $ret` 96 97echo "I:checking NSEC->NSEC3 conversion prerequisites ($n)" 98ret=0 99# these commands should result in an empty file: 100$DIG $DIGOPTS +noall +answer nsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.1.test$n || ret=1 101grep "NSEC3PARAM" dig.out.ns3.1.test$n > /dev/null && ret=1 102$DIG $DIGOPTS +noall +answer autonsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.2.test$n || ret=1 103grep "NSEC3PARAM" dig.out.ns3.2.test$n > /dev/null && ret=1 104n=`expr $n + 1` 105if [ $ret != 0 ]; then echo "I:failed"; fi 106status=`expr $status + $ret` 107 108echo "I:checking NSEC3->NSEC conversion prerequisites ($n)" 109ret=0 110$DIG $DIGOPTS +noall +answer nsec3-to-nsec.example. nsec3param @10.53.0.3 > dig.out.ns3.test$n || ret=1 111grep "NSEC3PARAM" dig.out.ns3.test$n > /dev/null || ret=1 112n=`expr $n + 1` 113if [ $ret != 0 ]; then echo "I:failed"; fi 114status=`expr $status + $ret` 115 116echo "I:converting zones from nsec to nsec3" 117$NSUPDATE > /dev/null 2>&1 <<END || status=1 118server 10.53.0.3 5300 119zone nsec3.nsec3.example. 120update add nsec3.nsec3.example. 3600 NSEC3PARAM 1 0 10 BEEF 121send 122zone optout.nsec3.example. 123update add optout.nsec3.example. 3600 NSEC3PARAM 1 1 10 BEEF 124send 125zone nsec3.example. 126update add nsec3.example. 3600 NSEC3PARAM 1 0 10 BEEF 127send 128zone autonsec3.example. 129update add autonsec3.example. 3600 NSEC3PARAM 1 0 20 DEAF 130send 131zone nsec3.optout.example. 132update add nsec3.optout.example. 3600 NSEC3PARAM 1 0 10 BEEF 133send 134zone optout.optout.example. 135update add optout.optout.example. 3600 NSEC3PARAM 1 1 10 BEEF 136send 137zone optout.example. 138update add optout.example. 3600 NSEC3PARAM 1 1 10 BEEF 139send 140END 141 142# try to convert nsec.example; this should fail due to non-NSEC key 143echo "I:preset nsec3param in unsigned zone via nsupdate ($n)" 144$NSUPDATE > nsupdate.out 2>&1 <<END 145server 10.53.0.3 5300 146zone nsec.example. 147update add nsec.example. 3600 NSEC3PARAM 1 0 10 BEEF 148send 149END 150 151echo "I:checking for nsec3param in unsigned zone ($n)" 152ret=0 153$DIG $DIGOPTS +noall +answer autonsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.test$n || ret=1 154grep "NSEC3PARAM" dig.out.ns3.test$n > /dev/null && ret=1 155n=`expr $n + 1` 156if [ $ret != 0 ]; then echo "I:failed"; fi 157status=`expr $status + $ret` 158 159echo "I:checking for nsec3param signing record ($n)" 160ret=0 161$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 signing -list autonsec3.example. > signing.out.test$n 2>&1 162grep "Pending NSEC3 chain 1 0 20 DEAF" signing.out.test$n > /dev/null || ret=1 163n=`expr $n + 1` 164if [ $ret != 0 ]; then echo "I:failed"; fi 165status=`expr $status + $ret` 166 167echo "I:resetting nsec3param via rndc signing ($n)" 168ret=0 169$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 signing -clear all autonsec3.example. > /dev/null 2>&1 170$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 signing -nsec3param 1 1 10 beef autonsec3.example. > /dev/null 2>&1 171sleep 1 172$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 signing -list autonsec3.example. > signing.out.test$n 2>&1 173grep "Pending NSEC3 chain 1 1 10 BEEF" signing.out.test$n > /dev/null || ret=1 174num=`grep "Pending " signing.out.test$n | wc -l` 175[ $num -eq 1 ] || ret=1 176n=`expr $n + 1` 177if [ $ret != 0 ]; then echo "I:failed"; fi 178status=`expr $status + $ret` 179 180echo "I:signing preset nsec3 zone" 181zsk=`cat autozsk.key` 182ksk=`cat autoksk.key` 183$SETTIME -K ns3 -P now -A now $zsk > /dev/null 2>&1 184$SETTIME -K ns3 -P now -A now $ksk > /dev/null 2>&1 185$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 loadkeys autonsec3.example. 2>&1 | sed 's/^/I:ns3 /' 186 187echo "I:waiting for changes to take effect" 188sleep 3 189 190echo "I:converting zone from nsec3 to nsec" 191$NSUPDATE > /dev/null 2>&1 << END || status=1 192server 10.53.0.3 5300 193zone nsec3-to-nsec.example. 194update delete nsec3-to-nsec.example. NSEC3PARAM 195send 196END 197 198echo "I:waiting for change to take effect" 199sleep 3 200 201echo "I:checking that expired RRSIGs from missing key are not deleted ($n)" 202ret=0 203missing=`sed 's/^K.*+007+0*\([0-9]\)/\1/' < missingzsk.key` 204$JOURNALPRINT ns3/nozsk.example.db.jnl | \ 205 awk '{if ($1 == "del" && $5 == "RRSIG" && $12 == id) {exit 1}} END {exit 0}' id=$missing || ret=1 206if [ $ret != 0 ]; then echo "I:failed"; fi 207status=`expr $status + $ret` 208 209echo "I:checking that expired RRSIGs from inactive key are not deleted ($n)" 210ret=0 211inactive=`sed 's/^K.*+007+0*\([0-9]\)/\1/' < inactivezsk.key` 212$JOURNALPRINT ns3/inaczsk.example.db.jnl | \ 213 awk '{if ($1 == "del" && $5 == "RRSIG" && $12 == id) {exit 1}} END {exit 0}' id=$inactive || ret=1 214if [ $ret != 0 ]; then echo "I:failed"; fi 215status=`expr $status + $ret` 216 217echo "I:checking that non-replaceable RRSIGs are logged only once ($n)" 218ret=0 219loglines=`grep "Key nozsk.example/NSEC3RSASHA1/$missing .* retaining signatures" ns3/named.run | wc -l` 220[ "$loglines" -eq 1 ] || ret=1 221loglines=`grep "Key inaczsk.example/NSEC3RSASHA1/$missing .* retaining signatures" ns3/named.run | wc -l` 222[ "$loglines" -eq 1 ] || ret=1 223if [ $ret != 0 ]; then echo "I:failed"; fi 224status=`expr $status + $ret` 225 226echo "I:checking serial is not incremented when signatures are unchanged ($n)" 227ret=0 228newserial=`$DIG $DIGOPTS +short soa nozsk.example @10.53.0.3 | awk '$0 !~ /SOA/ {print $3}'` 229[ "$newserial" -eq 2 ] || ret=1 230newserial=`$DIG $DIGOPTS +short soa inaczsk.example @10.53.0.3 | awk '$0 !~ /SOA/ {print $3}'` 231[ "$newserial" -eq 2 ] || ret=1 232if [ $ret != 0 ]; then echo "I:failed"; fi 233status=`expr $status + $ret` 234 235# Send rndc sync command to ns1, ns2 and ns3, to force the dynamically 236# signed zones to be dumped to their zone files 237echo "I:dumping zone files" 238$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 sync 2>&1 | sed 's/^/I:ns1 /' 239$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 sync 2>&1 | sed 's/^/I:ns2 /' 240$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 sync 2>&1 | sed 's/^/I:ns3 /' 241 242echo "I:checking expired signatures were updated ($n)" 243ret=0 244$DIG $DIGOPTS +noauth a.oldsigs.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 245$DIG $DIGOPTS +noauth a.oldsigs.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 246$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 247grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 248n=`expr $n + 1` 249if [ $ret != 0 ]; then echo "I:failed"; fi 250status=`expr $status + $ret` 251 252echo "I:checking NSEC->NSEC3 conversion succeeded ($n)" 253ret=0 254$DIG $DIGOPTS nsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.ok.test$n || ret=1 255grep "status: NOERROR" dig.out.ns3.ok.test$n > /dev/null || ret=1 256$DIG $DIGOPTS +noauth q.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 257$DIG $DIGOPTS +noauth q.nsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 258$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 259grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 260grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 261n=`expr $n + 1` 262if [ $ret != 0 ]; then echo "I:failed"; fi 263status=`expr $status + $ret` 264 265echo "I:checking direct NSEC3 autosigning succeeded ($n)" 266ret=0 267$DIG $DIGOPTS +noall +answer autonsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.ok.test$n || ret=1 268[ -s dig.out.ns3.ok.test$n ] || ret=1 269grep "NSEC3PARAM" dig.out.ns3.ok.test$n > /dev/null || ret=1 270$DIG $DIGOPTS +noauth q.autonsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 271$DIG $DIGOPTS +noauth q.autonsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 272$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 273grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 274grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 275n=`expr $n + 1` 276if [ $ret != 0 ]; then echo "I:failed"; fi 277status=`expr $status + $ret` 278 279echo "I:checking NSEC->NSEC3 conversion failed with NSEC-only key ($n)" 280ret=0 281grep "failed: REFUSED" nsupdate.out > /dev/null || ret=1 282n=`expr $n + 1` 283if [ $ret != 0 ]; then echo "I:failed"; fi 284status=`expr $status + $ret` 285 286echo "I:checking NSEC3->NSEC conversion succeeded ($n)" 287ret=0 288# this command should result in an empty file: 289$DIG $DIGOPTS +noall +answer nsec3-to-nsec.example. nsec3param @10.53.0.3 > dig.out.ns3.nx.test$n || ret=1 290grep "NSEC3PARAM" dig.out.ns3.nx.test$n > /dev/null && ret=1 291$DIG $DIGOPTS +noauth q.nsec3-to-nsec.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 292$DIG $DIGOPTS +noauth q.nsec3-to-nsec.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 293$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 294grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 295grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 296n=`expr $n + 1` 297if [ $ret != 0 ]; then echo "I:failed"; fi 298status=`expr $status + $ret` 299 300echo "I:checking NSEC3->NSEC conversion with 'rndc signing -nsec3param none' ($n)" 301ret=0 302$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 signing -nsec3param none autonsec3.example. > /dev/null 2>&1 303sleep 2 304# this command should result in an empty file: 305$DIG $DIGOPTS +noall +answer autonsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.nx.test$n || ret=1 306grep "NSEC3PARAM" dig.out.ns3.nx.test$n > /dev/null && ret=1 307$DIG $DIGOPTS +noauth q.autonsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 308$DIG $DIGOPTS +noauth q.autonsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 309$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 310grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 311grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 312n=`expr $n + 1` 313if [ $ret != 0 ]; then echo "I:failed"; fi 314status=`expr $status + $ret` 315 316echo "I:checking TTLs of imported DNSKEYs (no default) ($n)" 317ret=0 318$DIG $DIGOPTS +tcp +noall +answer dnskey ttl1.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 319[ -s dig.out.ns3.test$n ] || ret=1 320awk 'BEGIN {r=0} $2 != 300 {r=1; print "I:found TTL " $2} END {exit r}' dig.out.ns3.test$n || ret=1 321n=`expr $n + 1` 322if [ $ret != 0 ]; then echo "I:failed"; fi 323status=`expr $status + $ret` 324 325echo "I:checking TTLs of imported DNSKEYs (with default) ($n)" 326ret=0 327$DIG $DIGOPTS +tcp +noall +answer dnskey ttl2.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 328[ -s dig.out.ns3.test$n ] || ret=1 329awk 'BEGIN {r=0} $2 != 60 {r=1; print "I:found TTL " $2} END {exit r}' dig.out.ns3.test$n || ret=1 330n=`expr $n + 1` 331if [ $ret != 0 ]; then echo "I:failed"; fi 332status=`expr $status + $ret` 333 334echo "I:checking TTLs of imported DNSKEYs (mismatched) ($n)" 335ret=0 336$DIG $DIGOPTS +tcp +noall +answer dnskey ttl3.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 337[ -s dig.out.ns3.test$n ] || ret=1 338awk 'BEGIN {r=0} $2 != 30 {r=1; print "I:found TTL " $2} END {exit r}' dig.out.ns3.test$n || ret=1 339n=`expr $n + 1` 340if [ $ret != 0 ]; then echo "I:failed"; fi 341status=`expr $status + $ret` 342 343echo "I:checking TTLs of imported DNSKEYs (existing RRset) ($n)" 344ret=0 345$DIG $DIGOPTS +tcp +noall +answer dnskey ttl4.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 346[ -s dig.out.ns3.test$n ] || ret=1 347awk 'BEGIN {r=0} $2 != 30 {r=1; print "I:found TTL " $2} END {exit r}' dig.out.ns3.test$n || ret=1 348n=`expr $n + 1` 349if [ $ret != 0 ]; then echo "I:failed"; fi 350status=`expr $status + $ret` 351 352echo "I:checking positive validation NSEC ($n)" 353ret=0 354$DIG $DIGOPTS +noauth a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 355$DIG $DIGOPTS +noauth a.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 356$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 357grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 358n=`expr $n + 1` 359if [ $ret != 0 ]; then echo "I:failed"; fi 360status=`expr $status + $ret` 361 362echo "I:checking positive validation NSEC3 ($n)" 363ret=0 364$DIG $DIGOPTS +noauth a.nsec3.example. \ 365 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 366$DIG $DIGOPTS +noauth a.nsec3.example. \ 367 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 368$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 369grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 370n=`expr $n + 1` 371if [ $ret != 0 ]; then echo "I:failed"; fi 372status=`expr $status + $ret` 373 374echo "I:checking positive validation OPTOUT ($n)" 375ret=0 376$DIG $DIGOPTS +noauth a.optout.example. \ 377 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 378$DIG $DIGOPTS +noauth a.optout.example. \ 379 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 380$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 381grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 382n=`expr $n + 1` 383if [ $ret != 0 ]; then echo "I:failed"; fi 384status=`expr $status + $ret` 385 386echo "I:checking negative validation NXDOMAIN NSEC ($n)" 387ret=0 388$DIG $DIGOPTS +noauth q.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 389$DIG $DIGOPTS +noauth q.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 390$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 391grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 392grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 393n=`expr $n + 1` 394if [ $ret != 0 ]; then echo "I:failed"; fi 395status=`expr $status + $ret` 396 397echo "I:checking negative validation NXDOMAIN NSEC3 ($n)" 398ret=0 399$DIG $DIGOPTS +noauth q.nsec3.example. \ 400 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 401$DIG $DIGOPTS +noauth q.nsec3.example. \ 402 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 403$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 404grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 405grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 406n=`expr $n + 1` 407if [ $ret != 0 ]; then echo "I:failed"; fi 408status=`expr $status + $ret` 409 410echo "I:checking negative validation NXDOMAIN OPTOUT ($n)" 411ret=0 412$DIG $DIGOPTS +noauth q.optout.example. \ 413 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 414$DIG $DIGOPTS +noauth q.optout.example. \ 415 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 416$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 417grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 418# Note - this is looking for failure, hence the && 419grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 420n=`expr $n + 1` 421if [ $ret != 0 ]; then echo "I:failed"; fi 422status=`expr $status + $ret` 423 424echo "I:checking negative validation NODATA NSEC ($n)" 425ret=0 426$DIG $DIGOPTS +noauth a.example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1 427$DIG $DIGOPTS +noauth a.example. @10.53.0.4 txt > dig.out.ns4.test$n || ret=1 428$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 429grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 430grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 431grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1 432n=`expr $n + 1` 433if [ $ret != 0 ]; then echo "I:failed"; fi 434status=`expr $status + $ret` 435 436echo "I:checking negative validation NODATA NSEC3 ($n)" 437ret=0 438$DIG $DIGOPTS +noauth a.nsec3.example. \ 439 @10.53.0.3 txt > dig.out.ns3.test$n || ret=1 440$DIG $DIGOPTS +noauth a.nsec3.example. \ 441 @10.53.0.4 txt > dig.out.ns4.test$n || ret=1 442$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 443grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 444grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 445grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1 446n=`expr $n + 1` 447if [ $ret != 0 ]; then echo "I:failed"; fi 448status=`expr $status + $ret` 449 450echo "I:checking negative validation NODATA OPTOUT ($n)" 451ret=0 452$DIG $DIGOPTS +noauth a.optout.example. \ 453 @10.53.0.3 txt > dig.out.ns3.test$n || ret=1 454$DIG $DIGOPTS +noauth a.optout.example. \ 455 @10.53.0.4 txt > dig.out.ns4.test$n || ret=1 456$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 457grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 458grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 459grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1 460n=`expr $n + 1` 461if [ $ret != 0 ]; then echo "I:failed"; fi 462status=`expr $status + $ret` 463 464# Check the insecure.example domain 465 466echo "I:checking 1-server insecurity proof NSEC ($n)" 467ret=0 468$DIG $DIGOPTS +noauth a.insecure.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 469$DIG $DIGOPTS +noauth a.insecure.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 470$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 471grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 472# Note - this is looking for failure, hence the && 473grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 474n=`expr $n + 1` 475if [ $ret != 0 ]; then echo "I:failed"; fi 476status=`expr $status + $ret` 477 478echo "I:checking 1-server negative insecurity proof NSEC ($n)" 479ret=0 480$DIG $DIGOPTS q.insecure.example. a @10.53.0.3 \ 481 > dig.out.ns3.test$n || ret=1 482$DIG $DIGOPTS q.insecure.example. a @10.53.0.4 \ 483 > dig.out.ns4.test$n || ret=1 484$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 485grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 486# Note - this is looking for failure, hence the && 487grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 488n=`expr $n + 1` 489if [ $ret != 0 ]; then echo "I:failed"; fi 490status=`expr $status + $ret` 491 492# Check the secure.example domain 493 494echo "I:checking multi-stage positive validation NSEC/NSEC ($n)" 495ret=0 496$DIG $DIGOPTS +noauth a.secure.example. \ 497 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 498$DIG $DIGOPTS +noauth a.secure.example. \ 499 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 500$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 501grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 502grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 503n=`expr $n + 1` 504if [ $ret != 0 ]; then echo "I:failed"; fi 505status=`expr $status + $ret` 506 507echo "I:checking multi-stage positive validation NSEC/NSEC3 ($n)" 508ret=0 509$DIG $DIGOPTS +noauth a.nsec3.example. \ 510 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 511$DIG $DIGOPTS +noauth a.nsec3.example. \ 512 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 513$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 514grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 515grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 516n=`expr $n + 1` 517if [ $ret != 0 ]; then echo "I:failed"; fi 518status=`expr $status + $ret` 519 520echo "I:checking multi-stage positive validation NSEC/OPTOUT ($n)" 521ret=0 522$DIG $DIGOPTS +noauth a.optout.example. \ 523 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 524$DIG $DIGOPTS +noauth a.optout.example. \ 525 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 526$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 527grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 528grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 529n=`expr $n + 1` 530if [ $ret != 0 ]; then echo "I:failed"; fi 531status=`expr $status + $ret` 532 533echo "I:checking multi-stage positive validation NSEC3/NSEC ($n)" 534ret=0 535$DIG $DIGOPTS +noauth a.secure.nsec3.example. \ 536 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 537$DIG $DIGOPTS +noauth a.secure.nsec3.example. \ 538 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 539$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 540grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 541grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 542n=`expr $n + 1` 543if [ $ret != 0 ]; then echo "I:failed"; fi 544status=`expr $status + $ret` 545 546echo "I:checking multi-stage positive validation NSEC3/NSEC3 ($n)" 547ret=0 548$DIG $DIGOPTS +noauth a.nsec3.nsec3.example. \ 549 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 550$DIG $DIGOPTS +noauth a.nsec3.nsec3.example. \ 551 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 552$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 553grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 554grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 555n=`expr $n + 1` 556if [ $ret != 0 ]; then echo "I:failed"; fi 557status=`expr $status + $ret` 558 559echo "I:checking multi-stage positive validation NSEC3/OPTOUT ($n)" 560ret=0 561$DIG $DIGOPTS +noauth a.optout.nsec3.example. \ 562 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 563$DIG $DIGOPTS +noauth a.optout.nsec3.example. \ 564 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 565$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 566grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 567grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 568n=`expr $n + 1` 569if [ $ret != 0 ]; then echo "I:failed"; fi 570status=`expr $status + $ret` 571 572echo "I:checking multi-stage positive validation OPTOUT/NSEC ($n)" 573ret=0 574$DIG $DIGOPTS +noauth a.secure.optout.example. \ 575 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 576$DIG $DIGOPTS +noauth a.secure.optout.example. \ 577 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 578$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 579grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 580grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 581n=`expr $n + 1` 582if [ $ret != 0 ]; then echo "I:failed"; fi 583status=`expr $status + $ret` 584 585echo "I:checking multi-stage positive validation OPTOUT/NSEC3 ($n)" 586ret=0 587$DIG $DIGOPTS +noauth a.nsec3.optout.example. \ 588 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 589$DIG $DIGOPTS +noauth a.nsec3.optout.example. \ 590 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 591$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 592grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 593grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 594n=`expr $n + 1` 595if [ $ret != 0 ]; then echo "I:failed"; fi 596status=`expr $status + $ret` 597 598echo "I:checking multi-stage positive validation OPTOUT/OPTOUT ($n)" 599ret=0 600$DIG $DIGOPTS +noauth a.optout.optout.example. \ 601 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 602$DIG $DIGOPTS +noauth a.optout.optout.example. \ 603 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 604$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 605grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 606grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 607n=`expr $n + 1` 608if [ $ret != 0 ]; then echo "I:failed"; fi 609status=`expr $status + $ret` 610 611echo "I:checking empty NODATA OPTOUT ($n)" 612ret=0 613$DIG $DIGOPTS +noauth empty.optout.example. \ 614 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 615$DIG $DIGOPTS +noauth empty.optout.example. \ 616 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 617$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 618grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 619#grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 620n=`expr $n + 1` 621if [ $ret != 0 ]; then echo "I:failed"; fi 622status=`expr $status + $ret` 623 624# Check the insecure.secure.example domain (insecurity proof) 625 626echo "I:checking 2-server insecurity proof ($n)" 627ret=0 628$DIG $DIGOPTS +noauth a.insecure.secure.example. @10.53.0.2 a \ 629 > dig.out.ns2.test$n || ret=1 630$DIG $DIGOPTS +noauth a.insecure.secure.example. @10.53.0.4 a \ 631 > dig.out.ns4.test$n || ret=1 632$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 633grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 634# Note - this is looking for failure, hence the && 635grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 636n=`expr $n + 1` 637if [ $ret != 0 ]; then echo "I:failed"; fi 638status=`expr $status + $ret` 639 640# Check a negative response in insecure.secure.example 641 642echo "I:checking 2-server insecurity proof with a negative answer ($n)" 643ret=0 644$DIG $DIGOPTS q.insecure.secure.example. @10.53.0.2 a > dig.out.ns2.test$n \ 645 || ret=1 646$DIG $DIGOPTS q.insecure.secure.example. @10.53.0.4 a > dig.out.ns4.test$n \ 647 || ret=1 648$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 649grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 650# Note - this is looking for failure, hence the && 651grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 652n=`expr $n + 1` 653if [ $ret != 0 ]; then echo "I:failed"; fi 654status=`expr $status + $ret` 655 656echo "I:checking security root query ($n)" 657ret=0 658$DIG $DIGOPTS . @10.53.0.4 key > dig.out.ns4.test$n || ret=1 659grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 660grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 661n=`expr $n + 1` 662if [ $ret != 0 ]; then echo "I:failed"; fi 663status=`expr $status + $ret` 664 665echo "I:checking positive validation RSASHA256 NSEC ($n)" 666ret=0 667$DIG $DIGOPTS +noauth a.rsasha256.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 668$DIG $DIGOPTS +noauth a.rsasha256.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 669$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 670grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 671n=`expr $n + 1` 672if [ $ret != 0 ]; then echo "I:failed"; fi 673status=`expr $status + $ret` 674 675echo "I:checking positive validation RSASHA512 NSEC ($n)" 676ret=0 677$DIG $DIGOPTS +noauth a.rsasha512.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 678$DIG $DIGOPTS +noauth a.rsasha512.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 679$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 680grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 681n=`expr $n + 1` 682if [ $ret != 0 ]; then echo "I:failed"; fi 683status=`expr $status + $ret` 684 685echo "I:checking that positive validation in a privately secure zone works ($n)" 686ret=0 687$DIG $DIGOPTS +noauth a.private.secure.example. a @10.53.0.2 \ 688 > dig.out.ns2.test$n || ret=1 689$DIG $DIGOPTS +noauth a.private.secure.example. a @10.53.0.4 \ 690 > dig.out.ns4.test$n || ret=1 691$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 692grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 693# Note - this is looking for failure, hence the && 694grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 695n=`expr $n + 1` 696if [ $ret != 0 ]; then echo "I:failed"; fi 697status=`expr $status + $ret` 698 699echo "I:checking that negative validation in a privately secure zone works ($n)" 700ret=0 701$DIG $DIGOPTS +noauth q.private.secure.example. a @10.53.0.2 \ 702 > dig.out.ns2.test$n || ret=1 703$DIG $DIGOPTS +noauth q.private.secure.example. a @10.53.0.4 \ 704 > dig.out.ns4.test$n || ret=1 705$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 706grep "NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 707# Note - this is looking for failure, hence the && 708grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 709n=`expr $n + 1` 710if [ $ret != 0 ]; then echo "I:failed"; fi 711status=`expr $status + $ret` 712 713echo "I:checking privately secure to nxdomain works ($n)" 714ret=0 715$DIG $DIGOPTS +noauth private2secure-nxdomain.private.secure.example. SOA @10.53.0.2 \ 716 > dig.out.ns2.test$n || ret=1 717$DIG $DIGOPTS +noauth private2secure-nxdomain.private.secure.example. SOA @10.53.0.4 \ 718 > dig.out.ns4.test$n || ret=1 719$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 720# Note - this is looking for failure, hence the && 721grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 722n=`expr $n + 1` 723if [ $ret != 0 ]; then echo "I:failed"; fi 724status=`expr $status + $ret` 725 726# Try validating with a revoked trusted key. 727# This should fail. 728 729echo "I:checking that validation returns insecure due to revoked trusted key ($n)" 730ret=0 731$DIG $DIGOPTS example. soa @10.53.0.5 > dig.out.ns5.test$n || ret=1 732grep "flags:.*; QUERY" dig.out.ns5.test$n > /dev/null || ret=1 733grep "flags:.* ad.*; QUERY" dig.out.ns5.test$n > /dev/null && ret=1 734n=`expr $n + 1` 735if [ $ret != 0 ]; then echo "I:failed"; fi 736status=`expr $status + $ret` 737 738echo "I:checking that revoked key is present ($n)" 739ret=0 740id=`cat rev.key` 741$DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 742grep '; key id = '"$id"'$' dig.out.ns1.test$n > /dev/null || ret=1 743n=`expr $n + 1` 744if [ $ret != 0 ]; then echo "I:failed"; fi 745status=`expr $status + $ret` 746 747echo "I:checking that revoked key self-signs ($n)" 748ret=0 749id=`cat rev.key` 750$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 751grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null || ret=1 752n=`expr $n + 1` 753if [ $ret != 0 ]; then echo "I:failed"; fi 754status=`expr $status + $ret` 755 756echo "I:checking for unpublished key ($n)" 757ret=0 758id=`sed 's/^K.+007+0*\([0-9]\)/\1/' < unpub.key` 759$DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 760grep '; key id = '"$id"'$' dig.out.ns1.test$n > /dev/null && ret=1 761n=`expr $n + 1` 762if [ $ret != 0 ]; then echo "I:failed"; fi 763status=`expr $status + $ret` 764 765echo "I:checking that standby key does not sign records ($n)" 766ret=0 767id=`sed 's/^K.+007+0*\([0-9]\)/\1/' < standby.key` 768$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 769grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null && ret=1 770n=`expr $n + 1` 771if [ $ret != 0 ]; then echo "I:failed"; fi 772status=`expr $status + $ret` 773 774echo "I:checking that deactivated key does not sign records ($n)" 775ret=0 776id=`sed 's/^K.+007+0*\([0-9]\)/\1/' < inact.key` 777$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 778grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null && ret=1 779n=`expr $n + 1` 780if [ $ret != 0 ]; then echo "I:failed"; fi 781status=`expr $status + $ret` 782 783echo "I:checking insertion of public-only key ($n)" 784ret=0 785id=`sed 's/^K.+007+0*\([0-9]\)/\1/' < nopriv.key` 786file="ns1/`cat nopriv.key`.key" 787keydata=`grep DNSKEY $file` 788$NSUPDATE > /dev/null 2>&1 <<END || status=1 789server 10.53.0.1 5300 790zone . 791ttl 3600 792update add $keydata 793send 794END 795sleep 1 796$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 797grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null && ret=1 798n=`expr $n + 1` 799if [ $ret != 0 ]; then echo "I:failed"; fi 800status=`expr $status + $ret` 801 802echo "I:checking key deletion ($n)" 803ret=0 804id=`sed 's/^K.+007+0*\([0-9]\)/\1/' < del.key` 805$DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 806grep '; key id = '"$id"'$' dig.out.ns1.test$n > /dev/null && ret=1 807n=`expr $n + 1` 808if [ $ret != 0 ]; then echo "I:failed"; fi 809status=`expr $status + $ret` 810 811echo "I:checking secure-to-insecure transition, nsupdate ($n)" 812$NSUPDATE > /dev/null 2>&1 <<END || status=1 813server 10.53.0.3 5300 814zone secure-to-insecure.example 815update delete secure-to-insecure.example dnskey 816send 817END 818sleep 2 819$DIG $DIGOPTS axfr secure-to-insecure.example @10.53.0.3 > dig.out.ns3.test$n || ret=1 820egrep '(RRSIG|DNSKEY|NSEC)' dig.out.ns3.test$n > /dev/null && ret=1 821n=`expr $n + 1` 822if [ $ret != 0 ]; then echo "I:failed"; fi 823status=`expr $status + $ret` 824 825echo "I:checking secure-to-insecure transition, scheduled ($n)" 826ret=0 827file="ns3/`cat del1.key`.key" 828$SETTIME -I now -D now $file > /dev/null 829file="ns3/`cat del2.key`.key" 830$SETTIME -I now -D now $file > /dev/null 831$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 sign secure-to-insecure2.example. 2>&1 | sed 's/^/I:ns3 /' 832sleep 2 833$DIG $DIGOPTS axfr secure-to-insecure2.example @10.53.0.3 > dig.out.ns3.test$n || ret=1 834egrep '(RRSIG|DNSKEY|NSEC3)' dig.out.ns3.test$n > /dev/null && ret=1 835n=`expr $n + 1` 836if [ $ret != 0 ]; then echo "I:failed"; fi 837status=`expr $status + $ret` 838 839echo "I:checking that serial number and RRSIGs are both updated (rt21045) ($n)" 840ret=0 841oldserial=`$DIG $DIGOPTS +short soa prepub.example @10.53.0.3 | awk '$0 !~ /SOA/ {print $3}'` 842oldinception=`$DIG $DIGOPTS +short soa prepub.example @10.53.0.3 | awk '/SOA/ {print $6}' | sort -u` 843 844$KEYGEN -3 -q -r $RANDFILE -K ns3 -P 0 -A +6d -I +38d -D +45d prepub.example > /dev/null 845 846$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 sign prepub.example 2>&1 | sed 's/^/I:ns1 /' 847newserial=$oldserial 848try=0 849while [ $oldserial -eq $newserial -a $try -lt 42 ] 850do 851 newserial=`$DIG $DIGOPTS +short soa prepub.example @10.53.0.3 | 852 awk '$0 !~ /SOA/ {print $3}'` 853 sleep 1 854 try=`expr $try + 1` 855done 856newinception=`$DIG $DIGOPTS +short soa prepub.example @10.53.0.3 | awk '/SOA/ {print $6}' | sort -u` 857#echo "$oldserial : $newserial" 858#echo "$oldinception : $newinception" 859 860[ "$oldserial" = "$newserial" ] && ret=1 861[ "$oldinception" = "$newinception" ] && ret=1 862if [ $ret != 0 ]; then echo "I:failed"; fi 863status=`expr $status + $ret` 864 865echo "I:preparing to test key change corner cases" 866echo "I:removing a private key file" 867file="ns1/`cat vanishing.key`.private" 868rm -f $file 869 870echo "I:preparing ZSK roll" 871starttime=`$PERL -e 'print time(), "\n";'` 872oldfile=`cat active.key` 873oldid=`sed 's/^K.+007+0*\([0-9]\)/\1/' < active.key` 874newfile=`cat standby.key` 875newid=`sed 's/^K.+007+0*\([0-9]\)/\1/' < standby.key` 876$SETTIME -K ns1 -I now+2s -D now+25 $oldfile > /dev/null 877$SETTIME -K ns1 -i 0 -S $oldfile $newfile > /dev/null 878 879# note previous zone serial number 880oldserial=`$DIG $DIGOPTS +short soa . @10.53.0.1 | awk '{print $3}'` 881 882$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 loadkeys . 2>&1 | sed 's/^/I:ns1 /' 883sleep 4 884 885echo "I:revoking key to duplicated key ID" 886$SETTIME -R now -K ns2 Kbar.+005+30676.key > /dev/null 887 888$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 loadkeys bar. 2>&1 | sed 's/^/I:ns2 /' 889 890echo "I:waiting for changes to take effect" 891sleep 5 892 893echo "I:checking former standby key is now active ($n)" 894ret=0 895$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 896grep 'RRSIG.*'" $newid "'\. ' dig.out.ns1.test$n > /dev/null || ret=1 897n=`expr $n + 1` 898if [ $ret != 0 ]; then echo "I:failed"; fi 899status=`expr $status + $ret` 900 901echo "I:checking former standby key has only signed incrementally ($n)" 902ret=0 903$DIG $DIGOPTS txt . @10.53.0.1 > dig.out.ns1.test$n || ret=1 904grep 'RRSIG.*'" $newid "'\. ' dig.out.ns1.test$n > /dev/null && ret=1 905grep 'RRSIG.*'" $oldid "'\. ' dig.out.ns1.test$n > /dev/null || ret=1 906n=`expr $n + 1` 907if [ $ret != 0 ]; then echo "I:failed"; fi 908status=`expr $status + $ret` 909 910echo "I:checking that signing records have been marked as complete ($n)" 911ret=0 912checkprivate . 10.53.0.1 || ret=1 913checkprivate bar 10.53.0.2 || ret=1 914checkprivate example 10.53.0.2 || ret=1 915checkprivate private.secure.example 10.53.0.3 || ret=1 916checkprivate nsec3.example 10.53.0.3 || ret=1 917checkprivate nsec3.nsec3.example 10.53.0.3 || ret=1 918checkprivate nsec3.optout.example 10.53.0.3 || ret=1 919checkprivate nsec3-to-nsec.example 10.53.0.3 || ret=1 920checkprivate nsec.example 10.53.0.3 || ret=1 921checkprivate oldsigs.example 10.53.0.3 || ret=1 922checkprivate optout.example 10.53.0.3 || ret=1 923checkprivate optout.nsec3.example 10.53.0.3 || ret=1 924checkprivate optout.optout.example 10.53.0.3 || ret=1 925checkprivate prepub.example 10.53.0.3 || ret=1 926checkprivate rsasha256.example 10.53.0.3 || ret=1 927checkprivate rsasha512.example 10.53.0.3 || ret=1 928checkprivate secure.example 10.53.0.3 || ret=1 929checkprivate secure.nsec3.example 10.53.0.3 || ret=1 930checkprivate secure.optout.example 10.53.0.3 || ret=1 931checkprivate secure-to-insecure2.example 10.53.0.3 || ret=1 932checkprivate secure-to-insecure.example 10.53.0.3 || ret=1 933checkprivate ttl1.example 10.53.0.3 || ret=1 934checkprivate ttl2.example 10.53.0.3 || ret=1 935checkprivate ttl3.example 10.53.0.3 || ret=1 936checkprivate ttl4.example 10.53.0.3 || ret=1 937n=`expr $n + 1` 938status=`expr $status + $ret` 939 940echo "I:forcing full sign" 941$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 sign . 2>&1 | sed 's/^/I:ns1 /' 942 943echo "I:waiting for change to take effect" 944sleep 5 945 946echo "I:checking former standby key has now signed fully ($n)" 947ret=0 948$DIG $DIGOPTS txt . @10.53.0.1 > dig.out.ns1.test$n || ret=1 949grep 'RRSIG.*'" $newid "'\. ' dig.out.ns1.test$n > /dev/null || ret=1 950n=`expr $n + 1` 951if [ $ret != 0 ]; then echo "I:failed"; fi 952status=`expr $status + $ret` 953 954echo "I:checking SOA serial number has been incremented ($n)" 955ret=0 956newserial=`$DIG $DIGOPTS +short soa . @10.53.0.1 | awk '{print $3}'` 957[ "$newserial" != "$oldserial" ] || ret=1 958n=`expr $n + 1` 959if [ $ret != 0 ]; then echo "I:failed"; fi 960status=`expr $status + $ret` 961 962echo "I:checking delayed key publication/activation ($n)" 963ret=0 964zsk=`cat delayzsk.key` 965ksk=`cat delayksk.key` 966# publication and activation times should be unset 967$SETTIME -K ns3 -pA -pP $zsk | grep -v UNSET > /dev/null 2>&1 && ret=1 968$SETTIME -K ns3 -pA -pP $ksk | grep -v UNSET > /dev/null 2>&1 && ret=1 969$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 970# DNSKEY not expected: 971awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.test$n && ret=1 972n=`expr $n + 1` 973if [ $ret != 0 ]; then echo "I:failed"; fi 974status=`expr $status + $ret` 975 976echo "I:checking scheduled key publication, not activation ($n)" 977ret=0 978$SETTIME -K ns3 -P now+3s -A none $zsk > /dev/null 2>&1 979$SETTIME -K ns3 -P now+3s -A none $ksk > /dev/null 2>&1 980$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 loadkeys delay.example. 2>&1 | sed 's/^/I:ns2 /' 981 982echo "I:waiting for changes to take effect" 983sleep 5 984 985$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1 986# DNSKEY expected: 987awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.test$n || ret=1 988# RRSIG not expected: 989awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.test$n && ret=1 990n=`expr $n + 1` 991if [ $ret != 0 ]; then echo "I:failed"; fi 992status=`expr $status + $ret` 993 994echo "I:checking scheduled key activation ($n)" 995ret=0 996$SETTIME -K ns3 -A now+3s $zsk > /dev/null 2>&1 997$SETTIME -K ns3 -A now+3s $ksk > /dev/null 2>&1 998$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 loadkeys delay.example. 2>&1 | sed 's/^/I:ns2 /' 999 1000echo "I:waiting for changes to take effect" 1001sleep 5 1002 1003$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.1.test$n || ret=1 1004# DNSKEY expected: 1005awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.1.test$n || ret=1 1006# RRSIG expected: 1007awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.1.test$n || ret=1 1008$DIG $DIGOPTS +noall +answer a a.delay.example. @10.53.0.3 > dig.out.ns3.2.test$n || ret=1 1009# A expected: 1010awk 'BEGIN {r=1} $4=="A" {r=0} END {exit r}' dig.out.ns3.2.test$n || ret=1 1011# RRSIG expected: 1012awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.2.test$n || ret=1 1013n=`expr $n + 1` 1014if [ $ret != 0 ]; then echo "I:failed"; fi 1015status=`expr $status + $ret` 1016 1017echo "I:checking former active key was removed ($n)" 1018# 1019# Work out how long we need to sleep. Allow 4 seconds for the records 1020# to be removed. 1021# 1022now=`$PERL -e 'print time(), "\n";'` 1023sleep=`expr $starttime + 29 - $now` 1024case $sleep in 1025-*|0);; 1026*) echo "I:waiting for timer to have activated"; sleep $sleep;; 1027esac 1028ret=0 1029$DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 1030grep '; key id = '"$oldid"'$' dig.out.ns1.test$n > /dev/null && ret=1 1031n=`expr $n + 1` 1032if [ $ret != 0 ]; then echo "I:failed"; fi 1033status=`expr $status + $ret` 1034 1035echo "I:checking private key file removal caused no immediate harm ($n)" 1036ret=0 1037id=`sed 's/^K.+007+0*\([0-9]\)/\1/' < vanishing.key` 1038$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1 1039grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null || ret=1 1040n=`expr $n + 1` 1041if [ $ret != 0 ]; then echo "I:failed"; fi 1042status=`expr $status + $ret` 1043 1044echo "I:checking revoked key with duplicate key ID (failure expected) ($n)" 1045lret=0 1046id=30676 1047$DIG $DIGOPTS +multi dnskey bar @10.53.0.2 > dig.out.ns2.test$n || lret=1 1048grep '; key id = '"$id"'$' dig.out.ns2.test$n > /dev/null || lret=1 1049$DIG $DIGOPTS dnskey bar @10.53.0.4 > dig.out.ns4.test$n || lret=1 1050grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || lret=1 1051n=`expr $n + 1` 1052if [ $lret != 0 ]; then echo "I:not yet implemented"; fi 1053 1054echo "I:checking key event timers are always set ($n)" 1055# this is a regression test for a bug in which the next key event could 1056# be scheduled for the present moment, and then never fire. check for 1057# visible evidence of this error in the logs: 1058awk '/next key event/ {if ($1 == $8 && $2 == $9) exit 1}' */named.run || ret=1 1059n=`expr $n + 1` 1060if [ $ret != 0 ]; then echo "I:failed"; fi 1061status=`expr $status + $ret` 1062 1063# this confirms that key events are never scheduled more than 1064# 'dnssec-loadkeys-interval' minutes in the future, and that the 1065# event scheduled is within 10 seconds of expected interval. 1066check_interval () { 1067 awk '/next key event/ {print $2 ":" $9}' $1/named.run | 1068 sed 's/\.//g' | 1069 awk -F: ' 1070 { 1071 x = ($6+ $5*60000 + $4*3600000) - ($3+ $2*60000 + $1*3600000); 1072 # abs(x) < 1000 ms treat as 'now' 1073 if (x < 1000 && x > -1000) 1074 x = 0; 1075 # convert to seconds 1076 x = x/1000; 1077 # handle end of day roll over 1078 if (x < 0) 1079 x = x + 24*3600; 1080 # handle log timestamp being a few milliseconds later 1081 if (x != int(x)) 1082 x = int(x + 1); 1083 if (int(x) > int(interval)) 1084 exit (1); 1085 } 1086 END { if (int(x) > int(interval) || int(x) < int(interval-10)) exit(1) }' interval=$2 1087 return $? 1088} 1089 1090echo "I:checking automatic key reloading interval ($n)" 1091ret=0 1092check_interval ns1 3600 || ret=1 1093check_interval ns2 1800 || ret=1 1094check_interval ns3 600 || ret=1 1095n=`expr $n + 1` 1096if [ $ret != 0 ]; then echo "I:failed"; fi 1097status=`expr $status + $ret` 1098 1099echo "I:checking for key reloading loops ($n)" 1100ret=0 1101# every key event should schedule a successor, so these should be equal 1102rekey_calls=`grep "reconfiguring zone keys" ns*/named.run | wc -l` 1103rekey_events=`grep "next key event" ns*/named.run | wc -l` 1104[ "$rekey_calls" = "$rekey_events" ] || ret=1 1105n=`expr $n + 1` 1106if [ $ret != 0 ]; then echo "I:failed"; fi 1107status=`expr $status + $ret` 1108 1109echo "I:forcing full sign with unreadable keys ($n)" 1110ret=0 1111chmod 0 ns1/K.+*+*.key ns1/K.+*+*.private || ret=1 1112$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 sign . 2>&1 | sed 's/^/I:ns1 /' 1113$DIG $DIGOPTS . @10.53.0.1 dnskey > dig.out.ns1.test$n || ret=1 1114grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1 1115n=`expr $n + 1` 1116if [ $ret != 0 ]; then echo "I:failed"; fi 1117status=`expr $status + $ret` 1118 1119echo "I:test turning on auto-dnssec during reconfig ($n)" 1120ret=0 1121# first create a zone that doesn't have auto-dnssec 1122rm -f ns3/*.nzf 1123$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 addzone reconf.example '{ type master; file "reconf.example.db"; };' 2>&1 | sed 's/^/I:ns3 /' 1124rekey_calls=`grep "zone reconf.example.*next key event" ns3/named.run | wc -l` 1125[ "$rekey_calls" -eq 0 ] || ret=1 1126# ...then we add auto-dnssec and reconfigure 1127nzf=`ls ns3/*.nzf` 1128echo 'zone reconf.example { type master; file "reconf.example.db"; allow-update { any; }; auto-dnssec maintain; };' > $nzf 1129$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 reconfig 2>&1 | sed 's/^/I:ns3 /' 1130for i in 0 1 2 3 4 5 6 7 8 9; do 1131 lret=0 1132 rekey_calls=`grep "zone reconf.example.*next key event" ns3/named.run | wc -l` 1133 [ "$rekey_calls" -gt 0 ] || lret=1 1134 if [ "$lret" = 0 ]; then break; fi 1135 sleep 1 1136done 1137n=`expr $n + 1` 1138if [ "$lret" != 0 ]; then ret=$lret; fi 1139if [ $ret != 0 ]; then echo "I:failed"; fi 1140status=`expr $status + $ret` 1141 1142echo "I:exit status: $status" 1143exit $status 1144