1#!/bin/sh 2# 3# Copyright (C) Internet Systems Consortium, Inc. ("ISC") 4# 5# This Source Code Form is subject to the terms of the Mozilla Public 6# License, v. 2.0. If a copy of the MPL was not distributed with this 7# file, you can obtain one at https://mozilla.org/MPL/2.0/. 8# 9# See the COPYRIGHT file distributed with this work for additional 10# information regarding copyright ownership. 11 12# shellcheck source=conf.sh 13SYSTEMTESTTOP=.. 14. "$SYSTEMTESTTOP/conf.sh" 15 16set -e 17 18status=0 19n=1 20 21rm -f dig.out.* 22 23dig_with_opts() { 24 "$DIG" +tcp +noadd +nosea +nostat +nocmd +dnssec -p "$PORT" "$@" 25} 26 27dig_with_additionalopts() { 28 "$DIG" +noall +additional +dnssec -p "$PORT" "$@" 29} 30 31dig_with_answeropts() { 32 "$DIG" +noall +answer +dnssec -p "$PORT" "$@" 33} 34 35delv_with_opts() { 36 "$DELV" -a ns1/trusted.conf -p "$PORT" "$@" 37} 38 39rndccmd() { 40 "$RNDC" -c "$SYSTEMTESTTOP/common/rndc.conf" -p "$CONTROLPORT" -s "$@" 41} 42 43# TODO: Move loadkeys_on to conf.sh.common 44dnssec_loadkeys_on() { 45 nsidx=$1 46 zone=$2 47 nextpart ns${nsidx}/named.run > /dev/null 48 rndccmd 10.53.0.${nsidx} loadkeys ${zone} | sed "s/^/ns${nsidx} /" | cat_i 49 wait_for_log 20 "next key event" ns${nsidx}/named.run || return 1 50} 51 52# convert private-type records to readable form 53showprivate () { 54 echo "-- $* --" 55 dig_with_opts +nodnssec +short "@$2" -t type65534 "$1" | cut -f3 -d' ' | 56 while read -r record; do 57 # shellcheck disable=SC2016 58 $PERL -e 'my $rdata = pack("H*", @ARGV[0]); 59 die "invalid record" unless length($rdata) == 5; 60 my ($alg, $key, $remove, $complete) = unpack("CnCC", $rdata); 61 my $action = "signing"; 62 $action = "removing" if $remove; 63 my $state = " (incomplete)"; 64 $state = " (complete)" if $complete; 65 print ("$action: alg: $alg, key: $key$state\n");' "$record" 66 done 67} 68 69# check that signing records are marked as complete 70checkprivate () { 71 for i in 1 2 3 4 5 6 7 8 9 10; do 72 showprivate "$@" | grep -q incomplete || return 0 73 sleep 1 74 done 75 echo_d "$1 signing incomplete" 76 return 1 77} 78 79# check that a zone file is raw format, version 0 80israw0 () { 81 # shellcheck disable=SC2016 82 < "$1" $PERL -e 'binmode STDIN; 83 read(STDIN, $input, 8); 84 ($style, $version) = unpack("NN", $input); 85 exit 1 if ($style != 2 || $version != 0);' 86 return $? 87} 88 89# check that a zone file is raw format, version 1 90israw1 () { 91 # shellcheck disable=SC2016 92 < "$1" $PERL -e 'binmode STDIN; 93 read(STDIN, $input, 8); 94 ($style, $version) = unpack("NN", $input); 95 exit 1 if ($style != 2 || $version != 1);' 96 return $? 97} 98 99# strip NS and RRSIG NS from input 100stripns () { 101 awk '($4 == "NS") || ($4 == "RRSIG" && $5 == "NS") { next} { print }' "$1" 102} 103 104# 105# Ensure there is not multiple consecutive blank lines. 106# Ensure there is a blank line before "Start view" and 107# "Negative trust anchors:". 108# Ensure there is not a blank line before "Secure roots:". 109# 110check_secroots_layout () { 111 tr -d '\r' < "$1" | \ 112 awk '$0 == "" { if (empty) exit(1); empty=1; next } 113 /Start view/ { if (!empty) exit(1) } 114 /Secure roots:/ { if (empty) exit(1) } 115 /Negative trust anchors:/ { if (!empty) exit(1) } 116 { empty=0 }' 117 return $? 118} 119 120# Check that for a query against a validating resolver where the 121# authoritative zone is unsigned (insecure delegation), glue is returned 122# in the additional section 123echo_i "checking that additional glue is returned for unsigned delegation ($n)" 124ret=0 125$DIG +tcp +dnssec -p "$PORT" a.insecure.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 126grep "ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2" dig.out.ns4.test$n > /dev/null || ret=1 127grep "ns\\.insecure\\.example\\..*A.10\\.53\\.0\\.3" dig.out.ns4.test$n > /dev/null || ret=1 128n=$((n+1)) 129if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 130status=$((status+ret)) 131 132# Check the example. domain 133 134echo_i "checking that zone transfer worked ($n)" 135for i in 1 2 3 4 5 6 7 8 9 136do 137 ret=0 138 dig_with_opts a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 139 dig_with_opts a.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 140 $PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns3.test$n > /dev/null || ret=1 141 [ "$ret" -eq 0 ] && break 142 sleep 1 143done 144digcomp dig.out.ns2.test$n dig.out.ns3.test$n > /dev/null || ret=1 145n=$((n+1)) 146test "$ret" -eq 0 || echo_i "failed" 147status=$((status+ret)) 148 149# test AD bit: 150# - dig +adflag asks for authentication (ad in response) 151echo_i "checking AD bit asking for validation ($n)" 152ret=0 153dig_with_opts +noauth +noadd +nodnssec +adflag a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 154dig_with_opts +noauth +noadd +nodnssec +adflag a.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 155digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 156grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 157n=$((n+1)) 158test "$ret" -eq 0 || echo_i "failed" 159status=$((status+ret)) 160 161# test AD bit: 162# - dig +noadflag 163echo_i "checking that AD is not set without +adflag or +dnssec ($n)" 164ret=0 165dig_with_opts +noauth +noadd +nodnssec +noadflag a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 166dig_with_opts +noauth +noadd +nodnssec +noadflag a.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 167digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 168grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 169n=$((n+1)) 170test "$ret" -eq 0 || echo_i "failed" 171status=$((status+ret)) 172 173echo_i "checking for AD in authoritative answer ($n)" 174ret=0 175dig_with_opts a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 176grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null && ret=1 177n=$((n+1)) 178test "$ret" -eq 0 || echo_i "failed" 179status=$((status+ret)) 180 181echo_i "checking positive validation NSEC ($n)" 182ret=0 183dig_with_opts +noauth a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 184dig_with_opts +noauth a.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 185digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 186grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 187n=$((n+1)) 188test "$ret" -eq 0 || echo_i "failed" 189status=$((status+ret)) 190 191echo_i "checking that 'example/DS' from the referral was used in previous validation ($n)" 192ret=0 193grep "query 'example/DS/IN' approved" ns1/named.run > /dev/null && ret=1 194grep "fetch: example/DS" ns4/named.run > /dev/null && ret=1 195grep "validating example/DS: starting" ns4/named.run > /dev/null || ret=1 196n=$((n+1)) 197test "$ret" -eq 0 || echo_i "failed" 198status=$((status+ret)) 199 200if [ -x ${DELV} ] ; then 201 ret=0 202 echo_i "checking positive validation NSEC using dns_client ($n)" 203 delv_with_opts @10.53.0.4 a a.example > delv.out$n || ret=1 204 grep "a.example..*10.0.0.1" delv.out$n > /dev/null || ret=1 205 grep "a.example..*.RRSIG.A [0-9][0-9]* 2 300 .*" delv.out$n > /dev/null || ret=1 206 n=$((n+1)) 207 test "$ret" -eq 0 || echo_i "failed" 208 status=$((status+ret)) 209 210 ret=0 211 echo_i "checking positive validation NSEC using dns_client (trusted-keys) ($n)" 212 "$DELV" -a ns1/trusted.keys -p "$PORT" @10.53.0.4 a a.example > delv.out$n || ret=1 213 grep "a.example..*10.0.0.1" delv.out$n > /dev/null || ret=1 214 grep "a.example..*.RRSIG.A [0-9][0-9]* 2 300 .*" delv.out$n > /dev/null || ret=1 215 n=$((n+1)) 216 test "$ret" -eq 0 || echo_i "failed" 217 status=$((status+ret)) 218fi 219 220echo_i "checking positive validation NSEC3 ($n)" 221ret=0 222dig_with_opts +noauth a.nsec3.example. \ 223 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 224dig_with_opts +noauth a.nsec3.example. \ 225 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 226digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 227grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 228n=$((n+1)) 229test "$ret" -eq 0 || echo_i "failed" 230status=$((status+ret)) 231 232if [ -x ${DELV} ] ; then 233 ret=0 234 echo_i "checking positive validation NSEC3 using dns_client ($n)" 235 delv_with_opts @10.53.0.4 a a.nsec3.example > delv.out$n || ret=1 236 grep "a.nsec3.example..*10.0.0.1" delv.out$n > /dev/null || ret=1 237 grep "a.nsec3.example..*RRSIG.A [0-9][0-9]* 3 300.*" delv.out$n > /dev/null || ret=1 238 n=$((n+1)) 239 test "$ret" -eq 0 || echo_i "failed" 240 status=$((status+ret)) 241fi 242 243echo_i "checking positive validation OPTOUT ($n)" 244ret=0 245dig_with_opts +noauth a.optout.example. \ 246 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 247dig_with_opts +noauth a.optout.example. \ 248 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 249digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 250grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 251n=$((n+1)) 252test "$ret" -eq 0 || echo_i "failed" 253status=$((status+ret)) 254 255SP="[[:space:]]+" 256 257if [ -x ${DELV} ] ; then 258 ret=0 259 echo_i "checking positive validation OPTOUT using dns_client ($n)" 260 delv_with_opts @10.53.0.4 a a.optout.example > delv.out$n || ret=1 261 grep -Eq "^a\\.optout\\.example\\.""$SP""[0-9]+""$SP""IN""$SP""A""$SP""10.0.0.1" delv.out$n || ret=1 262 grep -Eq "^a\\.optout\\.example\\.""$SP""[0-9]+""$SP""IN""$SP""RRSIG""$SP""A""$SP""$DEFAULT_ALGORITHM_NUMBER""$SP""3""$SP""300" delv.out$n || ret=1 263 n=$((n+1)) 264 test "$ret" -eq 0 || echo_i "failed" 265 status=$((status+ret)) 266fi 267 268echo_i "checking positive wildcard validation NSEC ($n)" 269ret=0 270dig_with_opts a.wild.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 271dig_with_opts a.wild.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 272stripns dig.out.ns3.test$n > dig.out.ns3.stripped.test$n 273stripns dig.out.ns4.test$n > dig.out.ns4.stripped.test$n 274digcomp dig.out.ns3.stripped.test$n dig.out.ns4.stripped.test$n || ret=1 275grep "\\*\\.wild\\.example\\..*RRSIG NSEC" dig.out.ns4.test$n > /dev/null || ret=1 276grep "\\*\\.wild\\.example\\..*NSEC z\\.example" dig.out.ns4.test$n > /dev/null || ret=1 277grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 278grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 279n=$((n+1)) 280test "$ret" -eq 0 || echo_i "failed" 281status=$((status+ret)) 282 283if [ -x ${DELV} ] ; then 284 ret=0 285 echo_i "checking positive wildcard validation NSEC using dns_client ($n)" 286 delv_with_opts @10.53.0.4 a a.wild.example > delv.out$n || ret=1 287 grep "a.wild.example..*10.0.0.27" delv.out$n > /dev/null || ret=1 288 grep -E "a.wild.example..*RRSIG.A [0-9]+ 2 300.*" delv.out$n > /dev/null || ret=1 289 n=$((n+1)) 290 test "$ret" -eq 0 || echo_i "failed" 291 status=$((status+ret)) 292fi 293 294echo_i "checking positive wildcard answer NSEC3 ($n)" 295ret=0 296dig_with_opts a.wild.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 297grep "AUTHORITY: 4," dig.out.ns3.test$n > /dev/null || ret=1 298grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 299n=$((n+1)) 300test "$ret" -eq 0 || echo_i "failed" 301status=$((status+ret)) 302 303echo_i "checking positive wildcard answer NSEC3 ($n)" 304ret=0 305dig_with_opts a.wild.nsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 306grep "AUTHORITY: 4," dig.out.ns4.test$n > /dev/null || ret=1 307grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 308n=$((n+1)) 309test "$ret" -eq 0 || echo_i "failed" 310status=$((status+ret)) 311 312echo_i "checking positive wildcard validation NSEC3 ($n)" 313ret=0 314dig_with_opts a.wild.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 315dig_with_opts a.wild.nsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 316stripns dig.out.ns3.test$n > dig.out.ns3.stripped.test$n 317stripns dig.out.ns4.test$n > dig.out.ns4.stripped.test$n 318digcomp dig.out.ns3.stripped.test$n dig.out.ns4.stripped.test$n || ret=1 319grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 320grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 321n=$((n+1)) 322test "$ret" -eq 0 || echo_i "failed" 323status=$((status+ret)) 324 325if [ -x ${DELV} ] ; then 326 ret=0 327 echo_i "checking positive wildcard validation NSEC3 using dns_client ($n)" 328 delv_with_opts @10.53.0.4 a a.wild.nsec3.example > delv.out$n || ret=1 329 grep -E "a.wild.nsec3.example..*10.0.0.6" delv.out$n > /dev/null || ret=1 330 grep -E "a.wild.nsec3.example..*RRSIG.A [0-9][0-9]* 3 300.*" delv.out$n > /dev/null || ret=1 331 n=$((n+1)) 332 test "$ret" -eq 0 || echo_i "failed" 333 status=$((status+ret)) 334fi 335 336echo_i "checking positive wildcard validation OPTOUT ($n)" 337ret=0 338dig_with_opts a.wild.optout.example. \ 339 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 340dig_with_opts a.wild.optout.example. \ 341 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 342stripns dig.out.ns3.test$n > dig.out.ns3.stripped.test$n 343stripns dig.out.ns4.test$n > dig.out.ns4.stripped.test$n 344digcomp dig.out.ns3.stripped.test$n dig.out.ns4.stripped.test$n || ret=1 345grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 346grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 347n=$((n+1)) 348test "$ret" -eq 0 || echo_i "failed" 349status=$((status+ret)) 350 351if [ -x ${DELV} ] ; then 352 ret=0 353 echo_i "checking positive wildcard validation OPTOUT using dns_client ($n)" 354 delv_with_opts @10.53.0.4 a a.wild.optout.example > delv.out$n || ret=1 355 grep "a.wild.optout.example..*10.0.0.6" delv.out$n > /dev/null || ret=1 356 grep "a.wild.optout.example..*RRSIG.A [0-9][0-9]* 3 300.*" delv.out$n > /dev/null || ret=1 357 n=$((n+1)) 358 test "$ret" -eq 0 || echo_i "failed" 359 status=$((status+ret)) 360fi 361 362echo_i "checking negative validation NXDOMAIN NSEC ($n)" 363ret=0 364dig_with_opts +noauth q.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 365dig_with_opts +noauth q.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 366digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 367grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 368grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 369n=$((n+1)) 370test "$ret" -eq 0 || echo_i "failed" 371status=$((status+ret)) 372 373if [ -x ${DELV} ] ; then 374 ret=0 375 echo_i "checking negative validation NXDOMAIN NSEC using dns_client ($n)" 376 delv_with_opts @10.53.0.4 a q.example > delv.out$n 2>&1 || ret=1 377 grep "resolution failed: ncache nxdomain" delv.out$n > /dev/null || ret=1 378 n=$((n+1)) 379 test "$ret" -eq 0 || echo_i "failed" 380 status=$((status+ret)) 381fi 382 383echo_i "checking negative validation NXDOMAIN NSEC3 ($n)" 384ret=0 385dig_with_opts +noauth q.nsec3.example. \ 386 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 387dig_with_opts +noauth q.nsec3.example. \ 388 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 389digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 390grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 391grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 392n=$((n+1)) 393test "$ret" -eq 0 || echo_i "failed" 394status=$((status+ret)) 395 396if [ -x ${DELV} ] ; then 397 ret=0 398 echo_i "checking negative validation NXDOMAIN NSEC3 using dns_client ($n)" 399 delv_with_opts @10.53.0.4 a q.nsec3.example > delv.out$n 2>&1 || ret=1 400 grep "resolution failed: ncache nxdomain" delv.out$n > /dev/null || ret=1 401 n=$((n+1)) 402 test "$ret" -eq 0 || echo_i "failed" 403 status=$((status+ret)) 404fi 405 406echo_i "checking negative validation NXDOMAIN OPTOUT ($n)" 407ret=0 408dig_with_opts +noauth q.optout.example. \ 409 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 410dig_with_opts +noauth q.optout.example. \ 411 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 412digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 413grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 414# Note - this is looking for failure, hence the && 415grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 416n=$((n+1)) 417test "$ret" -eq 0 || echo_i "failed" 418status=$((status+ret)) 419 420if [ -x ${DELV} ] ; then 421 ret=0 422 echo_i "checking negative validation NXDOMAIN OPTOUT using dns_client ($n)" 423 delv_with_opts @10.53.0.4 a q.optout.example > delv.out$n 2>&1 || ret=1 424 grep "resolution failed: ncache nxdomain" delv.out$n > /dev/null || ret=1 425 n=$((n+1)) 426 test "$ret" -eq 0 || echo_i "failed" 427 status=$((status+ret)) 428fi 429 430echo_i "checking negative validation NODATA NSEC ($n)" 431ret=0 432dig_with_opts +noauth a.example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1 433dig_with_opts +noauth a.example. @10.53.0.4 txt > dig.out.ns4.test$n || ret=1 434digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 435grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 436grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 437grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1 438n=$((n+1)) 439test "$ret" -eq 0 || echo_i "failed" 440status=$((status+ret)) 441 442if [ -x ${DELV} ] ; then 443 ret=0 444 echo_i "checking negative validation NODATA OPTOUT using dns_client ($n)" 445 delv_with_opts @10.53.0.4 txt a.example > delv.out$n 2>&1 || ret=1 446 grep "resolution failed: ncache nxrrset" delv.out$n > /dev/null || ret=1 447 n=$((n+1)) 448 test "$ret" -eq 0 || echo_i "failed" 449 status=$((status+ret)) 450fi 451 452echo_i "checking negative validation NODATA NSEC3 ($n)" 453ret=0 454dig_with_opts +noauth a.nsec3.example. \ 455 @10.53.0.3 txt > dig.out.ns3.test$n || ret=1 456dig_with_opts +noauth a.nsec3.example. \ 457 @10.53.0.4 txt > dig.out.ns4.test$n || ret=1 458digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 459grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 460grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 461grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1 462n=$((n+1)) 463test "$ret" -eq 0 || echo_i "failed" 464status=$((status+ret)) 465 466if [ -x ${DELV} ] ; then 467 ret=0 468 echo_i "checking negative validation NODATA NSEC3 using dns_client ($n)" 469 delv_with_opts @10.53.0.4 txt a.nsec3.example > delv.out$n 2>&1 || ret=1 470 grep "resolution failed: ncache nxrrset" delv.out$n > /dev/null || ret=1 471 n=$((n+1)) 472 test "$ret" -eq 0 || echo_i "failed" 473 status=$((status+ret)) 474fi 475 476echo_i "checking negative validation NODATA OPTOUT ($n)" 477ret=0 478dig_with_opts +noauth a.optout.example. \ 479 @10.53.0.3 txt > dig.out.ns3.test$n || ret=1 480dig_with_opts +noauth a.optout.example. \ 481 @10.53.0.4 txt > dig.out.ns4.test$n || ret=1 482digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 483grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 484grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 485grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1 486n=$((n+1)) 487test "$ret" -eq 0 || echo_i "failed" 488status=$((status+ret)) 489 490if [ -x ${DELV} ] ; then 491 ret=0 492 echo_i "checking negative validation NODATA OPTOUT using dns_client ($n)" 493 delv_with_opts @10.53.0.4 txt a.optout.example > delv.out$n 2>&1 || ret=1 494 grep "resolution failed: ncache nxrrset" delv.out$n > /dev/null || ret=1 495 n=$((n+1)) 496 test "$ret" -eq 0 || echo_i "failed" 497 status=$((status+ret)) 498fi 499 500echo_i "checking negative wildcard validation NSEC ($n)" 501ret=0 502dig_with_opts b.wild.example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1 503dig_with_opts b.wild.example. @10.53.0.4 txt > dig.out.ns4.test$n || ret=1 504digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 505grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 506grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 507n=$((n+1)) 508test "$ret" -eq 0 || echo_i "failed" 509status=$((status+ret)) 510 511if [ -x ${DELV} ] ; then 512 ret=0 513 echo_i "checking negative wildcard validation NSEC using dns_client ($n)" 514 delv_with_opts @10.53.0.4 txt b.wild.example > delv.out$n 2>&1 || ret=1 515 grep "resolution failed: ncache nxrrset" delv.out$n > /dev/null || ret=1 516 n=$((n+1)) 517 test "$ret" -eq 0 || echo_i "failed" 518 status=$((status+ret)) 519fi 520 521echo_i "checking negative wildcard validation NSEC3 ($n)" 522ret=0 523dig_with_opts b.wild.nsec3.example. @10.53.0.3 txt > dig.out.ns3.test$n || ret=1 524dig_with_opts b.wild.nsec3.example. @10.53.0.4 txt > dig.out.ns4.test$n || ret=1 525digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 526grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 527n=$((n+1)) 528test "$ret" -eq 0 || echo_i "failed" 529status=$((status+ret)) 530 531if [ -x ${DELV} ] ; then 532 ret=0 533 echo_i "checking negative wildcard validation NSEC3 using dns_client ($n)" 534 delv_with_opts @10.53.0.4 txt b.wild.nsec3.example > delv.out$n 2>&1 || ret=1 535 grep "resolution failed: ncache nxrrset" delv.out$n > /dev/null || ret=1 536 n=$((n+1)) 537 test "$ret" -eq 0 || echo_i "failed" 538 status=$((status+ret)) 539fi 540 541echo_i "checking negative wildcard validation OPTOUT ($n)" 542ret=0 543dig_with_opts b.wild.optout.example. \ 544 @10.53.0.3 txt > dig.out.ns3.test$n || ret=1 545dig_with_opts b.wild.optout.example. \ 546 @10.53.0.4 txt > dig.out.ns4.test$n || ret=1 547digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 548grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 549# Note - this is looking for failure, hence the && 550grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 551n=$((n+1)) 552test "$ret" -eq 0 || echo_i "failed" 553status=$((status+ret)) 554 555if [ -x ${DELV} ] ; then 556 ret=0 557 echo_i "checking negative wildcard validation OPTOUT using dns_client ($n)" 558 delv_with_opts @10.53.0.4 txt b.optout.nsec3.example > delv.out$n 2>&1 || ret=1 559 grep "resolution failed: ncache nxrrset" delv.out$n > /dev/null || ret=1 560 n=$((n+1)) 561 test "$ret" -eq 0 || echo_i "failed" 562 status=$((status+ret)) 563fi 564 565# Check the insecure.example domain 566 567echo_i "checking 1-server insecurity proof NSEC ($n)" 568ret=0 569dig_with_opts +noauth a.insecure.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 570dig_with_opts +noauth a.insecure.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 571digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 572grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 573# Note - this is looking for failure, hence the && 574grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 575n=$((n+1)) 576test "$ret" -eq 0 || echo_i "failed" 577status=$((status+ret)) 578 579if [ -x ${DELV} ] ; then 580 ret=0 581 echo_i "checking 1-server insecurity proof NSEC using dns_client ($n)" 582 delv_with_opts @10.53.0.4 a a.insecure.example > delv.out$n || ret=1 583 grep "a.insecure.example..*10.0.0.1" delv.out$n > /dev/null || ret=1 584 n=$((n+1)) 585 test "$ret" -eq 0 || echo_i "failed" 586 status=$((status+ret)) 587fi 588 589echo_i "checking 1-server insecurity proof NSEC3 ($n)" 590ret=0 591dig_with_opts +noauth a.insecure.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 592dig_with_opts +noauth a.insecure.nsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 593digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 594grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 595# Note - this is looking for failure, hence the && 596grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 597n=$((n+1)) 598test "$ret" -eq 0 || echo_i "failed" 599status=$((status+ret)) 600 601if [ -x ${DELV} ] ; then 602 ret=0 603 echo_i "checking 1-server insecurity proof NSEC3 using dns_client ($n)" 604 delv_with_opts @10.53.0.4 a a.insecure.nsec3.example > delv.out$n || ret=1 605 grep "a.insecure.nsec3.example..*10.0.0.1" delv.out$n > /dev/null || ret=1 606 n=$((n+1)) 607 test "$ret" -eq 0 || echo_i "failed" 608 status=$((status+ret)) 609fi 610 611echo_i "checking 1-server insecurity proof OPTOUT ($n)" 612ret=0 613dig_with_opts +noauth a.insecure.optout.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 614dig_with_opts +noauth a.insecure.optout.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 615digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 616grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 617# Note - this is looking for failure, hence the && 618grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 619n=$((n+1)) 620test "$ret" -eq 0 || echo_i "failed" 621status=$((status+ret)) 622 623if [ -x ${DELV} ] ; then 624 ret=0 625 echo_i "checking 1-server insecurity proof OPTOUT using dns_client ($n)" 626 delv_with_opts @10.53.0.4 a a.insecure.optout.example > delv.out$n || ret=1 627 grep "a.insecure.optout.example..*10.0.0.1" delv.out$n > /dev/null || ret=1 628 n=$((n+1)) 629 test "$ret" -eq 0 || echo_i "failed" 630 status=$((status+ret)) 631fi 632 633echo_i "checking 1-server negative insecurity proof NSEC ($n)" 634ret=0 635dig_with_opts q.insecure.example. a @10.53.0.3 \ 636 > dig.out.ns3.test$n || ret=1 637dig_with_opts q.insecure.example. a @10.53.0.4 \ 638 > dig.out.ns4.test$n || ret=1 639digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 640grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 641# Note - this is looking for failure, hence the && 642grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 643n=$((n+1)) 644test "$ret" -eq 0 || echo_i "failed" 645status=$((status+ret)) 646 647if [ -x ${DELV} ] ; then 648 ret=0 649 echo_i "checking 1-server negative insecurity proof NSEC using dns_client ($n)" 650 delv_with_opts @10.53.0.4 a q.insecure.example > delv.out$n 2>&1 || ret=1 651 grep "resolution failed: ncache nxdomain" delv.out$n > /dev/null || ret=1 652 n=$((n+1)) 653 test "$ret" -eq 0 || echo_i "failed" 654 status=$((status+ret)) 655fi 656 657echo_i "checking 1-server negative insecurity proof NSEC3 ($n)" 658ret=0 659dig_with_opts q.insecure.nsec3.example. a @10.53.0.3 \ 660 > dig.out.ns3.test$n || ret=1 661dig_with_opts q.insecure.nsec3.example. a @10.53.0.4 \ 662 > dig.out.ns4.test$n || ret=1 663digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 664grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 665# Note - this is looking for failure, hence the && 666grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 667n=$((n+1)) 668test "$ret" -eq 0 || echo_i "failed" 669status=$((status+ret)) 670 671if [ -x ${DELV} ] ; then 672 ret=0 673 echo_i "checking 1-server negative insecurity proof NSEC3 using dns_client ($n)" 674 delv_with_opts @10.53.0.4 a q.insecure.nsec3.example > delv.out$n 2>&1 || ret=1 675 grep "resolution failed: ncache nxdomain" delv.out$n > /dev/null || ret=1 676 n=$((n+1)) 677 test "$ret" -eq 0 || echo_i "failed" 678 status=$((status+ret)) 679fi 680 681echo_i "checking 1-server negative insecurity proof OPTOUT ($n)" 682ret=0 683dig_with_opts q.insecure.optout.example. a @10.53.0.3 \ 684 > dig.out.ns3.test$n || ret=1 685dig_with_opts q.insecure.optout.example. a @10.53.0.4 \ 686 > dig.out.ns4.test$n || ret=1 687digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 688grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 689# Note - this is looking for failure, hence the && 690grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 691n=$((n+1)) 692test "$ret" -eq 0 || echo_i "failed" 693status=$((status+ret)) 694 695if [ -x ${DELV} ] ; then 696 ret=0 697 echo_i "checking 1-server negative insecurity proof OPTOUT using dns_client ($n)" 698 delv_with_opts @10.53.0.4 a q.insecure.optout.example > delv.out$n 2>&1 || ret=1 699 grep "resolution failed: ncache nxdomain" delv.out$n > /dev/null || ret=1 700 n=$((n+1)) 701 test "$ret" -eq 0 || echo_i "failed" 702 status=$((status+ret)) 703fi 704 705echo_i "checking 1-server negative insecurity proof with SOA hack NSEC ($n)" 706ret=0 707dig_with_opts r.insecure.example. soa @10.53.0.3 \ 708 > dig.out.ns3.test$n || ret=1 709dig_with_opts r.insecure.example. soa @10.53.0.4 \ 710 > dig.out.ns4.test$n || ret=1 711digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 712grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 713grep "0 IN SOA" dig.out.ns4.test$n > /dev/null || ret=1 714# Note - this is looking for failure, hence the && 715grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 716n=$((n+1)) 717test "$ret" -eq 0 || echo_i "failed" 718status=$((status+ret)) 719 720echo_i "checking 1-server negative insecurity proof with SOA hack NSEC3 ($n)" 721ret=0 722dig_with_opts r.insecure.nsec3.example. soa @10.53.0.3 \ 723 > dig.out.ns3.test$n || ret=1 724dig_with_opts r.insecure.nsec3.example. soa @10.53.0.4 \ 725 > dig.out.ns4.test$n || ret=1 726digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 727grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 728grep "0 IN SOA" dig.out.ns4.test$n > /dev/null || ret=1 729# Note - this is looking for failure, hence the && 730grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 731n=$((n+1)) 732test "$ret" -eq 0 || echo_i "failed" 733status=$((status+ret)) 734 735echo_i "checking 1-server negative insecurity proof with SOA hack OPTOUT ($n)" 736ret=0 737dig_with_opts r.insecure.optout.example. soa @10.53.0.3 \ 738 > dig.out.ns3.test$n || ret=1 739dig_with_opts r.insecure.optout.example. soa @10.53.0.4 \ 740 > dig.out.ns4.test$n || ret=1 741digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 742grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 743grep "0 IN SOA" dig.out.ns4.test$n > /dev/null || ret=1 744# Note - this is looking for failure, hence the && 745grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 746n=$((n+1)) 747test "$ret" -eq 0 || echo_i "failed" 748status=$((status+ret)) 749 750# Check the secure.example domain 751 752echo_i "checking multi-stage positive validation NSEC/NSEC ($n)" 753ret=0 754dig_with_opts +noauth a.secure.example. \ 755 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 756dig_with_opts +noauth a.secure.example. \ 757 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 758digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 759grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 760grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 761n=$((n+1)) 762test "$ret" -eq 0 || echo_i "failed" 763status=$((status+ret)) 764 765echo_i "checking multi-stage positive validation NSEC/NSEC3 ($n)" 766ret=0 767dig_with_opts +noauth a.nsec3.example. \ 768 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 769dig_with_opts +noauth a.nsec3.example. \ 770 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 771digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 772grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 773grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 774n=$((n+1)) 775test "$ret" -eq 0 || echo_i "failed" 776status=$((status+ret)) 777 778echo_i "checking multi-stage positive validation NSEC/OPTOUT ($n)" 779ret=0 780dig_with_opts +noauth a.optout.example. \ 781 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 782dig_with_opts +noauth a.optout.example. \ 783 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 784digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 785grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 786grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 787n=$((n+1)) 788test "$ret" -eq 0 || echo_i "failed" 789status=$((status+ret)) 790 791echo_i "checking multi-stage positive validation NSEC3/NSEC ($n)" 792ret=0 793dig_with_opts +noauth a.secure.nsec3.example. \ 794 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 795dig_with_opts +noauth a.secure.nsec3.example. \ 796 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 797digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 798grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 799grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 800n=$((n+1)) 801test "$ret" -eq 0 || echo_i "failed" 802status=$((status+ret)) 803 804echo_i "checking multi-stage positive validation NSEC3/NSEC3 ($n)" 805ret=0 806dig_with_opts +noauth a.nsec3.nsec3.example. \ 807 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 808dig_with_opts +noauth a.nsec3.nsec3.example. \ 809 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 810digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 811grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 812grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 813n=$((n+1)) 814test "$ret" -eq 0 || echo_i "failed" 815status=$((status+ret)) 816 817echo_i "checking multi-stage positive validation NSEC3/OPTOUT ($n)" 818ret=0 819dig_with_opts +noauth a.optout.nsec3.example. \ 820 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 821dig_with_opts +noauth a.optout.nsec3.example. \ 822 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 823digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 824grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 825grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 826n=$((n+1)) 827test "$ret" -eq 0 || echo_i "failed" 828status=$((status+ret)) 829 830echo_i "checking multi-stage positive validation OPTOUT/NSEC ($n)" 831ret=0 832dig_with_opts +noauth a.secure.optout.example. \ 833 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 834dig_with_opts +noauth a.secure.optout.example. \ 835 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 836digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 837grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 838grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 839n=$((n+1)) 840test "$ret" -eq 0 || echo_i "failed" 841status=$((status+ret)) 842 843echo_i "checking multi-stage positive validation OPTOUT/NSEC3 ($n)" 844ret=0 845dig_with_opts +noauth a.nsec3.optout.example. \ 846 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 847dig_with_opts +noauth a.nsec3.optout.example. \ 848 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 849digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 850grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 851grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 852n=$((n+1)) 853test "$ret" -eq 0 || echo_i "failed" 854status=$((status+ret)) 855 856echo_i "checking multi-stage positive validation OPTOUT/OPTOUT ($n)" 857ret=0 858dig_with_opts +noauth a.optout.optout.example. \ 859 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 860dig_with_opts +noauth a.optout.optout.example. \ 861 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 862digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 863grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 864grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 865n=$((n+1)) 866test "$ret" -eq 0 || echo_i "failed" 867status=$((status+ret)) 868 869echo_i "checking empty NODATA OPTOUT ($n)" 870ret=0 871dig_with_opts +noauth empty.optout.example. \ 872 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 873dig_with_opts +noauth empty.optout.example. \ 874 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 875digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 876grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 877#grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 878n=$((n+1)) 879test "$ret" -eq 0 || echo_i "failed" 880status=$((status+ret)) 881 882# Check the bogus domain 883 884echo_i "checking failed validation ($n)" 885ret=0 886dig_with_opts a.bogus.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 887grep "SERVFAIL" dig.out.ns4.test$n > /dev/null || ret=1 888n=$((n+1)) 889test "$ret" -eq 0 || echo_i "failed" 890status=$((status+ret)) 891 892if [ -x ${DELV} ] ; then 893 ret=0 894 echo_i "checking failed validation using dns_client ($n)" 895 delv_with_opts +cd @10.53.0.4 a a.bogus.example > delv.out$n 2>&1 || ret=1 896 grep "resolution failed: RRSIG failed to verify" delv.out$n > /dev/null || ret=1 897 n=$((n+1)) 898 test "$ret" -eq 0 || echo_i "failed" 899 status=$((status+ret)) 900fi 901 902# Try validating with a bad trusted key. 903# This should fail. 904 905echo_i "checking that validation fails with a misconfigured trusted key ($n)" 906ret=0 907dig_with_opts example. soa @10.53.0.5 > dig.out.ns5.test$n || ret=1 908grep "SERVFAIL" dig.out.ns5.test$n > /dev/null || ret=1 909n=$((n+1)) 910test "$ret" -eq 0 || echo_i "failed" 911status=$((status+ret)) 912 913echo_i "checking that negative validation fails with a misconfigured trusted key ($n)" 914ret=0 915dig_with_opts example. ptr @10.53.0.5 > dig.out.ns5.test$n || ret=1 916grep "SERVFAIL" dig.out.ns5.test$n > /dev/null || ret=1 917n=$((n+1)) 918test "$ret" -eq 0 || echo_i "failed" 919status=$((status+ret)) 920 921echo_i "checking that insecurity proofs fail with a misconfigured trusted key ($n)" 922ret=0 923dig_with_opts a.insecure.example. a @10.53.0.5 > dig.out.ns5.test$n || ret=1 924grep "SERVFAIL" dig.out.ns5.test$n > /dev/null || ret=1 925n=$((n+1)) 926test "$ret" -eq 0 || echo_i "failed" 927status=$((status+ret)) 928 929echo_i "checking that validation fails when key record is missing ($n)" 930ret=0 931dig_with_opts a.b.keyless.example. a @10.53.0.4 > dig.out.ns4.test$n || ret=1 932grep "SERVFAIL" dig.out.ns4.test$n > /dev/null || ret=1 933n=$((n+1)) 934test "$ret" -eq 0 || echo_i "failed" 935status=$((status+ret)) 936 937if [ -x ${DELV} ] ; then 938 ret=0 939 echo_i "checking that validation fails when key record is missing using dns_client ($n)" 940 delv_with_opts +cd @10.53.0.4 a a.b.keyless.example > delv.out$n 2>&1 || ret=1 941 grep "resolution failed: broken trust chain" delv.out$n > /dev/null || ret=1 942 n=$((n+1)) 943 test "$ret" -eq 0 || echo_i "failed" 944 status=$((status+ret)) 945fi 946 947echo_i "checking that validation succeeds when a revoked key is encountered ($n)" 948ret=0 949dig_with_opts revkey.example soa @10.53.0.4 > dig.out.ns4.test$n || ret=1 950grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 951grep "flags: .* ad" dig.out.ns4.test$n > /dev/null || ret=1 952n=$((n+1)) 953test "$ret" -eq 0 || echo_i "failed" 954status=$((status+ret)) 955 956if [ -x ${DELV} ] ; then 957 ret=0 958 echo_i "checking that validation succeeds when a revoked key is encountered using dns_client ($n)" 959 delv_with_opts +cd @10.53.0.4 soa revkey.example > delv.out$n 2>&1 || ret=1 960 grep "fully validated" delv.out$n > /dev/null || ret=1 961 n=$((n+1)) 962 test "$ret" -eq 0 || echo_i "failed" 963 status=$((status+ret)) 964fi 965 966echo_i "Checking that a bad CNAME signature is caught after a +CD query ($n)" 967ret=0 968#prime 969dig_with_opts +cd bad-cname.example. @10.53.0.4 > dig.out.ns4.prime$n || ret=1 970#check: requery with +CD. pending data should be returned even if it's bogus 971expect="a.example. 97210.0.0.1" 973ans=$(dig_with_opts +cd +nodnssec +short bad-cname.example. @10.53.0.4) || ret=1 974test "$ans" = "$expect" || ret=1 975test "$ret" -eq 0 || echo_i "failed, got '$ans', expected '$expect'" 976#check: requery without +CD. bogus cached data should be rejected. 977dig_with_opts +nodnssec bad-cname.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 978grep "SERVFAIL" dig.out.ns4.test$n > /dev/null || ret=1 979n=$((n+1)) 980test "$ret" -eq 0 || echo_i "failed" 981status=$((status+ret)) 982 983echo_i "Checking that a bad DNAME signature is caught after a +CD query ($n)" 984ret=0 985#prime 986dig_with_opts +cd a.bad-dname.example. @10.53.0.4 > dig.out.ns4.prime$n || ret=1 987#check: requery with +CD. pending data should be returned even if it's bogus 988expect="example. 989a.example. 99010.0.0.1" 991ans=$(dig_with_opts +cd +nodnssec +short a.bad-dname.example. @10.53.0.4) || ret=1 992test "$ans" = "$expect" || ret=1 993test "$ret" -eq 0 || echo_i "failed, got '$ans', expected '$expect'" 994#check: requery without +CD. bogus cached data should be rejected. 995dig_with_opts +nodnssec a.bad-dname.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 996grep "SERVFAIL" dig.out.ns4.test$n > /dev/null || ret=1 997n=$((n+1)) 998test "$ret" -eq 0 || echo_i "failed" 999status=$((status+ret)) 1000 1001# Check the insecure.secure.example domain (insecurity proof) 1002 1003echo_i "checking 2-server insecurity proof ($n)" 1004ret=0 1005dig_with_opts +noauth a.insecure.secure.example. @10.53.0.2 a \ 1006 > dig.out.ns2.test$n || ret=1 1007dig_with_opts +noauth a.insecure.secure.example. @10.53.0.4 a \ 1008 > dig.out.ns4.test$n || ret=1 1009digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 1010grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 1011# Note - this is looking for failure, hence the && 1012grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 1013n=$((n+1)) 1014test "$ret" -eq 0 || echo_i "failed" 1015status=$((status+ret)) 1016 1017# Check a negative response in insecure.secure.example 1018 1019echo_i "checking 2-server insecurity proof with a negative answer ($n)" 1020ret=0 1021dig_with_opts q.insecure.secure.example. @10.53.0.2 a > dig.out.ns2.test$n \ 1022 || ret=1 1023dig_with_opts q.insecure.secure.example. @10.53.0.4 a > dig.out.ns4.test$n \ 1024 || ret=1 1025digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 1026grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 1027# Note - this is looking for failure, hence the && 1028grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 1029n=$((n+1)) 1030test "$ret" -eq 0 || echo_i "failed" 1031status=$((status+ret)) 1032 1033echo_i "checking 2-server insecurity proof with a negative answer and SOA hack ($n)" 1034ret=0 1035dig_with_opts r.insecure.secure.example. @10.53.0.2 soa > dig.out.ns2.test$n \ 1036 || ret=1 1037dig_with_opts r.insecure.secure.example. @10.53.0.4 soa > dig.out.ns4.test$n \ 1038 || ret=1 1039digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 1040grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 1041# Note - this is looking for failure, hence the && 1042grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 1043n=$((n+1)) 1044test "$ret" -eq 0 || echo_i "failed" 1045status=$((status+ret)) 1046 1047# Check that the query for a security root is successful and has ad set 1048 1049echo_i "checking security root query ($n)" 1050ret=0 1051dig_with_opts . @10.53.0.4 key > dig.out.ns4.test$n || ret=1 1052grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 1053grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 1054n=$((n+1)) 1055test "$ret" -eq 0 || echo_i "failed" 1056status=$((status+ret)) 1057 1058# Check that the setting the cd bit works 1059 1060echo_i "checking cd bit on a positive answer ($n)" 1061ret=0 1062dig_with_opts +noauth example. soa @10.53.0.4 \ 1063 > dig.out.ns4.test$n || ret=1 1064dig_with_opts +noauth +cdflag example. soa @10.53.0.5 \ 1065 > dig.out.ns5.test$n || ret=1 1066digcomp dig.out.ns4.test$n dig.out.ns5.test$n || ret=1 1067grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 1068# Note - this is looking for failure, hence the && 1069grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null && ret=1 1070n=$((n+1)) 1071test "$ret" -eq 0 || echo_i "failed" 1072status=$((status+ret)) 1073 1074echo_i "checking cd bit on a negative answer ($n)" 1075ret=0 1076dig_with_opts q.example. soa @10.53.0.4 > dig.out.ns4.test$n || ret=1 1077dig_with_opts +cdflag q.example. soa @10.53.0.5 > dig.out.ns5.test$n || ret=1 1078digcomp dig.out.ns4.test$n dig.out.ns5.test$n || ret=1 1079grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 1080# Note - this is looking for failure, hence the && 1081grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null && ret=1 1082n=$((n+1)) 1083test "$ret" -eq 0 || echo_i "failed" 1084status=$((status+ret)) 1085 1086echo_i "checking insecurity proof works using negative cache ($n)" 1087ret=0 1088rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i 1089dig_with_opts +cd @10.53.0.4 insecure.example. ds > dig.out.ns4.test$n.1 || ret=1 1090for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 1091do 1092 dig_with_opts @10.53.0.4 nonexistent.insecure.example. > dig.out.ns4.test$n.2 || ret=1 1093 if grep "status: NXDOMAIN" dig.out.ns4.test$n.2 >/dev/null; then 1094 break 1095 fi 1096 sleep 1 1097done 1098grep "status: NXDOMAIN" dig.out.ns4.test$n.2 >/dev/null || ret=1 1099n=$((n+1)) 1100test "$ret" -eq 0 || echo_i "failed" 1101status=$((status+ret)) 1102 1103echo_i "checking positive validation RSASHA256 NSEC ($n)" 1104ret=0 1105dig_with_opts +noauth a.rsasha256.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 1106dig_with_opts +noauth a.rsasha256.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 1107digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 1108grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 1109n=$((n+1)) 1110test "$ret" -eq 0 || echo_i "failed" 1111status=$((status+ret)) 1112 1113echo_i "checking positive validation RSASHA512 NSEC ($n)" 1114ret=0 1115dig_with_opts +noauth a.rsasha512.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 1116dig_with_opts +noauth a.rsasha512.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 1117digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 1118grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 1119n=$((n+1)) 1120test "$ret" -eq 0 || echo_i "failed" 1121status=$((status+ret)) 1122 1123echo_i "checking positive validation with KSK-only DNSKEY signature ($n)" 1124ret=0 1125dig_with_opts +noauth a.kskonly.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 1126dig_with_opts +noauth a.kskonly.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 1127digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 1128grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 1129n=$((n+1)) 1130test "$ret" -eq 0 || echo_i "failed" 1131status=$((status+ret)) 1132 1133echo_i "checking cd bit on a query that should fail ($n)" 1134ret=0 1135dig_with_opts a.bogus.example. soa @10.53.0.4 \ 1136 > dig.out.ns4.test$n || ret=1 1137dig_with_opts +cdflag a.bogus.example. soa @10.53.0.5 \ 1138 > dig.out.ns5.test$n || ret=1 1139digcomp dig.out.ns4.test$n dig.out.ns5.test$n || ret=1 1140grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 1141# Note - this is looking for failure, hence the && 1142grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null && ret=1 1143n=$((n+1)) 1144test "$ret" -eq 0 || echo_i "failed" 1145status=$((status+ret)) 1146 1147echo_i "checking cd bit on an insecurity proof ($n)" 1148ret=0 1149dig_with_opts +noauth a.insecure.example. soa @10.53.0.4 \ 1150 > dig.out.ns4.test$n || ret=1 1151dig_with_opts +noauth +cdflag a.insecure.example. soa @10.53.0.5 \ 1152 > dig.out.ns5.test$n || ret=1 1153digcomp dig.out.ns4.test$n dig.out.ns5.test$n || ret=1 1154grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 1155# Note - these are looking for failure, hence the && 1156grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 1157grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null && ret=1 1158n=$((n+1)) 1159test "$ret" -eq 0 || echo_i "failed" 1160status=$((status+ret)) 1161 1162echo_i "checking cd bit on a negative insecurity proof ($n)" 1163ret=0 1164dig_with_opts q.insecure.example. a @10.53.0.4 \ 1165 > dig.out.ns4.test$n || ret=1 1166dig_with_opts +cdflag q.insecure.example. a @10.53.0.5 \ 1167 > dig.out.ns5.test$n || ret=1 1168digcomp dig.out.ns4.test$n dig.out.ns5.test$n || ret=1 1169grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 1170# Note - these are looking for failure, hence the && 1171grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 1172grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null && ret=1 1173n=$((n+1)) 1174test "$ret" -eq 0 || echo_i "failed" 1175status=$((status+ret)) 1176 1177echo_i "checking that validation of an ANY query works ($n)" 1178ret=0 1179dig_with_opts +noauth foo.example. any @10.53.0.2 > dig.out.ns2.test$n || ret=1 1180dig_with_opts +noauth foo.example. any @10.53.0.4 > dig.out.ns4.test$n || ret=1 1181digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 1182grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 1183# 2 records in the zone, 1 NXT, 3 SIGs 1184grep "ANSWER: 6" dig.out.ns4.test$n > /dev/null || ret=1 1185n=$((n+1)) 1186test "$ret" -eq 0 || echo_i "failed" 1187status=$((status+ret)) 1188 1189echo_i "checking that validation of a query returning a CNAME works ($n)" 1190ret=0 1191dig_with_opts +noauth cname1.example. txt @10.53.0.2 \ 1192 > dig.out.ns2.test$n || ret=1 1193dig_with_opts +noauth cname1.example. txt @10.53.0.4 \ 1194 > dig.out.ns4.test$n || ret=1 1195digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 1196grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 1197# the CNAME & its sig, the TXT and its SIG 1198grep "ANSWER: 4" dig.out.ns4.test$n > /dev/null || ret=1 1199n=$((n+1)) 1200test "$ret" -eq 0 || echo_i "failed" 1201status=$((status+ret)) 1202 1203echo_i "checking that validation of a query returning a DNAME works ($n)" 1204ret=0 1205dig_with_opts +noauth foo.dname1.example. txt @10.53.0.2 \ 1206 > dig.out.ns2.test$n || ret=1 1207dig_with_opts +noauth foo.dname1.example. txt @10.53.0.4 \ 1208 > dig.out.ns4.test$n || ret=1 1209digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 1210grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 1211# The DNAME & its sig, the TXT and its SIG, and the synthesized CNAME. 1212# It would be nice to test that the CNAME is being synthesized by the 1213# recursive server and not cached, but I don't know how. 1214grep "ANSWER: 5" dig.out.ns4.test$n > /dev/null || ret=1 1215n=$((n+1)) 1216test "$ret" -eq 0 || echo_i "failed" 1217status=$((status+ret)) 1218 1219echo_i "checking that validation of an ANY query returning a CNAME works ($n)" 1220ret=0 1221dig_with_opts +noauth cname2.example. any @10.53.0.2 \ 1222 > dig.out.ns2.test$n || ret=1 1223dig_with_opts +noauth cname2.example. any @10.53.0.4 \ 1224 > dig.out.ns4.test$n || ret=1 1225digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 1226grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 1227# The CNAME, NXT, and their SIGs 1228grep "ANSWER: 4" dig.out.ns4.test$n > /dev/null || ret=1 1229n=$((n+1)) 1230test "$ret" -eq 0 || echo_i "failed" 1231status=$((status+ret)) 1232 1233echo_i "checking that validation of an ANY query returning a DNAME works ($n)" 1234ret=0 1235dig_with_opts +noauth foo.dname2.example. any @10.53.0.2 \ 1236 > dig.out.ns2.test$n || ret=1 1237dig_with_opts +noauth foo.dname2.example. any @10.53.0.4 \ 1238 > dig.out.ns4.test$n || ret=1 1239digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 1240grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 1241n=$((n+1)) 1242test "$ret" -eq 0 || echo_i "failed" 1243status=$((status+ret)) 1244 1245echo_i "checking that lookups succeed after disabling an algorithm ($n)" 1246ret=0 1247dig_with_opts +noauth example. SOA @10.53.0.2 \ 1248 > dig.out.ns2.test$n || ret=1 1249dig_with_opts +noauth example. SOA @10.53.0.6 \ 1250 > dig.out.ns6.test$n || ret=1 1251digcomp dig.out.ns2.test$n dig.out.ns6.test$n || ret=1 1252# Note - this is looking for failure, hence the && 1253grep "flags:.*ad.*QUERY" dig.out.ns6.test$n > /dev/null && ret=1 1254n=$((n+1)) 1255test "$ret" -eq 0 || echo_i "failed" 1256status=$((status+ret)) 1257 1258echo_i "checking a non-cachable NODATA works ($n)" 1259ret=0 1260dig_with_opts +noauth a.nosoa.secure.example. txt @10.53.0.7 \ 1261 > dig.out.ns7.test$n || ret=1 1262grep "AUTHORITY: 0" dig.out.ns7.test$n > /dev/null || ret=1 1263dig_with_opts +noauth a.nosoa.secure.example. txt @10.53.0.4 \ 1264 > dig.out.ns4.test$n || ret=1 1265grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 1266n=$((n+1)) 1267test "$ret" -eq 0 || echo_i "failed" 1268status=$((status+ret)) 1269 1270echo_i "checking a non-cachable NXDOMAIN works ($n)" 1271ret=0 1272dig_with_opts +noauth b.nosoa.secure.example. txt @10.53.0.7 \ 1273 > dig.out.ns7.test$n || ret=1 1274grep "AUTHORITY: 0" dig.out.ns7.test$n > /dev/null || ret=1 1275dig_with_opts +noauth b.nosoa.secure.example. txt @10.53.0.4 \ 1276 > dig.out.ns4.test$n || ret=1 1277grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 1278n=$((n+1)) 1279test "$ret" -eq 0 || echo_i "failed" 1280status=$((status+ret)) 1281 1282echo_i "checking that we can load a rfc2535 signed zone ($n)" 1283ret=0 1284dig_with_opts rfc2535.example. SOA @10.53.0.2 \ 1285 > dig.out.ns2.test$n || ret=1 1286grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 1287n=$((n+1)) 1288test "$ret" -eq 0 || echo_i "failed" 1289status=$((status+ret)) 1290 1291echo_i "checking that we can transfer a rfc2535 signed zone ($n)" 1292ret=0 1293dig_with_opts rfc2535.example. SOA @10.53.0.3 \ 1294 > dig.out.ns3.test$n || ret=1 1295grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 1296n=$((n+1)) 1297test "$ret" -eq 0 || echo_i "failed" 1298status=$((status+ret)) 1299 1300echo_i "basic dnssec-signzone checks:" 1301echo_ic "two DNSKEYs ($n)" 1302ret=0 1303( 1304cd signer/general || exit 1 1305rm -f signed.zone 1306$SIGNER -f signed.zone -o example.com. test1.zone > signer.out.$n 1307test -f signed.zone 1308) || ret=1 1309n=$((n+1)) 1310test "$ret" -eq 0 || echo_i "failed" 1311status=$((status+ret)) 1312 1313echo_ic "one non-KSK DNSKEY ($n)" 1314ret=0 1315( 1316cd signer/general || exit 1 1317rm -f signed.zone 1318$SIGNER -f signed.zone -o example.com. test2.zone > signer.out.$n 1319test -f signed.zone 1320) && ret=1 1321n=$((n+1)) 1322test "$ret" -eq 0 || echo_i "failed" 1323status=$((status+ret)) 1324 1325echo_ic "one KSK DNSKEY ($n)" 1326ret=0 1327( 1328cd signer/general || exit 1 1329rm -f signed.zone 1330$SIGNER -f signed.zone -o example.com. test3.zone > signer.out.$n 1331test -f signed.zone 1332) && ret=1 1333n=$((n+1)) 1334test "$ret" -eq 0 || echo_i "failed" 1335status=$((status+ret)) 1336 1337echo_ic "three DNSKEY ($n)" 1338ret=0 1339( 1340cd signer/general || exit 1 1341rm -f signed.zone 1342$SIGNER -f signed.zone -o example.com. test4.zone > signer.out.$n 1343test -f signed.zone 1344) || ret=1 1345n=$((n+1)) 1346test "$ret" -eq 0 || echo_i "failed" 1347status=$((status+ret)) 1348 1349echo_ic "three DNSKEY, one private key missing ($n)" 1350ret=0 1351( 1352cd signer/general || exit 1 1353rm -f signed.zone 1354$SIGNER -f signed.zone -o example.com. test5.zone > signer.out.$n 1355test -f signed.zone 1356) || ret=1 1357n=$((n+1)) 1358test "$ret" -eq 0 || echo_i "failed" 1359status=$((status+ret)) 1360 1361echo_ic "four DNSKEY ($n)" 1362ret=0 1363( 1364cd signer/general || exit 1 1365rm -f signed.zone 1366$SIGNER -f signed.zone -o example.com. test6.zone > signer.out.$n 1367test -f signed.zone 1368) || ret=1 1369n=$((n+1)) 1370test "$ret" -eq 0 || echo_i "failed" 1371status=$((status+ret)) 1372 1373echo_ic "two DNSKEY, both private keys missing ($n)" 1374ret=0 1375( 1376cd signer/general || exit 1 1377rm -f signed.zone 1378$SIGNER -f signed.zone -o example.com. test7.zone > signer.out.$n 1379test -f signed.zone 1380) && ret=1 1381n=$((n+1)) 1382test "$ret" -eq 0 || echo_i "failed" 1383status=$((status+ret)) 1384 1385echo_ic "two DNSKEY, one private key missing ($n)" 1386ret=0 1387( 1388cd signer/general || exit 1 1389rm -f signed.zone 1390$SIGNER -f signed.zone -o example.com. test8.zone > signer.out.$n 1391test -f signed.zone 1392) && ret=1 1393n=$((n+1)) 1394test "$ret" -eq 0 || echo_i "failed" 1395status=$((status+ret)) 1396 1397echo_i "checking that a key using an unsupported algorithm cannot be generated ($n)" 1398ret=0 1399zone=example 1400# If dnssec-keygen fails, the test script will exit immediately. Prevent that 1401# from happening, and also trigger a test failure if dnssec-keygen unexpectedly 1402# succeeds, by using "&& ret=1". 1403$KEYGEN -a 255 $zone > dnssectools.out.test$n 2>&1 && ret=1 1404grep -q "unsupported algorithm: 255" dnssectools.out.test$n || ret=1 1405n=$((n+1)) 1406test "$ret" -eq 0 || echo_i "failed" 1407status=$((status+ret)) 1408 1409echo_i "checking that a DS record cannot be generated for a key using an unsupported algorithm ($n)" 1410ret=0 1411zone=example 1412# Fake an unsupported algorithm key 1413unsupportedkey=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") 1414awk '$3 == "DNSKEY" { $6 = 255 } { print }' ${unsupportedkey}.key > ${unsupportedkey}.tmp 1415mv ${unsupportedkey}.tmp ${unsupportedkey}.key 1416# If dnssec-dsfromkey fails, the test script will exit immediately. Prevent 1417# that from happening, and also trigger a test failure if dnssec-dsfromkey 1418# unexpectedly succeeds, by using "&& ret=1". 1419$DSFROMKEY ${unsupportedkey} > dnssectools.out.test$n 2>&1 && ret=1 1420grep -q "algorithm is unsupported" dnssectools.out.test$n || ret=1 1421n=$((n+1)) 1422test "$ret" -eq 0 || echo_i "failed" 1423status=$((status+ret)) 1424 1425echo_i "checking that a zone cannot be signed with a key using an unsupported algorithm ($n)" 1426ret=0 1427ret=0 1428cat signer/example.db.in "${unsupportedkey}.key" > signer/example.db 1429# If dnssec-signzone fails, the test script will exit immediately. Prevent that 1430# from happening, and also trigger a test failure if dnssec-signzone 1431# unexpectedly succeeds, by using "&& ret=1". 1432$SIGNER -o example signer/example.db ${unsupportedkey} > dnssectools.out.test$n 2>&1 && ret=1 1433grep -q "algorithm is unsupported" dnssectools.out.test$n || ret=1 1434n=$((n+1)) 1435test "$ret" -eq 0 || echo_i "failed" 1436status=$((status+ret)) 1437 1438get_rsasha1_key_ids_from_sigs() { 1439 tr -d '\r' < signer/example.db.signed | \ 1440 awk ' 1441 NF < 8 { next } 1442 $(NF-5) != "RRSIG" { next } 1443 $(NF-3) != "5" { next } 1444 $NF != "(" { next } 1445 { 1446 getline; 1447 print $3; 1448 } 1449 ' | \ 1450 sort -u 1451} 1452 1453echo_i "checking that we can sign a zone with out-of-zone records ($n)" 1454ret=0 1455zone=example 1456key1=$($KEYGEN -K signer -q -a NSEC3RSASHA1 -b 1024 -n zone $zone) 1457key2=$($KEYGEN -K signer -q -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone) 1458( 1459cd signer || exit 1 1460cat example.db.in "$key1.key" "$key2.key" > example.db 1461$SIGNER -o example -f example.db example.db > /dev/null 1462) || ret=1 1463n=$((n+1)) 1464test "$ret" -eq 0 || echo_i "failed" 1465status=$((status+ret)) 1466 1467echo_i "checking that we can sign a zone (NSEC3) with out-of-zone records ($n)" 1468ret=0 1469zone=example 1470key1=$($KEYGEN -K signer -q -a NSEC3RSASHA1 -b 1024 -n zone $zone) 1471key2=$($KEYGEN -K signer -q -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone) 1472( 1473cd signer || exit 1 1474cat example.db.in "$key1.key" "$key2.key" > example.db 1475$SIGNER -3 - -H 10 -o example -f example.db example.db > /dev/null 1476awk '/^IQF9LQTLK/ { 1477 printf("%s", $0); 1478 while (!index($0, ")")) { 1479 if (getline <= 0) 1480 break; 1481 printf (" %s", $0); 1482 } 1483 printf("\n"); 1484 }' example.db | sed 's/[ ][ ]*/ /g' > nsec3param.out 1485 1486grep "IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG.example. 0 IN NSEC3 1 0 10 - ( IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG A NS SOA RRSIG DNSKEY NSEC3PARAM )" nsec3param.out > /dev/null 1487) || ret=1 1488n=$((n+1)) 1489test "$ret" -eq 0 || echo_i "failed" 1490status=$((status+ret)) 1491 1492echo_i "checking NSEC3 signing with empty nonterminals above a delegation ($n)" 1493ret=0 1494zone=example 1495key1=$($KEYGEN -K signer -q -a NSEC3RSASHA1 -b 1024 -n zone $zone) 1496key2=$($KEYGEN -K signer -q -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone) 1497( 1498cd signer || exit 1 1499cat example.db.in "$key1.key" "$key2.key" > example3.db 1500echo "some.empty.nonterminal.nodes.example 60 IN NS ns.example.tld" >> example3.db 1501$SIGNER -3 - -A -H 10 -o example -f example3.db example3.db > /dev/null 1502awk '/^IQF9LQTLK/ { 1503 printf("%s", $0); 1504 while (!index($0, ")")) { 1505 if (getline <= 0) 1506 break; 1507 printf (" %s", $0); 1508 } 1509 printf("\n"); 1510 }' example.db | sed 's/[ ][ ]*/ /g' > nsec3param.out 1511 1512grep "IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG.example. 0 IN NSEC3 1 0 10 - ( IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG A NS SOA RRSIG DNSKEY NSEC3PARAM )" nsec3param.out > /dev/null 1513) || ret=1 1514n=$((n+1)) 1515test "$ret" -eq 0 || echo_i "failed" 1516status=$((status+ret)) 1517 1518echo_i "checking that dnssec-signzone updates originalttl on ttl changes ($n)" 1519ret=0 1520zone=example 1521key1=$($KEYGEN -K signer -q -a RSASHA1 -b 1024 -n zone $zone) 1522key2=$($KEYGEN -K signer -q -f KSK -a RSASHA1 -b 1024 -n zone $zone) 1523( 1524cd signer || exit 1 1525cat example.db.in "$key1.key" "$key2.key" > example.db 1526$SIGNER -o example -f example.db.before example.db > /dev/null 1527sed 's/60.IN.SOA./50 IN SOA /' example.db.before > example.db.changed 1528$SIGNER -o example -f example.db.after example.db.changed > /dev/null 1529) 1530grep "SOA 5 1 50" signer/example.db.after > /dev/null || ret=1 1531n=$((n+1)) 1532test "$ret" -eq 0 || echo_i "failed" 1533status=$((status+ret)) 1534 1535echo_i "checking dnssec-signzone keeps valid signatures from removed keys ($n)" 1536ret=0 1537zone=example 1538key1=$($KEYGEN -K signer -q -f KSK -a RSASHA1 -b 1024 -n zone $zone) 1539key2=$($KEYGEN -K signer -q -a RSASHA1 -b 1024 -n zone $zone) 1540keyid2=$(keyfile_to_key_id "$key2") 1541key3=$($KEYGEN -K signer -q -a RSASHA1 -b 1024 -n zone $zone) 1542keyid3=$(keyfile_to_key_id "$key3") 1543( 1544cd signer || exit 1 1545cat example.db.in "$key1.key" "$key2.key" > example.db 1546$SIGNER -D -o example example.db > /dev/null 1547 1548# now switch out key2 for key3 and resign the zone 1549cat example.db.in "$key1.key" "$key3.key" > example.db 1550echo "\$INCLUDE \"example.db.signed\"" >> example.db 1551$SIGNER -D -o example example.db > /dev/null 1552) || ret=1 1553get_rsasha1_key_ids_from_sigs | grep "^$keyid2$" > /dev/null || ret=1 1554get_rsasha1_key_ids_from_sigs | grep "^$keyid3$" > /dev/null || ret=1 1555n=$((n+1)) 1556test "$ret" -eq 0 || echo_i "failed" 1557status=$((status+ret)) 1558 1559echo_i "checking dnssec-signzone -R purges signatures from removed keys ($n)" 1560ret=0 1561( 1562cd signer || exit 1 1563$SIGNER -RD -o example example.db > /dev/null 1564) || ret=1 1565get_rsasha1_key_ids_from_sigs | grep "^$keyid2$" > /dev/null && ret=1 1566get_rsasha1_key_ids_from_sigs | grep "^$keyid3$" > /dev/null || ret=1 1567n=$((n+1)) 1568test "$ret" -eq 0 || echo_i "failed" 1569status=$((status+ret)) 1570 1571echo_i "checking dnssec-signzone keeps valid signatures from inactive keys ($n)" 1572ret=0 1573zone=example 1574( 1575cd signer || exit 1 1576cp -f example.db.in example.db 1577$SIGNER -SD -o example example.db > /dev/null 1578echo "\$INCLUDE \"example.db.signed\"" >> example.db 1579# now retire key2 and resign the zone 1580$SETTIME -I now "$key2" > /dev/null 2>&1 1581$SIGNER -SD -o example example.db > /dev/null 1582) || ret=1 1583get_rsasha1_key_ids_from_sigs | grep "^$keyid2$" > /dev/null || ret=1 1584get_rsasha1_key_ids_from_sigs | grep "^$keyid3$" > /dev/null || ret=1 1585n=$((n+1)) 1586test "$ret" -eq 0 || echo_i "failed" 1587status=$((status+ret)) 1588 1589echo_i "checking dnssec-signzone -Q purges signatures from inactive keys ($n)" 1590ret=0 1591( 1592cd signer || exit 1 1593$SIGNER -SDQ -o example example.db > /dev/null 1594) || ret=1 1595get_rsasha1_key_ids_from_sigs | grep "^$keyid2$" > /dev/null && ret=1 1596get_rsasha1_key_ids_from_sigs | grep "^$keyid3$" > /dev/null || ret=1 1597n=$((n+1)) 1598test "$ret" -eq 0 || echo_i "failed" 1599status=$((status+ret)) 1600 1601echo_i "checking dnssec-signzone retains unexpired signatures ($n)" 1602ret=0 1603( 1604cd signer || exit 1 1605$SIGNER -Sxt -o example example.db > signer.out.1 1606$SIGNER -Sxt -o example -f example.db.signed example.db.signed > signer.out.2 1607) || ret=1 1608gen1=$(awk '/generated/ {print $3}' signer/signer.out.1) 1609retain1=$(awk '/retained/ {print $3}' signer/signer.out.1) 1610gen2=$(awk '/generated/ {print $3}' signer/signer.out.2) 1611retain2=$(awk '/retained/ {print $3}' signer/signer.out.2) 1612drop2=$(awk '/dropped/ {print $3}' signer/signer.out.2) 1613[ "$retain2" -eq $((gen1+retain1)) ] || ret=1 1614[ "$gen2" -eq 0 ] || ret=1 1615[ "$drop2" -eq 0 ] || ret=1 1616n=$((n+1)) 1617test "$ret" -eq 0 || echo_i "failed" 1618status=$((status+ret)) 1619 1620echo_i "checking dnssec-signzone purges RRSIGs from formerly-owned glue (nsec) ($n)" 1621ret=0 1622( 1623cd signer || exit 1 1624# remove NSEC-only keys 1625rm -f Kexample.+005* 1626cp -f example.db.in example2.db 1627cat << EOF >> example2.db 1628sub1.example. IN A 10.53.0.1 1629ns.sub2.example. IN A 10.53.0.2 1630EOF 1631echo "\$INCLUDE \"example2.db.signed\"" >> example2.db 1632touch example2.db.signed 1633$SIGNER -DS -O full -f example2.db.signed -o example example2.db > /dev/null 1634) || ret=1 1635grep "^sub1\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 || ret=1 1636grep "^ns\\.sub2\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 || ret=1 1637( 1638cd signer || exit 1 1639cp -f example.db.in example2.db 1640cat << EOF >> example2.db 1641sub1.example. IN NS sub1.example. 1642sub1.example. IN A 10.53.0.1 1643sub2.example. IN NS ns.sub2.example. 1644ns.sub2.example. IN A 10.53.0.2 1645EOF 1646echo "\$INCLUDE \"example2.db.signed\"" >> example2.db 1647$SIGNER -DS -O full -f example2.db.signed -o example example2.db > /dev/null 1648) || ret=1 1649grep "^sub1\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 && ret=1 1650grep "^ns\\.sub2\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 && ret=1 1651n=$((n+1)) 1652test "$ret" -eq 0 || echo_i "failed" 1653status=$((status+ret)) 1654 1655echo_i "checking dnssec-signzone purges RRSIGs from formerly-owned glue (nsec3) ($n)" 1656ret=0 1657( 1658cd signer || exit 1 1659rm -f example2.db.signed 1660cp -f example.db.in example2.db 1661cat << EOF >> example2.db 1662sub1.example. IN A 10.53.0.1 1663ns.sub2.example. IN A 10.53.0.2 1664EOF 1665echo "\$INCLUDE \"example2.db.signed\"" >> example2.db 1666touch example2.db.signed 1667$SIGNER -DS -3 feedabee -O full -f example2.db.signed -o example example2.db > /dev/null 1668) || ret=1 1669grep "^sub1\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 || ret=1 1670grep "^ns\\.sub2\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 || ret=1 1671( 1672cd signer || exit 1 1673cp -f example.db.in example2.db 1674cat << EOF >> example2.db 1675sub1.example. IN NS sub1.example. 1676sub1.example. IN A 10.53.0.1 1677sub2.example. IN NS ns.sub2.example. 1678ns.sub2.example. IN A 10.53.0.2 1679EOF 1680echo "\$INCLUDE \"example2.db.signed\"" >> example2.db 1681$SIGNER -DS -3 feedabee -O full -f example2.db.signed -o example example2.db > /dev/null 1682) || ret=1 1683grep "^sub1\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 && ret=1 1684grep "^ns\\.sub2\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 && ret=1 1685n=$((n+1)) 1686test "$ret" -eq 0 || echo_i "failed" 1687status=$((status+ret)) 1688 1689echo_i "checking dnssec-signzone output format ($n)" 1690ret=0 1691( 1692cd signer || exit 1 1693$SIGNER -O full -f - -Sxt -o example example.db > signer.out.3 2> /dev/null 1694$SIGNER -O text -f - -Sxt -o example example.db > signer.out.4 2> /dev/null 1695$SIGNER -O raw -f signer.out.5 -Sxt -o example example.db > /dev/null 1696$SIGNER -O raw=0 -f signer.out.6 -Sxt -o example example.db > /dev/null 1697$SIGNER -O raw -f - -Sxt -o example example.db > signer.out.7 2> /dev/null 1698) || ret=1 1699awk '/IN *SOA/ {if (NF != 11) exit(1)}' signer/signer.out.3 || ret=1 1700awk '/IN *SOA/ {if (NF != 7) exit(1)}' signer/signer.out.4 || ret=1 1701israw1 signer/signer.out.5 || ret=1 1702israw0 signer/signer.out.6 || ret=1 1703israw1 signer/signer.out.7 || ret=1 1704n=$((n+1)) 1705test "$ret" -eq 0 || echo_i "failed" 1706status=$((status+ret)) 1707 1708echo_i "checking TTLs are capped by dnssec-signzone -M ($n)" 1709ret=0 1710( 1711cd signer || exit 1 1712$SIGNER -O full -f signer.out.8 -S -M 30 -o example example.db > /dev/null 1713) || ret=1 1714awk '/^;/ { next; } $2 > 30 { exit 1; }' signer/signer.out.8 || ret=1 1715n=$((n+1)) 1716test "$ret" -eq 0 || echo_i "failed" 1717status=$((status+ret)) 1718 1719echo_i "checking dnssec-signzone -N date ($n)" 1720ret=0 1721( 1722cd signer || exit 1 1723TZ=UTC $SIGNER -O full -f signer.out.9 -S -N date -o example example2.db > /dev/null 1724) || ret=1 1725# shellcheck disable=SC2016 1726now=$(TZ=UTC $PERL -e '@lt=localtime(); printf "%.4d%0.2d%0.2d00\n",$lt[5]+1900,$lt[4]+1,$lt[3];') 1727serial=$(awk '/^;/ { next; } $4 == "SOA" { print $7 }' signer/signer.out.9) 1728[ "$now" -eq "$serial" ] || ret=1 1729n=$((n+1)) 1730test "$ret" -eq 0 || echo_i "failed" 1731status=$((status+ret)) 1732 1733echo_i "checking validated data are not cached longer than originalttl ($n)" 1734ret=0 1735dig_with_opts +ttl +noauth a.ttlpatch.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 1736dig_with_opts +ttl +noauth a.ttlpatch.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 1737grep "3600.IN" dig.out.ns3.test$n > /dev/null || ret=1 1738grep "300.IN" dig.out.ns3.test$n > /dev/null && ret=1 1739grep "300.IN" dig.out.ns4.test$n > /dev/null || ret=1 1740grep "3600.IN" dig.out.ns4.test$n > /dev/null && ret=1 1741n=$((n+1)) 1742test "$ret" -eq 0 || echo_i "failed" 1743status=$((status+ret)) 1744 1745# Test that "rndc secroots" is able to dump trusted keys 1746echo_i "checking rndc secroots ($n)" 1747ret=0 1748keyid=$(cat ns1/managed.key.id) 1749rndccmd 10.53.0.4 secroots 2>&1 | sed 's/^/ns4 /' | cat_i 1750cp ns4/named.secroots named.secroots.test$n 1751check_secroots_layout named.secroots.test$n || ret=1 1752linecount=$(grep -c "./${DEFAULT_ALGORITHM}/$keyid ; static" named.secroots.test$n || true) 1753[ "$linecount" -eq 1 ] || ret=1 1754linecount=$(< named.secroots.test$n wc -l) 1755[ "$linecount" -eq 9 ] || ret=1 1756n=$((n+1)) 1757test "$ret" -eq 0 || echo_i "failed" 1758status=$((status+ret)) 1759 1760# Check direct query for RRSIG. If we first ask for normal (non RRSIG) 1761# record, the corresponding RRSIG should be cached and subsequent query 1762# for RRSIG will be returned with the cached record. 1763echo_i "checking RRSIG query from cache ($n)" 1764ret=0 1765dig_with_opts normalthenrrsig.secure.example. @10.53.0.4 a > /dev/null || ret=1 1766ans=$(dig_with_opts +short normalthenrrsig.secure.example. @10.53.0.4 rrsig) || ret=1 1767expect=$(dig_with_opts +short normalthenrrsig.secure.example. @10.53.0.3 rrsig | grep '^A' ) || ret=1 1768test "$ans" = "$expect" || ret=1 1769# also check that RA is set 1770dig_with_opts normalthenrrsig.secure.example. @10.53.0.4 rrsig > dig.out.ns4.test$n || ret=1 1771grep "flags:.*ra.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 1772n=$((n+1)) 1773test "$ret" -eq 0 || echo_i "failed" 1774status=$((status+ret)) 1775 1776# Check direct query for RRSIG: If it's not cached with other records, 1777# it should result in an empty response. 1778echo_i "checking RRSIG query not in cache ($n)" 1779ret=0 1780ans=$(dig_with_opts +short rrsigonly.secure.example. @10.53.0.4 rrsig) || ret=1 1781test -z "$ans" || ret=1 1782# also check that RA is cleared 1783dig_with_opts rrsigonly.secure.example. @10.53.0.4 rrsig > dig.out.ns4.test$n || ret=1 1784grep "flags:.*ra.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 1785n=$((n+1)) 1786test "$ret" -eq 0 || echo_i "failed" 1787status=$((status+ret)) 1788 1789# 1790# RT21868 regression test. 1791# 1792echo_i "checking NSEC3 zone with mismatched NSEC3PARAM / NSEC parameters ($n)" 1793ret=0 1794dig_with_opts non-exist.badparam. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 1795grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 1796n=$((n+1)) 1797test "$ret" -eq 0 || echo_i "failed" 1798status=$((status+ret)) 1799 1800# 1801# RT22007 regression test. 1802# 1803echo_i "checking optout NSEC3 referral with only insecure delegations ($n)" 1804ret=0 1805dig_with_opts +norec delegation.single-nsec3. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 1806grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 1807grep "3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN.*NSEC3 1 1 1 - 3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN" dig.out.ns2.test$n > /dev/null || ret=1 1808n=$((n+1)) 1809test "$ret" -eq 0 || echo_i "failed" 1810status=$((status+ret)) 1811 1812echo_i "checking optout NSEC3 NXDOMAIN with only insecure delegations ($n)" 1813ret=0 1814dig_with_opts +norec nonexist.single-nsec3. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 1815grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 1816grep "3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN.*NSEC3 1 1 1 - 3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN" dig.out.ns2.test$n > /dev/null || ret=1 1817n=$((n+1)) 1818test "$ret" -eq 0 || echo_i "failed" 1819 1820status=$((status+ret)) 1821echo_i "checking optout NSEC3 nodata with only insecure delegations ($n)" 1822ret=0 1823dig_with_opts +norec single-nsec3. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 1824grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 1825grep "3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN.*NSEC3 1 1 1 - 3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN" dig.out.ns2.test$n > /dev/null || ret=1 1826n=$((n+1)) 1827test "$ret" -eq 0 || echo_i "failed" 1828status=$((status+ret)) 1829 1830echo_i "checking that a zone finishing the transition from $ALTERNATIVE_ALGORITHM to $DEFAULT_ALGORITHM validates secure ($n)" 1831ret=0 1832dig_with_opts ns algroll. @10.53.0.4 > dig.out.ns4.test$n || ret=1 1833grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 1834grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n > /dev/null || ret=1 1835n=$((n+1)) 1836test "$ret" -eq 0 || echo_i "failed" 1837status=$((status+ret)) 1838 1839echo_i "checking validate-except in an insecure local domain ($n)" 1840ret=0 1841dig_with_opts ns www.corp @10.53.0.4 > dig.out.ns4.test$n || ret=1 1842grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 1843grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n > /dev/null && ret=1 1844n=$((n+1)) 1845test "$ret" -eq 0 || echo_i "failed" 1846status=$((status+ret)) 1847 1848echo_i "checking positive and negative validation with negative trust anchors ($n)" 1849ret=0 1850 1851# 1852# check correct initial behavior 1853# 1854dig_with_opts a.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.1 || ret=1 1855grep "status: SERVFAIL" dig.out.ns4.test$n.1 > /dev/null || ret=1 1856dig_with_opts badds.example. soa @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1 1857grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null || ret=1 1858dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.3 || ret=1 1859grep "status: SERVFAIL" dig.out.ns4.test$n.3 > /dev/null && ret=1 1860grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.3 > /dev/null || ret=1 1861 1862if [ "$ret" -ne 0 ]; then echo_i "failed - checking initial state"; fi 1863status=$((status+ret)) 1864ret=0 1865 1866# 1867# add negative trust anchors 1868# 1869rndccmd 10.53.0.4 nta -f -l 20s bogus.example 2>&1 | sed 's/^/ns4 /' | cat_i 1870rndccmd 10.53.0.4 nta badds.example 2>&1 | sed 's/^/ns4 /' | cat_i 1871# reconfig should maintain NTAs 1872rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i 1873rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 1874lines=$(wc -l < rndc.out.ns4.test$n.1) 1875[ "$lines" -eq 2 ] || ret=1 1876rndccmd 10.53.0.4 nta secure.example 2>&1 | sed 's/^/ns4 /' | cat_i 1877rndccmd 10.53.0.4 nta fakenode.secure.example 2>&1 | sed 's/^/ns4 /' | cat_i 1878# reload should maintain NTAs 1879rndc_reload ns4 10.53.0.4 1880rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.2 1881lines=$(wc -l < rndc.out.ns4.test$n.2) 1882[ "$lines" -eq 4 ] || ret=1 1883# shellcheck disable=SC2016 1884start=$($PERL -e 'print time()."\n";') 1885 1886if [ "$ret" -ne 0 ]; then echo_i "failed - adding NTA's failed"; fi 1887status=$((status+ret)) 1888ret=0 1889 1890# 1891# check behavior with NTA's in place 1892# 1893dig_with_opts a.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.4 || ret=1 1894grep "status: SERVFAIL" dig.out.ns4.test$n.4 > /dev/null && ret=1 1895grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.4 > /dev/null && ret=1 1896dig_with_opts badds.example. soa @10.53.0.4 > dig.out.ns4.test$n.5 || ret=1 1897grep "status: SERVFAIL" dig.out.ns4.test$n.5 > /dev/null && ret=1 1898grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.5 > /dev/null && ret=1 1899dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.6 || ret=1 1900grep "status: SERVFAIL" dig.out.ns4.test$n.6 > /dev/null && ret=1 1901grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.6 > /dev/null && ret=1 1902dig_with_opts a.fakenode.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.7 || ret=1 1903grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.7 > /dev/null && ret=1 1904echo_i "dumping secroots" 1905rndccmd 10.53.0.4 secroots | sed 's/^/ns4 /' | cat_i 1906cp ns4/named.secroots named.secroots.test$n 1907check_secroots_layout named.secroots.test$n || ret=1 1908grep "bogus.example: expiry" named.secroots.test$n > /dev/null || ret=1 1909grep "badds.example: expiry" named.secroots.test$n > /dev/null || ret=1 1910grep "secure.example: expiry" named.secroots.test$n > /dev/null || ret=1 1911grep "fakenode.secure.example: expiry" named.secroots.test$n > /dev/null || ret=1 1912 1913if [ "$ret" -ne 0 ]; then echo_i "failed - with NTA's in place failed"; fi 1914status=$((status+ret)) 1915ret=0 1916 1917echo_i "waiting for NTA rechecks/expirations" 1918 1919# 1920# secure.example and badds.example used default nta-duration 1921# (configured as 12s in ns4/named1.conf), but nta recheck interval 1922# is configured to 9s, so at t=10 the NTAs for secure.example and 1923# fakenode.secure.example should both be lifted, but badds.example 1924# should still be going. 1925# 1926# shellcheck disable=SC2016 1927$PERL -e 'my $delay = '"$start"' + 10 - time(); select(undef, undef, undef, $delay) if ($delay > 0);' 1928dig_with_opts b.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.8 || ret=1 1929grep "status: SERVFAIL" dig.out.ns4.test$n.8 > /dev/null && ret=1 1930grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.8 > /dev/null || ret=1 1931dig_with_opts b.fakenode.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.9 || ret=1 1932grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.9 > /dev/null || ret=1 1933grep "status: NXDOMAIN" dig.out.ns4.test$n.9 > /dev/null || ret=1 1934dig_with_opts badds.example. soa @10.53.0.4 > dig.out.ns4.test$n.10 || ret=1 1935grep "status: SERVFAIL" dig.out.ns4.test$n.10 > /dev/null && ret=1 1936grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.10 > /dev/null && ret=1 1937 1938if [ "$ret" -ne 0 ]; then echo_i "failed - checking that default nta's were lifted due to recheck"; fi 1939status=$((status+ret)) 1940ret=0 1941 1942# 1943# bogus.example was set to expire in 20s, so at t=13 1944# it should still be NTA'd, but badds.example used the default 1945# lifetime of 12s, so it should revert to SERVFAIL now. 1946# 1947# shellcheck disable=SC2016 1948$PERL -e 'my $delay = '"$start"' + 13 - time(); select(undef, undef, undef, $delay) if ($delay > 0);' 1949# check nta table 1950rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n._11 1951lines=$(grep -c " expiry " rndc.out.ns4.test$n._11 || true) 1952[ "$lines" -le 2 ] || ret=1 1953grep "bogus.example/_default: expiry" rndc.out.ns4.test$n._11 > /dev/null || ret=1 1954grep "badds.example/_default: expiry" rndc.out.ns4.test$n._11 > /dev/null && ret=1 1955dig_with_opts b.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.11 || ret=1 1956grep "status: SERVFAIL" dig.out.ns4.test$n.11 > /dev/null && ret=1 1957dig_with_opts a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.12 || ret=1 1958grep "status: SERVFAIL" dig.out.ns4.test$n.12 > /dev/null || ret=1 1959grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.12 > /dev/null && ret=1 1960dig_with_opts c.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.13 || ret=1 1961grep "status: SERVFAIL" dig.out.ns4.test$n.13 > /dev/null && ret=1 1962grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.13 > /dev/null || ret=1 1963 1964if [ "$ret" -ne 0 ]; then echo_i "failed - checking that default nta's were lifted due to lifetime"; fi 1965status=$((status+ret)) 1966ret=0 1967 1968# 1969# at t=21, all the NTAs should have expired. 1970# 1971# shellcheck disable=SC2016 1972$PERL -e 'my $delay = '"$start"' + 21 - time(); select(undef, undef, undef, $delay) if ($delay > 0);' 1973# check correct behavior after bogus.example expiry 1974dig_with_opts d.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.14 || ret=1 1975grep "status: SERVFAIL" dig.out.ns4.test$n.14 > /dev/null && ret=1 1976grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.14 > /dev/null || ret=1 1977dig_with_opts c.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.15 || ret=1 1978grep "status: SERVFAIL" dig.out.ns4.test$n.15 > /dev/null || ret=1 1979# check nta table has been cleaned up now 1980rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.3 1981lines=$(grep -c " expiry " rndc.out.ns4.test$n.3 || true) 1982[ "$lines" -eq 0 ] || ret=1 1983n=$((n+1)) 1984if [ "$ret" -ne 0 ]; then echo_i "failed - checking that all nta's have been lifted"; fi 1985status=$((status+ret)) 1986ret=0 1987 1988echo_i "testing NTA removals ($n)" 1989rndccmd 10.53.0.4 nta badds.example 2>&1 | sed 's/^/ns4 /' | cat_i 1990rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 1991grep "badds.example/_default: expiry" rndc.out.ns4.test$n.1 > /dev/null || ret=1 1992dig_with_opts a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.1 || ret=1 1993grep "status: SERVFAIL" dig.out.ns4.test$n.1 > /dev/null && ret=1 1994grep "^a.badds.example." dig.out.ns4.test$n.1 > /dev/null || ret=1 1995rndccmd 10.53.0.4 nta -remove badds.example > rndc.out.ns4.test$n.2 1996grep "Negative trust anchor removed: badds.example/_default" rndc.out.ns4.test$n.2 > /dev/null || ret=1 1997rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.3 1998grep "badds.example/_default: expiry" rndc.out.ns4.test$n.3 > /dev/null && ret=1 1999dig_with_opts a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1 2000grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null || ret=1 2001test "$ret" -eq 0 || echo_i "failed" 2002status=$((status+ret)) 2003ret=0 2004 2005echo_i "remove non-existent NTA three times" 2006rndccmd 10.53.0.4 nta -r foo > rndc.out.ns4.test$n.4 2>&1 2007rndccmd 10.53.0.4 nta -remove foo > rndc.out.ns4.test$n.5 2>&1 2008rndccmd 10.53.0.4 nta -r foo > rndc.out.ns4.test$n.6 2>&1 2009grep "not found" rndc.out.ns4.test$n.6 > /dev/null || ret=1 2010test "$ret" -eq 0 || echo_i "failed" 2011status=$((status+ret)) 2012ret=0 2013 2014n=$((n+1)) 2015echo_i "testing NTA with bogus lifetimes ($n)" 2016echo_i "check with no nta lifetime specified" 2017rndccmd 10.53.0.4 nta -l "" foo > rndc.out.ns4.test$n.1 2>&1 || true 2018grep "'nta' failed: bad ttl" rndc.out.ns4.test$n.1 > /dev/null || ret=1 2019test "$ret" -eq 0 || echo_i "failed" 2020status=$((status+ret)) 2021ret=0 2022 2023echo_i "check with bad nta lifetime" 2024rndccmd 10.53.0.4 nta -l garbage foo > rndc.out.ns4.test$n.2 2>&1 || true 2025grep "'nta' failed: bad ttl" rndc.out.ns4.test$n.2 > /dev/null || ret=1 2026test "$ret" -eq 0 || echo_i "failed" 2027status=$((status+ret)) 2028ret=0 2029 2030echo_i "check with too long nta lifetime" 2031rndccmd 10.53.0.4 nta -l 7d1h foo > rndc.out.ns4.test$n.3 2>&1 || true 2032grep "'nta' failed: out of range" rndc.out.ns4.test$n.3 > /dev/null || ret=1 2033test "$ret" -eq 0 || echo_i "failed" 2034status=$((status+ret)) 2035ret=0 2036 2037# 2038# check NTA persistence across restarts 2039# 2040n=$((n+1)) 2041echo_i "testing NTA persistence across restarts ($n)" 2042rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 2043lines=$(grep -c " expiry " rndc.out.ns4.test$n.1 || true) 2044[ "$lines" -eq 0 ] || ret=1 2045rndccmd 10.53.0.4 nta -f -l 30s bogus.example 2>&1 | sed 's/^/ns4 /' | cat_i 2046rndccmd 10.53.0.4 nta -f -l 10s badds.example 2>&1 | sed 's/^/ns4 /' | cat_i 2047rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.2 2048lines=$(grep -c " expiry " rndc.out.ns4.test$n.2 || true) 2049[ "$lines" -eq 2 ] || ret=1 2050# shellcheck disable=SC2016 2051start=$($PERL -e 'print time()."\n";') 2052 2053if [ "$ret" -ne 0 ]; then echo_i "failed - NTA persistence: adding NTA's failed"; fi 2054status=$((status+ret)) 2055ret=0 2056 2057echo_i "killing ns4 with SIGTERM" 2058$KILL -TERM "$(cat ns4/named.pid)" 2059rm -f ns4/named.pid 2060 2061# 2062# ns4 has now shutdown. wait until t=14 when badds.example's NTA 2063# (lifetime=10s) would have expired, and then restart ns4. 2064# 2065echo_i "waiting till 14s have passed since NTAs were added before restarting ns4" 2066# shellcheck disable=SC2016 2067$PERL -e 'my $delay = '"$start"' + 14 - time(); select(undef, undef, undef, $delay) if ($delay > 0);' 2068 2069if 2070 $PERL "$SYSTEMTESTTOP/start.pl" --noclean --restart --port "$PORT" dnssec ns4 2071then 2072 echo_i "restarted server ns4" 2073else 2074 echo_i "could not restart server ns4" 2075 exit 1 2076fi 2077 2078echo_i "sleeping for an additional 4 seconds for ns4 to fully startup" 2079sleep 4 2080 2081# 2082# ns4 should be back up now. The NTA for bogus.example should still be 2083# valid, whereas badds.example should not have been added during named 2084# startup (as it had already expired), the fact that it's ignored should 2085# be logged. 2086# 2087rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.3 2088lines=$(wc -l < rndc.out.ns4.test$n.3) 2089[ "$lines" -eq 1 ] || ret=1 2090grep "bogus.example/_default: expiry" rndc.out.ns4.test$n.3 > /dev/null || ret=1 2091dig_with_opts b.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.4 || ret=1 2092grep "status: SERVFAIL" dig.out.ns4.test$n.4 > /dev/null && ret=1 2093grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.4 > /dev/null && ret=1 2094dig_with_opts a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.5 || ret=1 2095grep "status: SERVFAIL" dig.out.ns4.test$n.5 > /dev/null || ret=1 2096grep "ignoring expired NTA at badds.example" ns4/named.run > /dev/null || ret=1 2097 2098# cleanup 2099rndccmd 10.53.0.4 nta -remove bogus.example > rndc.out.ns4.test$n.6 2100 2101if [ "$ret" -ne 0 ]; then echo_i "failed - NTA persistence: restoring NTA failed"; fi 2102status=$((status+ret)) 2103ret=0 2104 2105# 2106# check "regular" attribute in NTA file works as expected at named 2107# startup. 2108# 2109n=$((n+1)) 2110echo_i "testing loading regular attribute from NTA file ($n)" 2111rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 2>/dev/null 2112lines=$(wc -l < rndc.out.ns4.test$n.1) 2113[ "$lines" -eq 0 ] || ret=1 2114# initially, secure.example. validates with AD=1 2115dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1 2116grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null && ret=1 2117grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.2 > /dev/null || ret=1 2118 2119echo_i "killing ns4 with SIGTERM" 2120$KILL -TERM "$(cat ns4/named.pid)" 2121rm -f ns4/named.pid 2122 2123echo_i "sleeping for an additional 4 seconds for ns4 to fully shutdown" 2124sleep 4 2125 2126# 2127# ns4 has now shutdown. add NTA for secure.example. directly into the 2128# _default.nta file with the regular attribute and some future timestamp. 2129# 2130future="$(($(date +%Y)+20))0101010000" 2131echo "secure.example. regular $future" > ns4/_default.nta 2132# shellcheck disable=SC2016 2133start=$($PERL -e 'print time()."\n";') 2134 2135if 2136 $PERL "$SYSTEMTESTTOP/start.pl" --noclean --restart --port "$PORT" dnssec ns4 2137then 2138 echo_i "restarted server ns4" 2139else 2140 echo_i "could not restart server ns4" 2141 exit 1 2142fi 2143 2144# nta-recheck is configured as 9s, so at t=12 the NTAs for 2145# secure.example. should be lifted as it is not a forced NTA. 2146echo_i "waiting till 12s have passed after ns4 was restarted" 2147# shellcheck disable=SC2016 2148$PERL -e 'my $delay = '"$start"' + 12 - time(); select(undef, undef, undef, $delay) if ($delay > 0);' 2149 2150# secure.example. should now return an AD=1 answer (still validates) as 2151# the NTA has been lifted. 2152dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.3 || ret=1 2153grep "status: SERVFAIL" dig.out.ns4.test$n.3 > /dev/null && ret=1 2154grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.3 > /dev/null || ret=1 2155 2156# cleanup 2157rndccmd 10.53.0.4 nta -remove secure.example > rndc.out.ns4.test$n.4 2>/dev/null 2158 2159if [ "$ret" -ne 0 ]; then echo_i "failed - NTA persistence: loading regular NTAs failed"; fi 2160status=$((status+ret)) 2161ret=0 2162 2163# 2164# check "forced" attribute in NTA file works as expected at named 2165# startup. 2166# 2167n=$((n+1)) 2168echo_i "testing loading forced attribute from NTA file ($n)" 2169rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 2>/dev/null 2170lines=$(wc -l < rndc.out.ns4.test$n.1) 2171[ "$lines" -eq 0 ] || ret=1 2172# initially, secure.example. validates with AD=1 2173dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1 2174grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null && ret=1 2175grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.2 > /dev/null || ret=1 2176 2177echo_i "killing ns4 with SIGTERM" 2178$KILL -TERM "$(cat ns4/named.pid)" 2179rm -f named.pid 2180 2181echo_i "sleeping for an additional 4 seconds for ns4 to fully shutdown" 2182sleep 4 2183 2184# 2185# ns4 has now shutdown. add NTA for secure.example. directly into the 2186# _default.nta file with the forced attribute and some future timestamp. 2187# 2188echo "secure.example. forced $future" > ns4/_default.nta 2189start=$($PERL -e 'print time()."\n";') 2190 2191if 2192 $PERL "$SYSTEMTESTTOP/start.pl" --noclean --restart --port "$PORT" dnssec ns4 2193then 2194 echo_i "restarted server ns4" 2195else 2196 echo_i "could not restart server ns4" 2197 exit 1 2198fi 2199 2200# nta-recheck is configured as 9s, but even at t=12 the NTAs for 2201# secure.example. should not be lifted as it is a forced NTA. 2202echo_i "waiting till 12s have passed after ns4 was restarted" 2203# shellcheck disable=SC2016 2204$PERL -e 'my $delay = '"$start"' + 12 - time(); select(undef, undef, undef, $delay) if ($delay > 0);' 2205 2206# secure.example. should now return an AD=0 answer (non-authenticated) 2207# as the NTA is still there. 2208dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.3 || ret=1 2209grep "status: SERVFAIL" dig.out.ns4.test$n.3 > /dev/null && ret=1 2210grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.3 > /dev/null && ret=1 2211 2212# cleanup 2213rndccmd 10.53.0.4 nta -remove secure.example > rndc.out.ns4.test$n.4 2>/dev/null 2214 2215if [ "$ret" -ne 0 ]; then echo_i "failed - NTA persistence: loading forced NTAs failed"; fi 2216status=$((status+ret)) 2217ret=0 2218 2219# 2220# check that NTA lifetime read from file is clamped to 1 week. 2221# 2222n=$((n+1)) 2223echo_i "testing loading out of bounds lifetime from NTA file ($n)" 2224 2225echo_i "killing ns4 with SIGTERM" 2226$KILL -TERM "$(cat ns4/named.pid)" 2227rm -f ns4/named.pid 2228 2229echo_i "sleeping for an additional 4 seconds for ns4 to fully shutdown" 2230sleep 4 2231 2232# 2233# ns4 has now shutdown. add NTA for secure.example. directly into the 2234# _default.nta file with a lifetime well into the future. 2235# 2236echo "secure.example. forced $future" > ns4/_default.nta 2237added=$($PERL -e 'print time()."\n";') 2238 2239if 2240 $PERL "$SYSTEMTESTTOP/start.pl" --noclean --restart --port "$PORT" dnssec ns4 2241then 2242 echo_i "restarted server ns4" 2243else 2244 echo_i "could not restart server ns4" 2245 exit 1 2246fi 2247 2248echo_i "sleeping for an additional 4 seconds for ns4 to fully startup" 2249sleep 4 2250 2251# dump the NTA to a file (omit validate-except entries) 2252echo_i "testing 'rndc nta'" 2253rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 2>/dev/null 2254# "corp" is configured as a validate-except domain and thus should be 2255# omitted. only "secure.example" should be in the dump at this point. 2256lines=$(wc -l < rndc.out.ns4.test$n.1) 2257[ "$lines" -eq 1 ] || ret=1 2258grep 'secure.example' rndc.out.ns4.test$n.1 > /dev/null || ret=1 2259ts=$(awk '{print $3" "$4}' < rndc.out.ns4.test$n.1) 2260# rndc nta outputs localtime, so append the timezone 2261ts_with_zone="$ts $(date +%z)" 2262echo "ts=$ts" > rndc.out.ns4.test$n.2 2263echo "ts_with_zone=$ts_with_zone" >> rndc.out.ns4.test$n.2 2264echo "added=$added" >> rndc.out.ns4.test$n.2 2265if $PERL -e 'use Time::Piece; use Time::Seconds;' 2>/dev/null 2266then 2267 # ntadiff.pl computes $ts_with_zone - ($added + 1week) 2268 d=$($PERL ./ntadiff.pl "$ts_with_zone" "$added") 2269 echo "d=$d" >> rndc.out.ns4.test$n.2 2270 # diff from $added(now) + 1week to the clamped NTA lifetime should be 2271 # less than a few seconds (handle daylight saving changes by adding 3600). 2272 [ "$d" -lt 3610 ] || ret=1 2273else 2274 echo_i "skipped ntadiff test; install PERL module Time::Piece" 2275fi 2276 2277# cleanup 2278rndccmd 10.53.0.4 nta -remove secure.example > rndc.out.ns4.test$n.3 2>/dev/null 2279 2280n=$((n+1)) 2281if [ "$ret" -ne 0 ]; then echo_i "failed - NTA lifetime clamping failed"; fi 2282status=$((status+ret)) 2283 2284echo_i "checking that NTAs work with 'forward only;' to a validating resolver ($n)" 2285ret=0 2286# Sanity check behavior without an NTA in place. 2287dig_with_opts @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.1 || ret=1 2288grep "SERVFAIL" dig.out.ns9.test$n.1 > /dev/null || ret=1 2289grep "ANSWER: 0" dig.out.ns9.test$n.1 > /dev/null || ret=1 2290grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.1 > /dev/null && ret=1 2291# Add an NTA, expecting that to cause resolution to succeed. 2292rndccmd 10.53.0.9 nta badds.example > rndc.out.ns9.test$n.1 2>&1 || ret=1 2293dig_with_opts @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.2 || ret=1 2294grep "NOERROR" dig.out.ns9.test$n.2 > /dev/null || ret=1 2295grep "ANSWER: 2" dig.out.ns9.test$n.2 > /dev/null || ret=1 2296grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.2 > /dev/null && ret=1 2297# Remove the NTA, expecting that to cause resolution to fail again. 2298rndccmd 10.53.0.9 nta -remove badds.example > rndc.out.ns9.test$n.2 2>&1 || ret=1 2299dig_with_opts @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.3 || ret=1 2300grep "SERVFAIL" dig.out.ns9.test$n.3 > /dev/null || ret=1 2301grep "ANSWER: 0" dig.out.ns9.test$n.3 > /dev/null || ret=1 2302grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.3 > /dev/null && ret=1 2303if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 2304status=$((status+ret)) 2305 2306echo_i "completed NTA tests" 2307 2308# Run a minimal update test if possible. This is really just 2309# a regression test for RT #2399; more tests should be added. 2310 2311if $PERL -e 'use Net::DNS;' 2>/dev/null 2312then 2313 echo_i "running DNSSEC update test" 2314 ret=0 2315 output=$($PERL dnssec_update_test.pl -s 10.53.0.3 -p "$PORT" dynamic.example.) 2316 test "$?" -eq 0 || ret=1 2317 echo "$output" | cat_i 2318 [ $ret -eq 1 ] && status=1 2319else 2320 echo_i "The DNSSEC update test requires the Net::DNS library." >&2 2321fi 2322 2323n=$((n+1)) 2324echo_i "checking managed key maintenance has not started yet ($n)" 2325ret=0 2326[ -f "ns4/managed-keys.bind.jnl" ] && ret=1 2327n=$((n+1)) 2328test "$ret" -eq 0 || echo_i "failed" 2329status=$((status+ret)) 2330 2331# Reconfigure caching server to use "dnssec-validation auto", and repeat 2332# some of the DNSSEC validation tests to ensure that it works correctly. 2333echo_i "switching to automatic root key configuration" 2334copy_setports ns4/named2.conf.in ns4/named.conf 2335rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i 2336sleep 5 2337 2338echo_i "checking managed key maintenance timer has now started ($n)" 2339ret=0 2340[ -f "ns4/managed-keys.bind.jnl" ] || ret=1 2341n=$((n+1)) 2342test "$ret" -eq 0 || echo_i "failed" 2343status=$((status+ret)) 2344 2345echo_i "checking positive validation NSEC ($n)" 2346ret=0 2347dig_with_opts +noauth a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 2348dig_with_opts +noauth a.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 2349digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 2350grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 2351n=$((n+1)) 2352test "$ret" -eq 0 || echo_i "failed" 2353status=$((status+ret)) 2354 2355echo_i "checking positive validation NSEC3 ($n)" 2356ret=0 2357dig_with_opts +noauth a.nsec3.example. \ 2358 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 2359dig_with_opts +noauth a.nsec3.example. \ 2360 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 2361digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 2362grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 2363n=$((n+1)) 2364test "$ret" -eq 0 || echo_i "failed" 2365status=$((status+ret)) 2366 2367echo_i "checking positive validation OPTOUT ($n)" 2368ret=0 2369dig_with_opts +noauth a.optout.example. \ 2370 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 2371dig_with_opts +noauth a.optout.example. \ 2372 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 2373digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 2374grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 2375n=$((n+1)) 2376test "$ret" -eq 0 || echo_i "failed" 2377status=$((status+ret)) 2378 2379echo_i "checking negative validation ($n)" 2380ret=0 2381dig_with_opts +noauth q.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 2382dig_with_opts +noauth q.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 2383digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 2384grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 2385grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 2386n=$((n+1)) 2387test "$ret" -eq 0 || echo_i "failed" 2388status=$((status+ret)) 2389 2390echo_i "checking that root DS queries validate ($n)" 2391ret=0 2392dig_with_opts +noauth . @10.53.0.1 ds > dig.out.ns1.test$n || ret=1 2393dig_with_opts +noauth . @10.53.0.4 ds > dig.out.ns4.test$n || ret=1 2394digcomp dig.out.ns1.test$n dig.out.ns4.test$n || ret=1 2395grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 2396grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2397n=$((n+1)) 2398test "$ret" -eq 0 || echo_i "failed" 2399status=$((status+ret)) 2400 2401echo_i "checking that DS at a RFC 1918 empty zone lookup succeeds ($n)" 2402ret=0 2403dig_with_opts +noauth 10.in-addr.arpa ds @10.53.0.2 >dig.out.ns2.test$n || ret=1 2404dig_with_opts +noauth 10.in-addr.arpa ds @10.53.0.4 >dig.out.ns6.test$n || ret=1 2405digcomp dig.out.ns2.test$n dig.out.ns6.test$n || ret=1 2406grep "status: NOERROR" dig.out.ns6.test$n > /dev/null || ret=1 2407n=$((n+1)) 2408test "$ret" -eq 0 || echo_i "failed" 2409status=$((status+ret)) 2410 2411echo_i "checking expired signatures remain with "'"allow-update { none; };"'" and no keys available ($n)" 2412ret=0 2413dig_with_opts +noauth expired.example. +dnssec @10.53.0.3 soa > dig.out.ns3.test$n || ret=1 2414grep "RRSIG.SOA" dig.out.ns3.test$n > /dev/null || ret=1 2415n=$((n+1)) 2416test "$ret" -eq 0 || echo_i "failed" 2417 2418status=$((status+ret)) 2419echo_i "checking expired signatures do not validate ($n)" 2420ret=0 2421dig_with_opts +noauth expired.example. +dnssec @10.53.0.4 soa > dig.out.ns4.test$n || ret=1 2422grep "SERVFAIL" dig.out.ns4.test$n > /dev/null || ret=1 2423grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 2424grep "expired.example/.*: RRSIG has expired" ns4/named.run > /dev/null || ret=1 2425n=$((n+1)) 2426test "$ret" -eq 0 || echo_i "failed" 2427status=$((status+ret)) 2428 2429echo_i "checking that the NSEC3 record for the apex is properly signed when a DNSKEY is added via UPDATE ($n)" 2430ret=0 2431( 2432cd ns3 || exit 1 2433kskname=$($KEYGEN -q -3 -a RSASHA1 -fk update-nsec3.example) 2434( 2435echo zone update-nsec3.example 2436echo server 10.53.0.3 "$PORT" 2437grep DNSKEY "${kskname}.key" | sed -e 's/^/update add /' -e 's/IN/300 IN/' 2438echo send 2439) | $NSUPDATE 2440) 2441dig_with_opts +dnssec a update-nsec3.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2442grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2443grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1 2444grep "NSEC3 .* TYPE65534" dig.out.ns4.test$n > /dev/null || ret=1 2445n=$((n+1)) 2446test "$ret" -eq 0 || echo_i "failed" 2447status=$((status+ret)) 2448 2449echo_i "checking that the NSEC record is properly generated when DNSKEY are added via auto-dnssec ($n)" 2450ret=0 2451dig_with_opts +dnssec a auto-nsec.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2452grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2453grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1 2454grep "IN.NSEC[^3].* DNSKEY" dig.out.ns4.test$n > /dev/null || ret=1 2455n=$((n+1)) 2456test "$ret" -eq 0 || echo_i "failed" 2457status=$((status+ret)) 2458 2459echo_i "checking that the NSEC3 record is properly generated when DNSKEY are added via auto-dnssec ($n)" 2460ret=0 2461dig_with_opts +dnssec a auto-nsec3.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2462grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2463grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1 2464grep "IN.NSEC3 .* DNSKEY" dig.out.ns4.test$n > /dev/null || ret=1 2465n=$((n+1)) 2466test "$ret" -eq 0 || echo_i "failed" 2467status=$((status+ret)) 2468 2469echo_i "checking that signing records have been marked as complete ($n)" 2470ret=0 2471checkprivate dynamic.example 10.53.0.3 || ret=1 2472checkprivate update-nsec3.example 10.53.0.3 || ret=1 2473checkprivate auto-nsec3.example 10.53.0.3 || ret=1 2474checkprivate expiring.example 10.53.0.3 || ret=1 2475checkprivate auto-nsec.example 10.53.0.3 || ret=1 2476n=$((n+1)) 2477test "$ret" -eq 0 || echo_i "failed" 2478status=$((status+ret)) 2479 2480echo_i "check that 'rndc signing' without arguments is handled ($n)" 2481ret=0 2482rndccmd 10.53.0.3 signing > /dev/null 2>&1 && ret=1 2483rndccmd 10.53.0.3 status > /dev/null || ret=1 2484n=$((n+1)) 2485test "$ret" -eq 0 || echo_i "failed" 2486status=$((status+ret)) 2487 2488echo_i "check that 'rndc signing -list' without zone is handled ($n)" 2489ret=0 2490rndccmd 10.53.0.3 signing -list > /dev/null 2>&1 && ret=1 2491rndccmd 10.53.0.3 status > /dev/null || ret=1 2492n=$((n+1)) 2493test "$ret" -eq 0 || echo_i "failed" 2494status=$((status+ret)) 2495 2496echo_i "check that 'rndc signing -clear' without additional arguments is handled ($n)" 2497ret=0 2498rndccmd 10.53.0.3 signing -clear > /dev/null 2>&1 && ret=1 2499rndccmd 10.53.0.3 status > /dev/null || ret=1 2500n=$((n+1)) 2501test "$ret" -eq 0 || echo_i "failed" 2502status=$((status+ret)) 2503 2504echo_i "check that 'rndc signing -clear all' without zone is handled ($n)" 2505ret=0 2506rndccmd 10.53.0.3 signing -clear all > /dev/null 2>&1 && ret=1 2507rndccmd 10.53.0.3 status > /dev/null || ret=1 2508n=$((n+1)) 2509test "$ret" -eq 0 || echo_i "failed" 2510status=$((status+ret)) 2511 2512echo_i "check that 'rndc signing -nsec3param' without additional arguments is handled ($n)" 2513ret=0 2514rndccmd 10.53.0.3 signing -nsec3param > /dev/null 2>&1 && ret=1 2515rndccmd 10.53.0.3 status > /dev/null || ret=1 2516n=$((n+1)) 2517test "$ret" -eq 0 || echo_i "failed" 2518status=$((status+ret)) 2519 2520echo_i "check that 'rndc signing -nsec3param none' without zone is handled ($n)" 2521ret=0 2522rndccmd 10.53.0.3 signing -nsec3param none > /dev/null 2>&1 && ret=1 2523rndccmd 10.53.0.3 status > /dev/null || ret=1 2524n=$((n+1)) 2525test "$ret" -eq 0 || echo_i "failed" 2526status=$((status+ret)) 2527 2528echo_i "check that 'rndc signing -nsec3param 1' without additional arguments is handled ($n)" 2529ret=0 2530rndccmd 10.53.0.3 signing -nsec3param 1 > /dev/null 2>&1 && ret=1 2531rndccmd 10.53.0.3 status > /dev/null || ret=1 2532n=$((n+1)) 2533test "$ret" -eq 0 || echo_i "failed" 2534status=$((status+ret)) 2535 2536echo_i "check that 'rndc signing -nsec3param 1 0' without additional arguments is handled ($n)" 2537ret=0 2538rndccmd 10.53.0.3 signing -nsec3param 1 0 > /dev/null 2>&1 && ret=1 2539rndccmd 10.53.0.3 status > /dev/null || ret=1 2540n=$((n+1)) 2541test "$ret" -eq 0 || echo_i "failed" 2542status=$((status+ret)) 2543 2544echo_i "check that 'rndc signing -nsec3param 1 0 0' without additional arguments is handled ($n)" 2545ret=0 2546rndccmd 10.53.0.3 signing -nsec3param 1 0 0 > /dev/null 2>&1 && ret=1 2547rndccmd 10.53.0.3 status > /dev/null || ret=1 2548n=$((n+1)) 2549test "$ret" -eq 0 || echo_i "failed" 2550status=$((status+ret)) 2551 2552echo_i "check that 'rndc signing -nsec3param 1 0 0 -' without zone is handled ($n)" 2553ret=0 2554rndccmd 10.53.0.3 signing -nsec3param 1 0 0 - > /dev/null 2>&1 && ret=1 2555rndccmd 10.53.0.3 status > /dev/null || ret=1 2556n=$((n+1)) 2557test "$ret" -eq 0 || echo_i "failed" 2558status=$((status+ret)) 2559 2560echo_i "check that 'rndc signing -nsec3param' works with salt ($n)" 2561ret=0 2562rndccmd 10.53.0.3 signing -nsec3param 1 0 0 ffff inline.example > /dev/null 2>&1 || ret=1 2563rndccmd 10.53.0.3 status > /dev/null || ret=1 2564for i in 1 2 3 4 5 6 7 8 9 10 ; do 2565 salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}') 2566 if [ "$salt" = "FFFF" ]; then 2567 break; 2568 fi 2569 echo_i "sleeping ...." 2570 sleep 1 2571done; 2572[ "$salt" = "FFFF" ] || ret=1 2573n=$((n+1)) 2574test "$ret" -eq 0 || echo_i "failed" 2575status=$((status+ret)) 2576 2577echo_i "check that 'rndc signing -nsec3param' works without salt ($n)" 2578ret=0 2579rndccmd 10.53.0.3 signing -nsec3param 1 0 0 - inline.example > /dev/null 2>&1 || ret=1 2580rndccmd 10.53.0.3 status > /dev/null || ret=1 2581for i in 1 2 3 4 5 6 7 8 9 10 ; do 2582 salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}') 2583 if [ "$salt" = "-" ]; then 2584 break; 2585 fi 2586 echo_i "sleeping ...." 2587 sleep 1 2588done; 2589[ "$salt" = "-" ] || ret=1 2590n=$((n+1)) 2591test "$ret" -eq 0 || echo_i "failed" 2592status=$((status+ret)) 2593 2594echo_i "check that 'rndc signing -nsec3param' works with 'auto' as salt ($n)" 2595ret=0 2596rndccmd 10.53.0.3 signing -nsec3param 1 0 0 auto inline.example > /dev/null 2>&1 || ret=1 2597rndccmd 10.53.0.3 status > /dev/null || ret=1 2598for i in 1 2 3 4 5 6 7 8 9 10 ; do 2599 salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}') 2600 [ -n "$salt" ] && [ "$salt" != "-" ] && break 2601 echo_i "sleeping ...." 2602 sleep 1 2603done; 2604[ "$salt" != "-" ] || ret=1 2605[ "${#salt}" -eq 16 ] || ret=1 2606n=$((n+1)) 2607test "$ret" -eq 0 || echo_i "failed" 2608status=$((status+ret)) 2609 2610echo_i "check that 'rndc signing -nsec3param' with 'auto' as salt again generates a different salt ($n)" 2611ret=0 2612oldsalt=$salt 2613rndccmd 10.53.0.3 signing -nsec3param 1 0 0 auto inline.example > /dev/null 2>&1 || ret=1 2614rndccmd 10.53.0.3 status > /dev/null || ret=1 2615for i in 1 2 3 4 5 6 7 8 9 10 ; do 2616 salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}') 2617 [ -n "$salt" ] && [ "$salt" != "$oldsalt" ] && break 2618 echo_i "sleeping ...." 2619 sleep 1 2620done; 2621[ "$salt" != "$oldsalt" ] || ret=1 2622[ "${#salt}" -eq 16 ] || ret=1 2623n=$((n+1)) 2624test "$ret" -eq 0 || echo_i "failed" 2625status=$((status+ret)) 2626 2627echo_i "check rndc signing -list output ($n)" 2628ret=0 2629{ rndccmd 10.53.0.3 signing -list dynamic.example > signing.out; } 2>&1 2630grep -q "No signing records found" signing.out || { 2631 ret=1 2632 sed 's/^/ns3 /' signing.out | cat_i 2633} 2634{ rndccmd 10.53.0.3 signing -list update-nsec3.example > signing.out; } 2>&1 2635grep -q "Done signing with key .*/NSEC3RSASHA1" signing.out || { 2636 ret=1 2637 sed 's/^/ns3 /' signing.out | cat_i 2638} 2639n=$((n+1)) 2640test "$ret" -eq 0 || echo_i "failed" 2641status=$((status+ret)) 2642 2643echo_i "clear signing records ($n)" 2644{ rndccmd 10.53.0.3 signing -clear all update-nsec3.example > /dev/null; } 2>&1 || ret=1 2645check_no_signing_record_found() { 2646 { rndccmd 10.53.0.3 signing -list update-nsec3.example > signing.out; } 2>&1 2647 grep -q "No signing records found" signing.out || { 2648 sed 's/^/ns3 /' signing.out | cat_i 2649 return 1 2650 } 2651 return 0 2652} 2653retry_quiet 5 check_no_signing_record_found || ret=1 2654n=$((n+1)) 2655test "$ret" -eq 0 || echo_i "failed" 2656status=$((status+ret)) 2657 2658echo_i "checking that a insecure zone beneath a cname resolves ($n)" 2659ret=0 2660dig_with_opts soa insecure.below-cname.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2661grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2662grep "ANSWER: 1," dig.out.ns4.test$n > /dev/null || ret=1 2663n=$((n+1)) 2664test "$ret" -eq 0 || echo_i "failed" 2665status=$((status+ret)) 2666 2667echo_i "checking that a secure zone beneath a cname resolves ($n)" 2668ret=0 2669dig_with_opts soa secure.below-cname.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2670grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2671grep "ANSWER: 2," dig.out.ns4.test$n > /dev/null || ret=1 2672grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1 2673n=$((n+1)) 2674test "$ret" -eq 0 || echo_i "failed" 2675status=$((status+ret)) 2676 2677my_dig() { 2678 "$DIG" +noadd +nosea +nostat +noquest +nocomm +nocmd -p "$PORT" @10.53.0.4 "$@" 2679} 2680 2681echo_i "checking DNSKEY query with no data still gets put in cache ($n)" 2682ret=0 2683firstVal=$(my_dig insecure.example. dnskey| awk '$1 != ";;" { print $2 }') 2684sleep 1 2685secondVal=$(my_dig insecure.example. dnskey| awk '$1 != ";;" { print $2 }') 2686if [ "${firstVal:-0}" -eq "${secondVal:-0}" ] 2687then 2688 sleep 1 2689 thirdVal=$(my_dig insecure.example. dnskey|awk '$1 != ";;" { print $2 }') 2690 if [ "${firstVal:-0}" -eq "${thirdVal:-0}" ] 2691 then 2692 echo_i "cannot confirm query answer still in cache" 2693 ret=1 2694 fi 2695fi 2696n=$((n+1)) 2697test "$ret" -eq 0 || echo_i "failed" 2698status=$((status+ret)) 2699 2700echo_i "check that a split dnssec dnssec-signzone work ($n)" 2701ret=0 2702dig_with_opts soa split-dnssec.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2703grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2704grep "ANSWER: 2," dig.out.ns4.test$n > /dev/null || ret=1 2705grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1 2706n=$((n+1)) 2707test "$ret" -eq 0 || echo_i "failed" 2708status=$((status+ret)) 2709 2710echo_i "check that a smart split dnssec dnssec-signzone work ($n)" 2711ret=0 2712dig_with_opts soa split-smart.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2713grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2714grep "ANSWER: 2," dig.out.ns4.test$n > /dev/null || ret=1 2715grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1 2716n=$((n+1)) 2717test "$ret" -eq 0 || echo_i "failed" 2718status=$((status+ret)) 2719 2720echo_i "check that NOTIFY is sent at the end of NSEC3 chain generation ($n)" 2721ret=0 2722( 2723echo zone nsec3chain-test 2724echo server 10.53.0.2 "$PORT" 2725echo update add nsec3chain-test. 0 nsec3param 1 0 1 123456 2726echo send 2727) | $NSUPDATE 2728for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 2729do 2730 dig_with_opts nsec3param nsec3chain-test @10.53.0.2 > dig.out.ns2.test$n || ret=1 2731 if grep "ANSWER: 3," dig.out.ns2.test$n >/dev/null 2732 then 2733 break; 2734 fi 2735 echo_i "sleeping ...." 2736 sleep 3 2737done 2738grep "ANSWER: 3," dig.out.ns2.test$n > /dev/null || ret=1 2739if [ "$ret" -ne 0 ]; then echo_i "nsec3 chain generation not complete"; fi 2740dig_with_opts +noauth +nodnssec soa nsec3chain-test @10.53.0.2 > dig.out.ns2.test$n || ret=1 2741s2=$(awk '$4 == "SOA" { print $7}' dig.out.ns2.test$n) 2742for i in 1 2 3 4 5 6 7 8 9 10 2743do 2744 dig_with_opts +noauth +nodnssec soa nsec3chain-test @10.53.0.3 > dig.out.ns3.test$n || ret=1 2745 s3=$(awk '$4 == "SOA" { print $7}' dig.out.ns3.test$n) 2746 test "$s2" = "$s3" && break 2747 sleep 1 2748done 2749digcomp dig.out.ns2.test$n dig.out.ns3.test$n || ret=1 2750n=$((n+1)) 2751test "$ret" -eq 0 || echo_i "failed" 2752status=$((status+ret)) 2753 2754echo_i "check dnssec-dsfromkey from stdin ($n)" 2755ret=0 2756dig_with_opts dnskey algroll. @10.53.0.2 | \ 2757 $DSFROMKEY -f - algroll. > dig.out.ns2.test$n || ret=1 2758NF=$(awk '{print NF}' dig.out.ns2.test$n | sort -u) 2759[ "${NF}" = 7 ] || ret=1 2760# make canonical 2761awk '{ 2762 for (i=1;i<7;i++) printf("%s ", $i); 2763 for (i=7;i<=NF;i++) printf("%s", $i); 2764 printf("\n"); 2765}' < dig.out.ns2.test$n > canonical1.$n || ret=1 2766awk '{ 2767 for (i=1;i<7;i++) printf("%s ", $i); 2768 for (i=7;i<=NF;i++) printf("%s", $i); 2769 printf("\n"); 2770}' < ns1/dsset-algroll$TP > canonical2.$n || ret=1 2771$DIFF -b canonical1.$n canonical2.$n > /dev/null 2>&1 || ret=1 2772n=$((n+1)) 2773test "$ret" -eq 0 || echo_i "failed" 2774status=$((status+ret)) 2775 2776# Intentionally strip ".key" from keyfile name to ensure the error message 2777# includes it anyway to avoid confusion (RT #21731) 2778echo_i "check dnssec-dsfromkey error message when keyfile is not found ($n)" 2779ret=0 2780key=$($KEYGEN -a RSASHA1 -q example.) || ret=1 2781mv "$key.key" "$key" 2782$DSFROMKEY "$key" > dsfromkey.out.$n 2>&1 && ret=1 2783grep "$key.key: file not found" dsfromkey.out.$n > /dev/null || ret=1 2784n=$((n+1)) 2785test "$ret" -eq 0 || echo_i "failed" 2786status=$((status+ret)) 2787 2788echo_i "testing soon-to-expire RRSIGs without a replacement private key ($n)" 2789ret=0 2790dig_with_answeropts +nottlid expiring.example ns @10.53.0.3 | grep RRSIG > dig.out.ns3.test$n 2>&1 2791# there must be a signature here 2792[ -s dig.out.ns3.test$n ] || ret=1 2793n=$((n+1)) 2794test "$ret" -eq 0 || echo_i "failed" 2795status=$((status+ret)) 2796 2797echo_i "testing new records are signed with 'no-resign' ($n)" 2798ret=0 2799( 2800echo zone nosign.example 2801echo server 10.53.0.3 "$PORT" 2802echo update add new.nosign.example 300 in txt "hi there" 2803echo send 2804) | $NSUPDATE 2805sleep 1 2806dig_with_answeropts +nottlid txt new.nosign.example @10.53.0.3 \ 2807 > dig.out.ns3.test$n 2>&1 2808grep RRSIG dig.out.ns3.test$n > /dev/null 2>&1 || ret=1 2809n=$((n+1)) 2810test "$ret" -eq 0 || echo_i "failed" 2811status=$((status+ret)) 2812 2813echo_i "testing expiring records aren't resigned with 'no-resign' ($n)" 2814ret=0 2815dig_with_answeropts +nottlid nosign.example ns @10.53.0.3 | \ 2816 grep RRSIG | sed 's/[ ][ ]*/ /g' > dig.out.ns3.test$n 2>&1 2817# the NS RRSIG should not be changed 2818$DIFF nosign.before dig.out.ns3.test$n > /dev/null|| ret=1 2819n=$((n+1)) 2820test "$ret" -eq 0 || echo_i "failed" 2821status=$((status+ret)) 2822 2823echo_i "testing updates fail with no private key ($n)" 2824ret=0 2825rm -f ns3/Knosign.example.*.private 2826( 2827echo zone nosign.example 2828echo server 10.53.0.3 "$PORT" 2829echo update add fail.nosign.example 300 in txt "reject me" 2830echo send 2831) | $NSUPDATE > /dev/null 2>&1 && ret=1 2832dig_with_answeropts +nottlid fail.nosign.example txt @10.53.0.3 \ 2833 > dig.out.ns3.test$n 2>&1 2834[ -s dig.out.ns3.test$n ] && ret=1 2835n=$((n+1)) 2836test "$ret" -eq 0 || echo_i "failed" 2837status=$((status+ret)) 2838 2839echo_i "testing legacy upper case signer name validation ($n)" 2840ret=0 2841$DIG +tcp +noadd +noauth +dnssec -p "$PORT" soa upper.example @10.53.0.4 \ 2842 > dig.out.ns4.test$n 2>&1 2843grep "flags:.* ad;" dig.out.ns4.test$n > /dev/null || ret=1 2844grep "RRSIG.*SOA.* UPPER\\.EXAMPLE\\. " dig.out.ns4.test$n > /dev/null || ret=1 2845n=$((n+1)) 2846test "$ret" -eq 0 || echo_i "failed" 2847status=$((status+ret)) 2848 2849echo_i "testing that we lower case signer name ($n)" 2850ret=0 2851$DIG +tcp +noadd +noauth +dnssec -p "$PORT" soa LOWER.EXAMPLE @10.53.0.4 \ 2852 > dig.out.ns4.test$n 2>&1 2853grep "flags:.* ad;" dig.out.ns4.test$n > /dev/null || ret=1 2854grep "RRSIG.*SOA.* lower\\.example\\. " dig.out.ns4.test$n > /dev/null || ret=1 2855n=$((n+1)) 2856test "$ret" -eq 0 || echo_i "failed" 2857status=$((status+ret)) 2858 2859echo_i "testing TTL is capped at RRSIG expiry time ($n)" 2860ret=0 2861rndccmd 10.53.0.3 freeze expiring.example 2>&1 | sed 's/^/ns3 /' | cat_i 2862( 2863cd ns3 || exit 1 2864for file in K*.moved; do 2865 mv "$file" "$(basename "$file" .moved)" 2866done 2867$SIGNER -S -N increment -e now+1mi -o expiring.example expiring.example.db > /dev/null 2868) || ret=1 2869rndc_reload ns3 10.53.0.3 expiring.example 2870 2871rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i 2872dig_with_answeropts +cd expiring.example soa @10.53.0.4 > dig.out.ns4.1.$n 2873dig_with_answeropts expiring.example soa @10.53.0.4 > dig.out.ns4.2.$n 2874ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n) 2875ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n) 2876for ttl in ${ttls:-0}; do 2877 [ "${ttl}" -eq 300 ] || ret=1 2878done 2879for ttl in ${ttls2:-0}; do 2880 [ "${ttl}" -le 60 ] || ret=1 2881done 2882n=$((n+1)) 2883test "$ret" -eq 0 || echo_i "failed" 2884status=$((status+ret)) 2885 2886echo_i "testing TTL is capped at RRSIG expiry time for records in the additional section (NS) ($n)" 2887ret=0 2888rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i 2889sleep 1 2890dig_with_additionalopts +cd expiring.example ns @10.53.0.4 > dig.out.ns4.1.$n 2891dig_with_additionalopts expiring.example ns @10.53.0.4 > dig.out.ns4.2.$n 2892ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n) 2893ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n) 2894for ttl in ${ttls:-300}; do 2895 [ "$ttl" -le 300 ] && [ "$ttl" -gt 240 ] || ret=1 2896done 2897for ttl in ${ttls2:-0}; do 2898 [ "$ttl" -le 60 ] || ret=1 2899done 2900n=$((n+1)) 2901test "$ret" -eq 0 || echo_i "failed" 2902status=$((status+ret)) 2903 2904echo_i "testing TTL is capped at RRSIG expiry time for records in the additional section (MX) ($n)" 2905ret=0 2906rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i 2907sleep 1 2908dig_with_additionalopts +cd expiring.example mx @10.53.0.4 > dig.out.ns4.1.$n 2909dig_with_additionalopts expiring.example mx @10.53.0.4 > dig.out.ns4.2.$n 2910ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n) 2911ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n) 2912for ttl in ${ttls:-300}; do 2913 [ "$ttl" -le 300 ] && [ "$ttl" -gt 240 ] || ret=1 2914done 2915for ttl in ${ttls2:-0}; do 2916 [ "$ttl" -le 60 ] || ret=1 2917done 2918n=$((n+1)) 2919test "$ret" -eq 0 || echo_i "failed" 2920status=$((status+ret)) 2921 2922copy_setports ns4/named3.conf.in ns4/named.conf 2923rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i 2924sleep 3 2925 2926echo_i "testing TTL of about to expire RRsets with dnssec-accept-expired yes; ($n)" 2927ret=0 2928rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i 2929dig_with_answeropts +cd expiring.example soa @10.53.0.4 > dig.out.ns4.1.$n 2930dig_with_answeropts expiring.example soa @10.53.0.4 > dig.out.ns4.2.$n 2931ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n) 2932ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n) 2933for ttl in ${ttls:-0}; do 2934 [ "$ttl" -eq 300 ] || ret=1 2935done 2936for ttl in ${ttls2:-0}; do 2937 [ "$ttl" -eq 120 ] || ret=1 2938done 2939n=$((n+1)) 2940test "$ret" -eq 0 || echo_i "failed" 2941status=$((status+ret)) 2942 2943echo_i "testing TTL of expired RRsets with dnssec-accept-expired yes; ($n)" 2944ret=0 2945dig_with_answeropts +cd expired.example soa @10.53.0.4 > dig.out.ns4.1.$n 2946dig_with_answeropts expired.example soa @10.53.0.4 > dig.out.ns4.2.$n 2947ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n) 2948ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n) 2949for ttl in ${ttls:-0}; do 2950 [ "$ttl" -eq 300 ] || ret=1 2951done 2952for ttl in ${ttls2:-0}; do 2953 [ "$ttl" -eq 120 ] || ret=1 2954done 2955n=$((n+1)) 2956test "$ret" -eq 0 || echo_i "failed" 2957status=$((status+ret)) 2958 2959echo_i "testing TTL is capped at RRSIG expiry time for records in the additional section with dnssec-accept-expired yes; ($n)" 2960ret=0 2961rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i 2962dig_with_additionalopts +cd expiring.example mx @10.53.0.4 > dig.out.ns4.1.$n 2963dig_with_additionalopts expiring.example mx @10.53.0.4 > dig.out.ns4.2.$n 2964ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n) 2965ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n) 2966for ttl in ${ttls:-300}; do 2967 [ "$ttl" -le 300 ] && [ "$ttl" -gt 240 ] || ret=1 2968done 2969for ttl in ${ttls2:-0}; do 2970 [ "$ttl" -le 120 ] && [ "$ttl" -gt 60 ] || ret=1 2971done 2972n=$((n+1)) 2973test "$ret" -eq 0 || echo_i "failed" 2974status=$((status+ret)) 2975 2976echo_i "testing DNSKEY lookup via CNAME ($n)" 2977ret=0 2978dig_with_opts +noauth cnameandkey.secure.example. \ 2979 @10.53.0.3 dnskey > dig.out.ns3.test$n || ret=1 2980dig_with_opts +noauth cnameandkey.secure.example. \ 2981 @10.53.0.4 dnskey > dig.out.ns4.test$n || ret=1 2982digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 2983grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 2984grep "CNAME" dig.out.ns4.test$n > /dev/null || ret=1 2985n=$((n+1)) 2986test "$ret" -eq 0 || echo_i "failed" 2987status=$((status+ret)) 2988 2989echo_i "testing KEY lookup at CNAME (present) ($n)" 2990ret=0 2991dig_with_opts +noauth cnameandkey.secure.example. \ 2992 @10.53.0.3 key > dig.out.ns3.test$n || ret=1 2993dig_with_opts +noauth cnameandkey.secure.example. \ 2994 @10.53.0.4 key > dig.out.ns4.test$n || ret=1 2995digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 2996grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 2997grep "CNAME" dig.out.ns4.test$n > /dev/null && ret=1 2998n=$((n+1)) 2999test "$ret" -eq 0 || echo_i "failed" 3000status=$((status+ret)) 3001 3002echo_i "testing KEY lookup at CNAME (not present) ($n)" 3003ret=0 3004dig_with_opts +noauth cnamenokey.secure.example. \ 3005 @10.53.0.3 key > dig.out.ns3.test$n || ret=1 3006dig_with_opts +noauth cnamenokey.secure.example. \ 3007 @10.53.0.4 key > dig.out.ns4.test$n || ret=1 3008digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 3009grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3010grep "CNAME" dig.out.ns4.test$n > /dev/null && ret=1 3011n=$((n+1)) 3012test "$ret" -eq 0 || echo_i "failed" 3013status=$((status+ret)) 3014 3015echo_i "testing DNSKEY lookup via DNAME ($n)" 3016ret=0 3017dig_with_opts a.dnameandkey.secure.example. \ 3018 @10.53.0.3 dnskey > dig.out.ns3.test$n || ret=1 3019dig_with_opts a.dnameandkey.secure.example. \ 3020 @10.53.0.4 dnskey > dig.out.ns4.test$n || ret=1 3021digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 3022grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3023grep "CNAME" dig.out.ns4.test$n > /dev/null || ret=1 3024grep "DNAME" dig.out.ns4.test$n > /dev/null || ret=1 3025n=$((n+1)) 3026test "$ret" -eq 0 || echo_i "failed" 3027status=$((status+ret)) 3028 3029echo_i "testing KEY lookup via DNAME ($n)" 3030ret=0 3031dig_with_opts b.dnameandkey.secure.example. \ 3032 @10.53.0.3 key > dig.out.ns3.test$n || ret=1 3033dig_with_opts b.dnameandkey.secure.example. \ 3034 @10.53.0.4 key > dig.out.ns4.test$n || ret=1 3035digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 3036grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3037grep "DNAME" dig.out.ns4.test$n > /dev/null || ret=1 3038n=$((n+1)) 3039test "$ret" -eq 0 || echo_i "failed" 3040status=$((status+ret)) 3041 3042echo_i "check that named doesn't loop when all private keys are not available ($n)" 3043ret=0 3044lines=$(grep -c "reading private key file expiring.example" ns3/named.run || true) 3045test "${lines:-1000}" -lt 15 || ret=1 3046n=$((n+1)) 3047test "$ret" -eq 0 || echo_i "failed" 3048status=$((status+ret)) 3049 3050echo_i "check against against missing nearest provable proof ($n)" 3051dig_with_opts +norec b.c.d.optout-tld. \ 3052 @10.53.0.6 ds > dig.out.ds.ns6.test$n || ret=1 3053nsec3=$(grep -c "IN.NSEC3" dig.out.ds.ns6.test$n || true) 3054[ "$nsec3" -eq 2 ] || ret=1 3055dig_with_opts +norec b.c.d.optout-tld. \ 3056 @10.53.0.6 A > dig.out.ns6.test$n || ret=1 3057nsec3=$(grep -c "IN.NSEC3" dig.out.ns6.test$n || true) 3058[ "$nsec3" -eq 1 ] || ret=1 3059dig_with_opts optout-tld. \ 3060 @10.53.0.4 SOA > dig.out.soa.ns4.test$n || ret=1 3061grep "flags:.*ad.*QUERY" dig.out.soa.ns4.test$n > /dev/null || ret=1 3062dig_with_opts b.c.d.optout-tld. \ 3063 @10.53.0.4 A > dig.out.ns4.test$n || ret=1 3064grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 3065grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 3066n=$((n+1)) 3067test "$ret" -eq 0 || echo_i "failed" 3068status=$((status+ret)) 3069 3070echo_i "check that key id are logged when dumping the cache ($n)" 3071ret=0 3072rndc_dumpdb ns4 3073grep "; key id = " ns4/named_dump.db.test$n > /dev/null || ret=1 3074n=$((n+1)) 3075test "$ret" -eq 0 || echo_i "failed" 3076status=$((status+ret)) 3077 3078echo_i "check KEYDATA records are printed in human readable form in key zone ($n)" 3079# force the managed-keys zone to be written out 3080rndccmd 10.53.0.4 managed-keys sync 2>&1 | sed 's/^/ns4 /' | cat_i 3081for i in 1 2 3 4 5 6 7 8 9 3082do 3083 ret=0 3084 if test -f ns4/managed-keys.bind 3085 then 3086 grep KEYDATA ns4/managed-keys.bind > /dev/null && 3087 grep "next refresh:" ns4/managed-keys.bind > /dev/null && 3088 break 3089 fi 3090 ret=1 3091 sleep 1 3092done 3093n=$((n+1)) 3094test "$ret" -eq 0 || echo_i "failed" 3095status=$((status+ret)) 3096 3097echo_i "check dig's +nocrypto flag ($n)" 3098ret=0 3099dig_with_opts +norec +nocrypto DNSKEY . \ 3100 @10.53.0.1 > dig.out.dnskey.ns1.test$n || ret=1 3101grep -E "256 [0-9]+ $DEFAULT_ALGORITHM_NUMBER \\[key id = [1-9][0-9]*]" dig.out.dnskey.ns1.test$n > /dev/null || ret=1 3102grep -E "RRSIG.* \\[omitted]" dig.out.dnskey.ns1.test$n > /dev/null || ret=1 3103dig_with_opts +norec +nocrypto DS example \ 3104 @10.53.0.1 > dig.out.ds.ns1.test$n || ret=1 3105grep -E "DS.* [0-9]+ [12] \[omitted]" dig.out.ds.ns1.test$n > /dev/null || ret=1 3106n=$((n+1)) 3107test "$ret" -eq 0 || echo_i "failed" 3108status=$((status+ret)) 3109 3110echo_i "check simultaneous inactivation and publishing of dnskeys removes inactive signature ($n)" 3111ret=0 3112cnt=0 3113while : 3114do 3115dig_with_opts publish-inactive.example @10.53.0.3 dnskey > dig.out.ns3.test$n 3116keys=$(awk '$5 == 257 { print; }' dig.out.ns3.test$n | wc -l) 3117test "$keys" -gt 2 && break 3118cnt=$((cnt+1)) 3119test "$cnt" -gt 120 && break 3120sleep 1 3121done 3122test "$keys" -gt 2 || ret=1 3123sigs=$(grep -c RRSIG dig.out.ns3.test$n || true) 3124n=$((n+1)) 3125test "$sigs" -eq 2 || ret=1 3126if test "$ret" -ne 0 ; then echo_i "failed"; fi 3127status=$((status+ret)) 3128 3129echo_i "check that increasing the sig-validity-interval resigning triggers re-signing ($n)" 3130ret=0 3131before=$($DIG axfr siginterval.example -p "$PORT" @10.53.0.3 | grep RRSIG.SOA) 3132cp ns3/siginterval2.conf ns3/siginterval.conf 3133rndccmd 10.53.0.3 reconfig 2>&1 | sed 's/^/ns3 /' | cat_i 3134i=10 3135while [ "$i" -ge 0 ]; do 3136after=$($DIG axfr siginterval.example -p "$PORT" @10.53.0.3 | grep RRSIG.SOA) 3137test "$before" != "$after" && break 3138sleep 1 3139i=$((i-1)) 3140done 3141n=$((n+1)) 3142if test "$before" = "$after" ; then echo_i "failed"; ret=1; fi 3143status=$((status+ret)) 3144 3145if [ -x "$PYTHON" ]; then 3146 echo_i "check dnskey-sig-validity sets longer expiry for DNSKEY ($n)" 3147 ret=0 3148 rndccmd 10.53.0.3 sign siginterval.example 2>&1 | sed 's/^/ns3 /' | cat_i 3149 # convert expiry date to a comma-separated list of integers python can 3150 # use as input to date(). strip leading 0s in months and days so 3151 # python3 will recognize them as integers. 3152 $DIG +dnssec +short -p "$PORT" @10.53.0.3 soa siginterval.example > dig.out.soa.test$n 3153 soaexpire=$(awk '$1 ~ /SOA/ { print $5 }' dig.out.soa.test$n | 3154 sed 's/\(....\)\(..\)\(..\).*/\1, \2, \3/' | 3155 sed 's/ 0/ /g') 3156 $DIG +dnssec +short -p "$PORT" @10.53.0.3 dnskey siginterval.example > dig.out.dnskey.test$n 3157 dnskeyexpire=$(awk '$1 ~ /DNSKEY/ { print $5; exit 0 }' dig.out.dnskey.test$n | 3158 sed 's/\(....\)\(..\)\(..\).*/\1, \2, \3/' | 3159 sed 's/ 0/ /g') 3160 $PYTHON > python.out.$n <<EOF 3161from datetime import date; 3162ke=date($dnskeyexpire) 3163se=date($soaexpire) 3164print((ke-se).days); 3165EOF 3166 diff=$(cat python.out.$n) 3167 [ "$diff" -ge 55 ] || ret=1 3168 n=$((n+1)) 3169 test "$ret" -eq 0 || echo_i "failed" 3170 status=$((status+ret)) 3171fi 3172 3173copy_setports ns4/named4.conf.in ns4/named.conf 3174rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i 3175sleep 3 3176 3177echo_i "check insecure delegation between static-stub zones ($n)" 3178ret=0 3179dig_with_opts ns insecure.secure.example \ 3180 @10.53.0.4 > dig.out.ns4.1.test$n || ret=1 3181grep "SERVFAIL" dig.out.ns4.1.test$n > /dev/null && ret=1 3182dig_with_opts ns secure.example \ 3183 @10.53.0.4 > dig.out.ns4.2.test$n || ret=1 3184grep "SERVFAIL" dig.out.ns4.2.test$n > /dev/null && ret=1 3185n=$((n+1)) 3186test "$ret" -eq 0 || echo_i "failed" 3187status=$((status+ret)) 3188 3189echo_i "check the acceptance of seconds as inception and expiration times ($n)" 3190ret=0 3191in="NSEC 8 0 86400 1390003200 1389394800 33655 . NYWjZYBV1b+h4j0yu/SmPOOylR8P4IXKDzHX3NwEmU1SUp27aJ91dP+i+UBcnPmBib0hck4DrFVvpflCEpCnVQd2DexcN0GX+3PM7XobxhtDlmnU X1L47zJlbdHNwTqHuPaMM6Xy9HGMXps7O5JVyfggVhTz2C+G5OVxBdb2rOo=" 3192 3193exp="NSEC 8 0 86400 20140118000000 20140110230000 33655 . NYWjZYBV1b+h4j0yu/SmPOOylR8P4IXKDzHX3NwEmU1SUp27aJ91dP+i +UBcnPmBib0hck4DrFVvpflCEpCnVQd2DexcN0GX+3PM7XobxhtDlmnU X1L47zJlbdHNwTqHuPaMM6Xy9HGMXps7O5JVyfggVhTz2C+G5OVxBdb2 rOo=" 3194 3195out=$(echo "IN RRSIG $in" | $RRCHECKER -p | sed 's/^IN.RRSIG.//') 3196[ "$out" = "$exp" ] || ret=1 3197n=$((n+1)) 3198test "$ret" -eq 0 || echo_i "failed" 3199status=$((status+ret)) 3200 3201echo_i "check the correct resigning time is reported in zonestatus ($n)" 3202ret=0 3203rndccmd 10.53.0.3 \ 3204 zonestatus secure.example > rndc.out.ns3.test$n 3205# next resign node: secure.example/DNSKEY 3206qname=$(awk '/next resign node:/ { print $4 }' rndc.out.ns3.test$n | sed 's,/.*,,') 3207qtype=$(awk '/next resign node:/ { print $4 }' rndc.out.ns3.test$n | sed 's,.*/,,') 3208# next resign time: Thu, 24 Apr 2014 10:38:16 GMT 3209time=$(awk 'BEGIN { m["Jan"] = "01"; m["Feb"] = "02"; m["Mar"] = "03"; 3210 m["Apr"] = "04"; m["May"] = "05"; m["Jun"] = "06"; 3211 m["Jul"] = "07"; m["Aug"] = "08"; m["Sep"] = "09"; 3212 m["Oct"] = "10"; m["Nov"] = "11"; m["Dec"] = "12";} 3213 /next resign time:/ { printf "%d%s%02d%s\n", $7, m[$6], $5, $8 }' rndc.out.ns3.test$n | sed 's/://g') 3214dig_with_opts +noall +answer "$qname" "$qtype" @10.53.0.3 > dig.out.test$n 3215expire=$(awk '$4 == "RRSIG" { print $9 }' dig.out.test$n) 3216inception=$(awk '$4 == "RRSIG" { print $10 }' dig.out.test$n) 3217$PERL -e 'exit(0) if ("'"$time"'" lt "'"$expire"'" && "'"$time"'" gt "'"$inception"'"); exit(1);' || ret=1 3218n=$((n+1)) 3219test "$ret" -eq 0 || echo_i "failed" 3220status=$((status+ret)) 3221 3222echo_i "check that split rrsigs are handled ($n)" 3223ret=0 3224dig_with_opts split-rrsig soa @10.53.0.7 > dig.out.test$n || ret=1 3225awk 'BEGIN { ok=0; } $4 == "SOA" { if ($7 > 1) ok=1; } END { if (!ok) exit(1); }' dig.out.test$n || ret=1 3226n=$((n+1)) 3227test "$ret" -eq 0 || echo_i "failed" 3228status=$((status+ret)) 3229 3230echo_i "check that 'dnssec-keygen -S' works for all supported algorithms ($n)" 3231ret=0 3232alg=1 3233until test $alg -eq 256 3234do 3235 zone="keygen-$alg." 3236 case $alg in 3237 2) # Diffie Helman 3238 alg=$((alg+1)) 3239 continue;; 3240 157|160|161|162|163|164|165) # private - non standard 3241 alg=$((alg+1)) 3242 continue;; 3243 1|5|7|8|10) # RSA algorithms 3244 key1=$($KEYGEN -a "$alg" -b "1024" -n zone "$zone" 2> "keygen-$alg.err" || true) 3245 ;; 3246 15|16) 3247 key1=$($KEYGEN -a "$alg" -n zone "$zone" 2> "keygen-$alg.err" || true) 3248 # Soft-fail in case HSM doesn't support Edwards curves 3249 if grep "not found" "keygen-$alg.err" > /dev/null && [ "$CRYPTO" = "pkcs11" ]; then 3250 echo_i "Algorithm $alg not supported by HSM: skipping" 3251 alg=$((alg+1)) 3252 continue 3253 fi 3254 ;; 3255 *) 3256 key1=$($KEYGEN -a "$alg" -n zone "$zone" 2> "keygen-$alg.err" || true) 3257 esac 3258 if grep "unsupported algorithm" "keygen-$alg.err" > /dev/null 3259 then 3260 alg=$((alg+1)) 3261 continue 3262 fi 3263 if test -z "$key1" 3264 then 3265 echo_i "'$KEYGEN -a $alg': failed" 3266 cat "keygen-$alg.err" 3267 ret=1 3268 alg=$((alg+1)) 3269 continue 3270 fi 3271 $SETTIME -I now+4d "$key1.private" > /dev/null 3272 key2=$($KEYGEN -v 10 -i 3d -S "$key1.private" 2> /dev/null) 3273 test -f "$key2.key" -a -f "$key2.private" || { 3274 ret=1 3275 echo_i "'dnssec-keygen -S' failed for algorithm: $alg" 3276 } 3277 alg=$((alg+1)) 3278done 3279n=$((n+1)) 3280test "$ret" -eq 0 || echo_i "failed" 3281status=$((status+ret)) 3282 3283echo_i "check that CDS records are signed using KSK by dnssec-signzone ($n)" 3284ret=0 3285dig_with_opts +noall +answer @10.53.0.2 cds cds.secure > dig.out.test$n 3286lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3287test "$lines" -eq 2 || ret=1 3288n=$((n+1)) 3289test "$ret" -eq 0 || echo_i "failed" 3290status=$((status+ret)) 3291 3292echo_i "check that CDS records are not signed using ZSK by dnssec-signzone -x ($n)" 3293ret=0 3294dig_with_opts +noall +answer @10.53.0.2 cds cds-x.secure > dig.out.test$n 3295lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3296test "$lines" -eq 2 || ret=1 3297n=$((n+1)) 3298test "$ret" -eq 0 || echo_i "failed" 3299status=$((status+ret)) 3300 3301echo_i "checking that positive unknown NSEC3 hash algorithm does validate ($n)" 3302ret=0 3303dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 nsec3-unknown.example SOA > dig.out.ns3.test$n 3304dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 nsec3-unknown.example SOA > dig.out.ns4.test$n 3305grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3306grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1 3307grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3308grep "ANSWER: 1," dig.out.ns4.test$n > /dev/null || ret=1 3309n=$((n+1)) 3310test "$ret" -eq 0 || echo_i "failed" 3311status=$((status+ret)) 3312 3313echo_i "check that CDS records are signed using KSK by with dnssec-auto ($n)" 3314ret=0 3315dig_with_opts +noall +answer @10.53.0.2 cds cds-auto.secure > dig.out.test$n 3316lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3317test "$lines" -eq 2 || ret=1 3318n=$((n+1)) 3319test "$ret" -eq 0 || echo_i "failed" 3320status=$((status+ret)) 3321 3322echo_i "check that a lone non matching CDS record is rejected ($n)" 3323ret=0 3324( 3325echo zone cds-update.secure 3326echo server 10.53.0.2 "$PORT" 3327echo update delete cds-update.secure CDS 3328dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure | 3329grep "DNSKEY.257" | sed 's/DNSKEY.257/DNSKEY 258/' | 3330$DSFROMKEY -C -A -f - -T 1 cds-update.secure | 3331sed "s/^/update add /" 3332echo send 3333) | $NSUPDATE > nsupdate.out.test$n 2>&1 || true 3334grep "update failed: REFUSED" nsupdate.out.test$n > /dev/null || ret=1 3335dig_with_opts +noall +answer @10.53.0.2 cds cds-update.secure > dig.out.test$n 3336lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l) 3337test "${lines:-10}" -eq 0 || ret=1 3338n=$((n+1)) 3339test "$ret" -eq 0 || echo_i "failed" 3340status=$((status+ret)) 3341 3342echo_i "check that a CDS deletion record is accepted ($n)" 3343ret=0 3344( 3345echo zone cds-update.secure 3346echo server 10.53.0.2 "$PORT" 3347echo update delete cds-update.secure CDS 3348echo update add cds-update.secure 0 CDS 0 0 0 00 3349echo send 3350) | $NSUPDATE > nsupdate.out.test$n 2>&1 3351dig_with_opts +noall +answer @10.53.0.2 cds cds-update.secure > dig.out.test$n 3352lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l) 3353test "${lines:-10}" -eq 1 || ret=1 3354lines=$(tr -d '\r' < dig.out.test$n | awk '$4 == "CDS" && $5 == "0" && $6 == "0" && $7 == "0" && $8 == "00" {print}' | wc -l) 3355test "$lines" -eq 1 || ret=1 3356n=$((n+1)) 3357test "$ret" -eq 0 || echo_i "failed" 3358status=$((status+ret)) 3359 3360echo_i "check that CDS records are signed using KSK when added by nsupdate ($n)" 3361ret=0 3362( 3363echo zone cds-update.secure 3364echo server 10.53.0.2 "$PORT" 3365echo update delete cds-update.secure CDS 3366echo send 3367dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure | 3368grep "DNSKEY.257" | 3369$DSFROMKEY -12 -C -f - -T 1 cds-update.secure | 3370sed "s/^/update add /" 3371echo send 3372) | $NSUPDATE 3373dig_with_opts +noall +answer @10.53.0.2 cds cds-update.secure > dig.out.test$n 3374lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3375test "$lines" -eq 2 || ret=1 3376lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l) 3377test "$lines" -eq 2 || ret=1 3378n=$((n+1)) 3379test "$ret" -eq 0 || echo_i "failed" 3380status=$((status+ret)) 3381 3382echo_i "check that CDS records are signed only using KSK when added by" 3383echo_ic "nsupdate when dnssec-dnskey-kskonly is yes ($n)" 3384ret=0 3385keyid=$(cat ns2/cds-kskonly.secure.id) 3386( 3387echo zone cds-kskonly.secure 3388echo server 10.53.0.2 "$PORT" 3389echo update delete cds-kskonly.secure CDS 3390echo send 3391dig_with_opts +noall +answer @10.53.0.2 dnskey cds-kskonly.secure | 3392grep "DNSKEY.257" | 3393$DSFROMKEY -12 -C -f - -T 1 cds-kskonly.secure | 3394sed "s/^/update add /" 3395echo send 3396) | $NSUPDATE 3397dig_with_opts +noall +answer @10.53.0.2 cds cds-kskonly.secure > dig.out.test$n 3398lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3399test "$lines" -eq 1 || ret=1 3400lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDS" && $11 == id {print}' dig.out.test$n | wc -l) 3401test "$lines" -eq 1 || ret=1 3402lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l) 3403test "$lines" -eq 2 || ret=1 3404n=$((n+1)) 3405test "$ret" -eq 0 || echo_i "failed" 3406status=$((status+ret)) 3407 3408echo_i "check that CDS deletion records are signed only using KSK when added by" 3409echo_ic "nsupdate when dnssec-dnskey-kskonly is yes ($n)" 3410ret=0 3411keyid=$(cat ns2/cds-kskonly.secure.id) 3412( 3413echo zone cds-kskonly.secure 3414echo server 10.53.0.2 "$PORT" 3415echo update delete cds-kskonly.secure CDS 3416echo update add cds-kskonly.secure 0 CDS 0 0 0 00 3417echo send 3418) | $NSUPDATE 3419dig_with_opts +noall +answer @10.53.0.2 cds cds-kskonly.secure > dig.out.test$n 3420lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3421test "$lines" -eq 1 || ret=1 3422lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDS" && $11 == id {print}' dig.out.test$n | wc -l) 3423test "$lines" -eq 1 || ret=1 3424lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l) 3425test "$lines" -eq 1 || ret=1 3426lines=$(tr -d '\r' < dig.out.test$n | awk '$4 == "CDS" && $5 == "0" && $6 == "0" && $7 == "0" && $8 == "00" {print}' | wc -l) 3427test "$lines" -eq 1 || ret=1 3428n=$((n+1)) 3429test "$ret" -eq 0 || echo_i "failed" 3430status=$((status+ret)) 3431 3432echo_i "checking that positive unknown NSEC3 hash algorithm with OPTOUT does validate ($n)" 3433ret=0 3434dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 optout-unknown.example SOA > dig.out.ns3.test$n 3435dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 optout-unknown.example SOA > dig.out.ns4.test$n 3436grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3437grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1 3438grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3439grep "ANSWER: 1," dig.out.ns4.test$n > /dev/null || ret=1 3440n=$((n+1)) 3441test "$ret" -eq 0 || echo_i "failed" 3442status=$((status+ret)) 3443 3444echo_i "check that a non matching CDS record is accepted with a matching CDS record ($n)" 3445ret=0 3446( 3447echo zone cds-update.secure 3448echo server 10.53.0.2 "$PORT" 3449echo update delete cds-update.secure CDS 3450echo send 3451dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure | 3452grep "DNSKEY.257" | 3453$DSFROMKEY -12 -C -f - -T 1 cds-update.secure | 3454sed "s/^/update add /" 3455dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure | 3456grep "DNSKEY.257" | sed 's/DNSKEY.257/DNSKEY 258/' | 3457$DSFROMKEY -12 -C -A -f - -T 1 cds-update.secure | 3458sed "s/^/update add /" 3459echo send 3460) | $NSUPDATE 3461dig_with_opts +noall +answer @10.53.0.2 cds cds-update.secure > dig.out.test$n 3462lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3463test "$lines" -eq 2 || ret=1 3464lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l) 3465test "$lines" -eq 4 || ret=1 3466n=$((n+1)) 3467test "$ret" -eq 0 || echo_i "failed" 3468status=$((status+ret)) 3469 3470echo_i "checking that negative unknown NSEC3 hash algorithm does not validate ($n)" 3471ret=0 3472dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 nsec3-unknown.example A > dig.out.ns3.test$n 3473dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 nsec3-unknown.example A > dig.out.ns4.test$n 3474grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3475grep "status: SERVFAIL," dig.out.ns4.test$n > /dev/null || ret=1 3476n=$((n+1)) 3477test "$ret" -eq 0 || echo_i "failed" 3478status=$((status+ret)) 3479 3480echo_i "check that CDNSKEY records are signed using KSK by dnssec-signzone ($n)" 3481ret=0 3482dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey.secure > dig.out.test$n 3483lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3484test "$lines" -eq 2 || ret=1 3485n=$((n+1)) 3486test "$ret" -eq 0 || echo_i "failed" 3487status=$((status+ret)) 3488 3489echo_i "check that CDNSKEY records are not signed using ZSK by dnssec-signzone -x ($n)" 3490ret=0 3491dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-x.secure > dig.out.test$n 3492lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3493test "$lines" -eq 2 || ret=1 3494n=$((n+1)) 3495test "$ret" -eq 0 || echo_i "failed" 3496status=$((status+ret)) 3497 3498echo_i "checking that negative unknown NSEC3 hash algorithm with OPTOUT does not validate ($n)" 3499ret=0 3500dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 optout-unknown.example A > dig.out.ns3.test$n 3501dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 optout-unknown.example A > dig.out.ns4.test$n 3502grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3503grep "status: SERVFAIL," dig.out.ns4.test$n > /dev/null || ret=1 3504n=$((n+1)) 3505test "$ret" -eq 0 || echo_i "failed" 3506status=$((status+ret)) 3507 3508echo_i "check that CDNSKEY records are signed using KSK by with dnssec-auto ($n)" 3509ret=0 3510dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-auto.secure > dig.out.test$n 3511lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3512test "$lines" -eq 2 || ret=1 3513n=$((n+1)) 3514test "$ret" -eq 0 || echo_i "failed" 3515status=$((status+ret)) 3516 3517echo_i "checking that unknown DNSKEY algorithm validates as insecure ($n)" 3518ret=0 3519dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 dnskey-unknown.example A > dig.out.ns3.test$n 3520dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 dnskey-unknown.example A > dig.out.ns4.test$n 3521grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3522grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1 3523grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 3524n=$((n+1)) 3525test "$ret" -eq 0 || echo_i "failed" 3526status=$((status+ret)) 3527 3528echo_i "checking that unsupported DNSKEY algorithm validates as insecure ($n)" 3529ret=0 3530dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 dnskey-unsupported.example A > dig.out.ns3.test$n 3531dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 dnskey-unsupported.example A > dig.out.ns4.test$n 3532grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3533grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1 3534grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 3535n=$((n+1)) 3536test "$ret" -eq 0 || echo_i "failed" 3537status=$((status+ret)) 3538 3539echo_i "checking that unsupported DNSKEY algorithm is in DNSKEY RRset ($n)" 3540ret=0 3541dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 dnskey-unsupported-2.example DNSKEY > dig.out.test$n 3542grep "status: NOERROR," dig.out.test$n > /dev/null || ret=1 3543grep "dnskey-unsupported-2\.example\..*IN.*DNSKEY.*257 3 255" dig.out.test$n > /dev/null || ret=1 3544n=$((n+1)) 3545test "$ret" -eq 0 || echo_i "failed" 3546status=$((status+ret)) 3547 3548# TODO: test case for GL #1689. 3549# If we allow the dnssec tools to use deprecated algorithms (such as RSAMD5) 3550# we could write a test that signs a zone with supported and unsupported 3551# algorithm, apply a fixed rrset order such that the unsupported algorithm 3552# precedes the supported one in the DNSKEY RRset, and verify the result still 3553# validates succesfully. 3554 3555echo_i "check that a lone non matching CDNSKEY record is rejected ($n)" 3556ret=0 3557( 3558echo zone cdnskey-update.secure 3559echo server 10.53.0.2 "$PORT" 3560echo update delete cdnskey-update.secure CDNSKEY 3561echo send 3562dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-update.secure | 3563sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 258/p' 3564echo send 3565) | $NSUPDATE > nsupdate.out.test$n 2>&1 || true 3566grep "update failed: REFUSED" nsupdate.out.test$n > /dev/null || ret=1 3567dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-update.secure > dig.out.test$n 3568lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3569test "${lines:-10}" -eq 0 || ret=1 3570n=$((n+1)) 3571test "$ret" -eq 0 || echo_i "failed" 3572status=$((status+ret)) 3573 3574echo_i "check that a CDNSKEY deletion record is accepted ($n)" 3575ret=0 3576( 3577echo zone cdnskey-update.secure 3578echo server 10.53.0.2 "$PORT" 3579echo update delete cdnskey-update.secure CDNSKEY 3580echo update add cdnskey-update.secure 0 CDNSKEY 0 3 0 AA== 3581echo send 3582) | $NSUPDATE > nsupdate.out.test$n 2>&1 3583dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-update.secure > dig.out.test$n 3584lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3585test "${lines:-10}" -eq 1 || ret=1 3586lines=$(tr -d '\r' < dig.out.test$n | awk '$4 == "CDNSKEY" && $5 == "0" && $6 == "3" && $7 == "0" && $8 == "AA==" {print}' | wc -l) 3587test "${lines:-10}" -eq 1 || ret=1 3588n=$((n+1)) 3589test "$ret" -eq 0 || echo_i "failed" 3590status=$((status+ret)) 3591 3592echo_i "checking that unknown DNSKEY algorithm + unknown NSEC3 has algorithm validates as insecure ($n)" 3593ret=0 3594dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 dnskey-nsec3-unknown.example A > dig.out.ns3.test$n 3595dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 dnskey-nsec3-unknown.example A > dig.out.ns4.test$n 3596grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3597grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1 3598grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 3599n=$((n+1)) 3600test "$ret" -eq 0 || echo_i "failed" 3601status=$((status+ret)) 3602 3603echo_i "check that CDNSKEY records are signed using KSK when added by nsupdate ($n)" 3604ret=0 3605( 3606echo zone cdnskey-update.secure 3607echo server 10.53.0.2 "$PORT" 3608echo update delete cdnskey-update.secure CDNSKEY 3609dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-update.secure | 3610sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 257/p' 3611echo send 3612) | $NSUPDATE 3613dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-update.secure > dig.out.test$n 3614lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3615test "$lines" -eq 2 || ret=1 3616lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3617test "$lines" -eq 1 || ret=1 3618n=$((n+1)) 3619test "$ret" -eq 0 || echo_i "failed" 3620status=$((status+ret)) 3621 3622echo_i "check that CDNSKEY records are signed only using KSK when added by" 3623echo_ic "nsupdate when dnssec-dnskey-kskonly is yes ($n)" 3624ret=0 3625keyid=$(cat ns2/cdnskey-kskonly.secure.id) 3626( 3627echo zone cdnskey-kskonly.secure 3628echo server 10.53.0.2 "$PORT" 3629echo update delete cdnskey-kskonly.secure CDNSKEY 3630dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-kskonly.secure | 3631sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 257/p' 3632echo send 3633) | $NSUPDATE 3634dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-kskonly.secure > dig.out.test$n 3635lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3636test "$lines" -eq 1 || ret=1 3637lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDNSKEY" && $11 == id {print}' dig.out.test$n | wc -l) 3638test "$lines" -eq 1 || ret=1 3639lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3640test "$lines" -eq 1 || ret=1 3641n=$((n+1)) 3642test "$ret" -eq 0 || echo_i "failed" 3643status=$((status+ret)) 3644 3645echo_i "check that CDNSKEY deletion records are signed only using KSK when added by" 3646echo_ic "nsupdate when dnssec-dnskey-kskonly is yes ($n)" 3647ret=0 3648keyid=$(cat ns2/cdnskey-kskonly.secure.id) 3649( 3650echo zone cdnskey-kskonly.secure 3651echo server 10.53.0.2 "$PORT" 3652echo update delete cdnskey-kskonly.secure CDNSKEY 3653echo update add cdnskey-kskonly.secure 0 CDNSKEY 0 3 0 AA== 3654echo send 3655) | $NSUPDATE 3656dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-kskonly.secure > dig.out.test$n 3657lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3658test "$lines" -eq 1 || ret=1 3659lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDNSKEY" && $11 == id {print}' dig.out.test$n | wc -l) 3660test "$lines" -eq 1 || ret=1 3661lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3662test "$lines" -eq 1 || ret=1 3663lines=$(tr -d '\r' < dig.out.test$n | awk '$4 == "CDNSKEY" && $5 == "0" && $6 == "3" && $7 == "0" && $8 == "AA==" {print}' | wc -l) 3664test "${lines:-10}" -eq 1 || ret=1 3665n=$((n+1)) 3666test "$ret" -eq 0 || echo_i "failed" 3667status=$((status+ret)) 3668 3669echo_i "checking initialization with a revoked managed key ($n)" 3670ret=0 3671copy_setports ns5/named2.conf.in ns5/named.conf 3672rndccmd 10.53.0.5 reconfig 2>&1 | sed 's/^/ns5 /' | cat_i 3673sleep 3 3674dig_with_opts +dnssec @10.53.0.5 SOA . > dig.out.ns5.test$n 3675grep "status: SERVFAIL" dig.out.ns5.test$n > /dev/null || ret=1 3676n=$((n+1)) 3677test "$ret" -eq 0 || echo_i "failed" 3678status=$((status+ret)) 3679 3680echo_i "check that a non matching CDNSKEY record is accepted with a matching CDNSKEY record ($n)" 3681ret=0 3682( 3683echo zone cdnskey-update.secure 3684echo server 10.53.0.2 "$PORT" 3685echo update delete cdnskey-update.secure CDNSKEY 3686dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-update.secure | 3687sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 257/p' 3688dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-update.secure | 3689sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 258/p' 3690echo send 3691) | $NSUPDATE 3692dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-update.secure > dig.out.test$n 3693lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3694test "$lines" -eq 2 || ret=1 3695lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3696test "$lines" -eq 2 || ret=1 3697n=$((n+1)) 3698test "$ret" -eq 0 || echo_i "failed" 3699status=$((status+ret)) 3700 3701echo_i "check that RRSIGs are correctly removed from apex when RRset is removed NSEC ($n)" 3702ret=0 3703# generate signed zone with MX and AAAA records at apex. 3704( 3705cd signer || exit 1 3706$KEYGEN -q -a RSASHA1 -3 -fK remove > /dev/null 3707$KEYGEN -q -a RSASHA1 -33 remove > /dev/null 3708echo > remove.db.signed 3709$SIGNER -S -o remove -D -f remove.db.signed remove.db.in > signer.out.1.$n 3710) 3711grep "RRSIG MX" signer/remove.db.signed > /dev/null || { 3712 ret=1 ; cp signer/remove.db.signed signer/remove.db.signed.pre$n; 3713} 3714# re-generate signed zone without MX and AAAA records at apex. 3715( 3716cd signer || exit 1 3717$SIGNER -S -o remove -D -f remove.db.signed remove2.db.in > signer.out.2.$n 3718) 3719grep "RRSIG MX" signer/remove.db.signed > /dev/null && { 3720 ret=1 ; cp signer/remove.db.signed signer/remove.db.signed.post$n; 3721} 3722n=$((n+1)) 3723test "$ret" -eq 0 || echo_i "failed" 3724status=$((status+ret)) 3725 3726echo_i "check that RRSIGs are correctly removed from apex when RRset is removed NSEC3 ($n)" 3727ret=0 3728# generate signed zone with MX and AAAA records at apex. 3729( 3730cd signer || exit 1 3731echo > remove.db.signed 3732$SIGNER -3 - -S -o remove -D -f remove.db.signed remove.db.in > signer.out.1.$n 3733) 3734grep "RRSIG MX" signer/remove.db.signed > /dev/null || { 3735 ret=1 ; cp signer/remove.db.signed signer/remove.db.signed.pre$n; 3736} 3737# re-generate signed zone without MX and AAAA records at apex. 3738( 3739cd signer || exit 1 3740$SIGNER -3 - -S -o remove -D -f remove.db.signed remove2.db.in > signer.out.2.$n 3741) 3742grep "RRSIG MX" signer/remove.db.signed > /dev/null && { 3743 ret=1 ; cp signer/remove.db.signed signer/remove.db.signed.post$n; 3744} 3745n=$((n+1)) 3746test "$ret" -eq 0 || echo_i "failed" 3747status=$((status+ret)) 3748 3749echo_i "check that a named managed zone that was signed 'in-the-future' is re-signed when loaded ($n)" 3750ret=0 3751dig_with_opts managed-future.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 3752grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3753grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 3754n=$((n+1)) 3755test "$ret" -eq 0 || echo_i "failed" 3756status=$((status+ret)) 3757 3758echo_i "check that trust-anchor-telemetry queries are logged ($n)" 3759ret=0 3760grep "sending trust-anchor-telemetry query '_ta-[0-9a-f]*/NULL" ns6/named.run > /dev/null || ret=1 3761n=$((n+1)) 3762test "$ret" -eq 0 || echo_i "failed" 3763status=$((status+ret)) 3764 3765echo_i "check that _ta-XXXX trust-anchor-telemetry queries are logged ($n)" 3766ret=0 3767grep "trust-anchor-telemetry '_ta-[0-9a-f]*/IN' from" ns1/named.run > /dev/null || ret=1 3768n=$((n+1)) 3769test "$ret" -eq 0 || echo_i "failed" 3770status=$((status+ret)) 3771 3772echo_i "check that _ta-AAAA trust-anchor-telemetry are not sent when disabled ($n)" 3773ret=0 3774grep "sending trust-anchor-telemetry query '_ta-[0-9a-f]*/IN" ns1/named.run > /dev/null && ret=1 3775n=$((n+1)) 3776test "$ret" -eq 0 || echo_i "failed" 3777status=$((status+ret)) 3778 3779echo_i "check that KEY-TAG trust-anchor-telemetry queries are logged ($n)" 3780ret=0 3781dig_with_opts . dnskey +ednsopt=KEY-TAG:ffff @10.53.0.1 > dig.out.ns1.test$n || ret=1 3782grep "trust-anchor-telemetry './IN' from .* 65535" ns1/named.run > /dev/null || ret=1 3783n=$((n+1)) 3784test "$ret" -eq 0 || echo_i "failed" 3785status=$((status+ret)) 3786 3787echo_i "check that multiple KEY-TAG trust-anchor-telemetry options don't leak memory ($n)" 3788ret=0 3789dig_with_opts . dnskey +ednsopt=KEY-TAG:fffe +ednsopt=KEY-TAG:fffd @10.53.0.1 > dig.out.ns1.test$n || ret=1 3790grep "trust-anchor-telemetry './IN' from .* 65534" ns1/named.run > /dev/null || ret=1 3791grep "trust-anchor-telemetry './IN' from .* 65533" ns1/named.run > /dev/null && ret=1 3792$PERL $SYSTEMTESTTOP/stop.pl dnssec ns1 || ret=1 3793nextpart ns1/named.run > /dev/null 3794$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} dnssec ns1 || ret=1 3795n=$(($n+1)) 3796test "$ret" -eq 0 || echo_i "failed" 3797status=$((status+ret)) 3798 3799echo_i "waiting for root server to finish reloading ($n)" 3800ret=0 3801wait_for_log 20 "all zones loaded" ns1/named.run || ret=1 3802n=$(($n+1)) 3803test "$ret" -eq 0 || echo_i "failed" 3804status=$((status+ret)) 3805 3806echo_i "check that the view is logged in messages from the validator when using views ($n)" 3807ret=0 3808grep "view rec: *validat" ns4/named.run > /dev/null || ret=1 3809n=$((n+1)) 3810test "$ret" -eq 0 || echo_i "failed" 3811status=$((status+ret)) 3812 3813echo_i "check that DNAME at apex with NSEC3 is correctly signed (dnssec-signzone) ($n)" 3814ret=0 3815dig_with_opts txt dname-at-apex-nsec3.example @10.53.0.3 > dig.out.ns3.test$n || ret=1 3816grep "RRSIG.NSEC3 ${DEFAULT_ALGORITHM_NUMBER} 3 3600" dig.out.ns3.test$n > /dev/null || ret=1 3817n=$((n+1)) 3818test "$ret" -eq 0 || echo_i "failed" 3819status=$((status+ret)) 3820 3821echo_i "check that DNSKEY and other occluded data are excluded from the delegating bitmap ($n)" 3822ret=0 3823dig_with_opts axfr occluded.example @10.53.0.3 > dig.out.ns3.test$n || ret=1 3824grep "^delegation.occluded.example..*NSEC.*NS KEY DS RRSIG NSEC$" dig.out.ns3.test$n > /dev/null || ret=1 3825grep "^delegation.occluded.example..*DNSKEY.*" dig.out.ns3.test$n > /dev/null || ret=1 3826grep "^delegation.occluded.example..*AAAA.*" dig.out.ns3.test$n > /dev/null || ret=1 3827n=$((n+1)) 3828test "$ret" -eq 0 || echo_i "failed" 3829status=$((status+ret)) 3830 3831echo_i "checking DNSSEC records are occluded from ANY in an insecure zone ($n)" 3832ret=0 3833dig_with_opts any x.insecure.example. @10.53.0.3 > dig.out.ns3.1.test$n || ret=1 3834grep "status: NOERROR" dig.out.ns3.1.test$n > /dev/null || ret=1 3835grep "ANSWER: 0," dig.out.ns3.1.test$n > /dev/null || ret=1 3836dig_with_opts any zz.secure.example. @10.53.0.3 > dig.out.ns3.2.test$n || ret=1 3837grep "status: NOERROR" dig.out.ns3.2.test$n > /dev/null || ret=1 3838# DNSKEY+RRSIG, NSEC+RRSIG 3839grep "ANSWER: 4," dig.out.ns3.2.test$n > /dev/null || ret=1 3840n=$((n+1)) 3841test "$ret" -eq 0 || echo_i "failed" 3842status=$((status+ret)) 3843 3844# 3845# DNSSEC tests related to unsupported, disabled and revoked trust anchors. 3846# 3847 3848# This nameserver (ns8) is loaded with a bunch of trust anchors. Some of 3849# them are good (enabled.managed, enabled.trusted, secure.managed, 3850# secure.trusted), and some of them are bad (disabled.managed, 3851# revoked.managed, unsupported.managed, disabled.trusted, revoked.trusted, 3852# unsupported.trusted). Make sure that the bad trust anchors are ignored. 3853# This is tested by looking for the corresponding lines in the logfile. 3854echo_i "checking that keys with unsupported algorithms and disabled algorithms are ignored ($n)" 3855ret=0 3856grep -q "ignoring static-key for 'disabled\.trusted\.': algorithm is disabled" ns8/named.run || ret=1 3857grep -q "ignoring static-key for 'unsupported\.trusted\.': algorithm is unsupported" ns8/named.run || ret=1 3858grep -q "ignoring static-key for 'revoked\.trusted\.': bad key type" ns8/named.run || ret=1 3859grep -q "ignoring initial-key for 'disabled\.managed\.': algorithm is disabled" ns8/named.run || ret=1 3860grep -q "ignoring initial-key for 'unsupported\.managed\.': algorithm is unsupported" ns8/named.run || ret=1 3861grep -q "ignoring initial-key for 'revoked\.managed\.': bad key type" ns8/named.run || ret=1 3862n=$((n+1)) 3863test "$ret" -eq 0 || echo_i "failed" 3864status=$((status+ret)) 3865 3866# The next two tests are fairly normal DNSSEC queries to signed zones with a 3867# default algorithm. First, a query is made against the server that is 3868# authoritative for the given zone (ns3). Second, a query is made against a 3869# resolver with trust anchors for the given zone (ns8). Both are expected to 3870# return an authentic data positive response. 3871echo_i "checking that a trusted key using a supported algorithm validates as secure ($n)" 3872ret=0 3873dig_with_opts @10.53.0.3 a.secure.trusted A > dig.out.ns3.test$n 3874dig_with_opts @10.53.0.8 a.secure.trusted A > dig.out.ns8.test$n 3875grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3876grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3877grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 3878n=$((n+1)) 3879test "$ret" -eq 0 || echo_i "failed" 3880status=$((status+ret)) 3881 3882echo_i "checking that a managed key using a supported algorithm validates as secure ($n)" 3883ret=0 3884dig_with_opts @10.53.0.3 a.secure.managed A > dig.out.ns3.test$n 3885dig_with_opts @10.53.0.8 a.secure.managed A > dig.out.ns8.test$n 3886grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3887grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3888grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 3889n=$((n+1)) 3890test "$ret" -eq 0 || echo_i "failed" 3891status=$((status+ret)) 3892 3893# The next two queries ensure that a zone signed with a DNSKEY with an unsupported 3894# algorithm will yield insecure positive responses. These trust anchors in ns8 are 3895# ignored and so this domain is treated as insecure. The AD bit should not be set 3896# in the response. 3897echo_i "checking that a trusted key using an unsupported algorithm validates as insecure ($n)" 3898ret=0 3899dig_with_opts @10.53.0.3 a.unsupported.trusted A > dig.out.ns3.test$n 3900dig_with_opts @10.53.0.8 a.unsupported.trusted A > dig.out.ns8.test$n 3901grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3902grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3903grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 3904n=$((n+1)) 3905test "$ret" -eq 0 || echo_i "failed" 3906status=$((status+ret)) 3907 3908echo_i "checking that a managed key using an unsupported algorithm validates as insecure ($n)" 3909ret=0 3910dig_with_opts @10.53.0.3 a.unsupported.managed A > dig.out.ns3.test$n 3911dig_with_opts @10.53.0.8 a.unsupported.managed A > dig.out.ns8.test$n 3912grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3913grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3914grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 3915n=$((n+1)) 3916test "$ret" -eq 0 || echo_i "failed" 3917status=$((status+ret)) 3918 3919# The next two queries ensure that a zone signed with a DNSKEY that the nameserver 3920# has a disabled algorithm match for will yield insecure positive responses. 3921# These trust anchors in ns8 are ignored and so this domain is treated as insecure. 3922# The AD bit should not be set in the response. 3923echo_i "checking that a trusted key using a disabled algorithm validates as insecure ($n)" 3924ret=0 3925dig_with_opts @10.53.0.3 a.disabled.trusted A > dig.out.ns3.test$n 3926dig_with_opts @10.53.0.8 a.disabled.trusted A > dig.out.ns8.test$n 3927grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3928grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3929grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 3930n=$((n+1)) 3931test "$ret" -eq 0 || echo_i "failed" 3932status=$((status+ret)) 3933 3934echo_i "checking that a managed key using a disabled algorithm validates as insecure ($n)" 3935ret=0 3936dig_with_opts @10.53.0.3 a.disabled.managed A > dig.out.ns3.test$n 3937dig_with_opts @10.53.0.8 a.disabled.managed A > dig.out.ns8.test$n 3938grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3939grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3940grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 3941n=$((n+1)) 3942test "$ret" -eq 0 || echo_i "failed" 3943status=$((status+ret)) 3944 3945# The next two queries ensure that a zone signed with a DNSKEY that the 3946# nameserver has a disabled algorithm for, but for a different domain, will 3947# yield secure positive responses. Since "enabled.trusted." and 3948# "enabled.managed." do not match the "disable-algorithms" option, no 3949# special rules apply and these zones should validate as secure, with the AD 3950# bit set. 3951echo_i "checking that a trusted key using an algorithm disabled for another domain validates as secure ($n)" 3952ret=0 3953dig_with_opts @10.53.0.3 a.enabled.trusted A > dig.out.ns3.test$n 3954dig_with_opts @10.53.0.8 a.enabled.trusted A > dig.out.ns8.test$n 3955grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3956grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3957grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 3958n=$((n+1)) 3959test "$ret" -eq 0 || echo_i "failed" 3960status=$((status+ret)) 3961 3962echo_i "checking that a managed key using an algorithm disabled for another domain validates as secure ($n)" 3963ret=0 3964dig_with_opts @10.53.0.3 a.enabled.managed A > dig.out.ns3.test$n 3965dig_with_opts @10.53.0.8 a.enabled.managed A > dig.out.ns8.test$n 3966grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3967grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3968grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 3969n=$((n+1)) 3970test "$ret" -eq 0 || echo_i "failed" 3971status=$((status+ret)) 3972 3973# A configured revoked trust anchor is ignored and thus the two queries below 3974# should result in insecure responses, since no trust points for the 3975# "revoked.trusted." and "revoked.managed." zones are created. 3976echo_i "checking that a trusted key that is revoked validates as insecure ($n)" 3977ret=0 3978dig_with_opts @10.53.0.3 a.revoked.trusted A > dig.out.ns3.test$n 3979dig_with_opts @10.53.0.8 a.revoked.trusted A > dig.out.ns8.test$n 3980grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3981grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3982grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 3983n=$((n+1)) 3984test "$ret" -eq 0 || echo_i "failed" 3985status=$((status+ret)) 3986 3987echo_i "checking that a managed key that is revoked validates as insecure ($n)" 3988ret=0 3989dig_with_opts @10.53.0.3 a.revoked.managed A > dig.out.ns3.test$n 3990dig_with_opts @10.53.0.8 a.revoked.managed A > dig.out.ns8.test$n 3991grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3992grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3993grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 3994n=$((n+1)) 3995test "$ret" -eq 0 || echo_i "failed" 3996status=$((status+ret)) 3997 3998### 3999### Additional checks for when the KSK is offline. 4000### 4001 4002# Save some useful information 4003zone="updatecheck-kskonly.secure" 4004KSK=`cat ns2/${zone}.ksk.key` 4005ZSK=`cat ns2/${zone}.zsk.key` 4006KSK_ID=`cat ns2/${zone}.ksk.id` 4007ZSK_ID=`cat ns2/${zone}.zsk.id` 4008SECTIONS="+answer +noauthority +noadditional" 4009echo_i "testing zone $zone KSK=$KSK_ID ZSK=$ZSK_ID" 4010 4011# Print IDs of keys used for generating RRSIG records for RRsets of type $1 4012# found in dig output file $2. 4013get_keys_which_signed() { 4014 qtype=$1 4015 output=$2 4016 # The key ID is the 11th column of the RRSIG record line. 4017 awk -v qt="$qtype" '$4 == "RRSIG" && $5 == qt {print $11}' < "$output" 4018} 4019 4020# Basic checks to make sure everything is fine before the KSK is made offline. 4021for qtype in "DNSKEY" "CDNSKEY" "CDS" 4022do 4023 echo_i "checking $qtype RRset is signed with KSK only (update-check-ksk, dnssec-ksk-only) ($n)" 4024 ret=0 4025 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4026 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4027 test "$lines" -eq 1 || ret=1 4028 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null || ret=1 4029 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4030 n=$((n+1)) 4031 test "$ret" -eq 0 || echo_i "failed" 4032 status=$((status+ret)) 4033done 4034 4035echo_i "checking SOA RRset is signed with ZSK only (update-check-ksk and dnssec-ksk-only) ($n)" 4036ret=0 4037dig_with_opts $SECTIONS @10.53.0.2 soa $zone > dig.out.test$n 4038lines=$(get_keys_which_signed "SOA" dig.out.test$n | wc -l) 4039test "$lines" -eq 1 || ret=1 4040get_keys_which_signed "SOA" dig.out.test$n | grep "^$KSK_ID$" > /dev/null && ret=1 4041get_keys_which_signed "SOA" dig.out.test$n | grep "^$ZSK_ID$" > /dev/null || ret=1 4042n=$((n+1)) 4043test "$ret" -eq 0 || echo_i "failed" 4044status=$((status+ret)) 4045 4046# Roll the ZSK. 4047zsk2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -K ns2 -n zone "$zone") 4048keyfile_to_key_id "$zsk2" > ns2/$zone.zsk.id2 4049ZSK_ID2=`cat ns2/$zone.zsk.id2` 4050 4051echo_i "load new ZSK $ZSK_ID2 for $zone ($n)" 4052ret=0 4053dnssec_loadkeys_on 2 $zone || ret=1 4054n=$((n+1)) 4055test "$ret" -eq 0 || echo_i "failed" 4056status=$((status+ret)) 4057 4058# Make new ZSK active. 4059echo_i "make ZSK $ZSK_ID inactive and make new ZSK $ZSK_ID2 active for zone $zone ($n)" 4060ret=0 4061$SETTIME -I now -K ns2 $ZSK > /dev/null 4062$SETTIME -A now -K ns2 $zsk2 > /dev/null 4063dnssec_loadkeys_on 2 $zone || ret=1 4064n=$((n+1)) 4065test "$ret" -eq 0 || echo_i "failed" 4066status=$((status+ret)) 4067 4068# Remove the KSK from disk. 4069echo_i "remove the KSK $KSK_ID for zone $zone from disk" 4070mv ns2/$KSK.key ns2/$KSK.key.bak 4071mv ns2/$KSK.private ns2/$KSK.private.bak 4072 4073# Update the zone that requires a resign of the SOA RRset. 4074echo_i "update the zone with $zone IN TXT nsupdate added me" 4075( 4076echo zone $zone 4077echo server 10.53.0.2 "$PORT" 4078echo update add $zone. 300 in txt "nsupdate added me" 4079echo send 4080) | $NSUPDATE 4081 4082# Redo the tests now that the zone is updated and the KSK is offline. 4083for qtype in "DNSKEY" "CDNSKEY" "CDS" 4084do 4085 echo_i "checking $qtype RRset is signed with KSK only, KSK offline (update-check-ksk, dnssec-ksk-only) ($n)" 4086 ret=0 4087 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4088 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4089 test "$lines" -eq 1 || ret=1 4090 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null || ret=1 4091 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4092 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null && ret=1 4093 n=$((n+1)) 4094 test "$ret" -eq 0 || echo_i "failed" 4095 status=$((status+ret)) 4096done 4097 4098for qtype in "SOA" "TXT" 4099do 4100 echo_i "checking $qtype RRset is signed with ZSK only, KSK offline (update-check-ksk and dnssec-ksk-only) ($n)" 4101 ret=0 4102 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4103 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4104 test "$lines" -eq 1 || ret=1 4105 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null && ret=1 4106 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4107 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null || ret=1 4108 n=$((n+1)) 4109 test "$ret" -eq 0 || echo_i "failed" 4110 status=$((status+ret)) 4111done 4112 4113# Put back the KSK. 4114echo_i "put back the KSK $KSK_ID for zone $zone from disk" 4115mv ns2/$KSK.key.bak ns2/$KSK.key 4116mv ns2/$KSK.private.bak ns2/$KSK.private 4117 4118# Roll the ZSK again. 4119zsk3=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -K ns2 -n zone "$zone") 4120keyfile_to_key_id "$zsk3" > ns2/$zone.zsk.id3 4121ZSK_ID3=`cat ns2/$zone.zsk.id3` 4122 4123# Schedule the new ZSK (ZSK3) to become active. 4124echo_i "delete old ZSK $ZSK_ID schedule ZSK $ZSK_ID2 inactive and new ZSK $ZSK_ID3 active for zone $zone ($n)" 4125$SETTIME -D now -K ns2 $ZSK > /dev/null 4126$SETTIME -I +3600 -K ns2 $zsk2 > /dev/null 4127$SETTIME -A +3600 -K ns2 $zsk3 > /dev/null 4128dnssec_loadkeys_on 2 $zone || ret=1 4129n=$((n+1)) 4130test "$ret" -eq 0 || echo_i "failed" 4131status=$((status+ret)) 4132 4133# Remove the KSK from disk. 4134echo_i "remove the KSK $KSK_ID for zone $zone from disk" 4135mv ns2/$KSK.key ns2/$KSK.key.bak 4136mv ns2/$KSK.private ns2/$KSK.private.bak 4137 4138# Update the zone that requires a resign of the SOA RRset. 4139echo_i "update the zone with $zone IN TXT nsupdate added me again" 4140( 4141echo zone $zone 4142echo server 10.53.0.2 "$PORT" 4143echo update add $zone. 300 in txt "nsupdate added me again" 4144echo send 4145) | $NSUPDATE 4146 4147# Redo the tests now that the ZSK roll has deleted the old key. 4148for qtype in "DNSKEY" "CDNSKEY" "CDS" 4149do 4150 echo_i "checking $qtype RRset is signed with KSK only, old ZSK deleted (update-check-ksk, dnssec-ksk-only) ($n)" 4151 ret=0 4152 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4153 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4154 test "$lines" -eq 1 || ret=1 4155 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null || ret=1 4156 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4157 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null && ret=1 4158 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID3$" > /dev/null && ret=1 4159 n=$((n+1)) 4160 test "$ret" -eq 0 || echo_i "failed" 4161 status=$((status+ret)) 4162done 4163 4164for qtype in "SOA" "TXT" 4165do 4166 echo_i "checking $qtype RRset is signed with ZSK only, old ZSK deleted (update-check-ksk and dnssec-ksk-only) ($n)" 4167 ret=0 4168 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4169 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4170 test "$lines" -eq 1 || ret=1 4171 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null && ret=1 4172 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4173 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null || ret=1 4174 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID3$" > /dev/null && ret=1 4175 n=$((n+1)) 4176 test "$ret" -eq 0 || echo_i "failed" 4177 status=$((status+ret)) 4178done 4179 4180# Make the new ZSK (ZSK3) active. 4181echo_i "make new ZSK $ZSK_ID3 active for zone $zone ($n)" 4182$SETTIME -I +1 -K ns2 $zsk2 > /dev/null 4183$SETTIME -A +1 -K ns2 $zsk3 > /dev/null 4184dnssec_loadkeys_on 2 $zone || ret=1 4185n=$((n+1)) 4186test "$ret" -eq 0 || echo_i "failed" 4187status=$((status+ret)) 4188 4189# Wait for newest ZSK to become active. 4190echo_i "wait until new ZSK $ZSK_ID3 active and ZSK $ZSK_ID2 inactive" 4191for i in 1 2 3 4 5 6 7 8 9 10; do 4192 ret=0 4193 grep "DNSKEY $zone/$DEFAULT_ALGORITHM/$ZSK_ID3 (ZSK) is now active" ns2/named.run > /dev/null || ret=1 4194 grep "DNSKEY $zone/$DEFAULT_ALGORITHM/$ZSK_ID2 (ZSK) is now inactive" ns2/named.run > /dev/null || ret=1 4195 [ "$ret" -eq 0 ] && break 4196 sleep 1 4197done 4198n=$((n+1)) 4199test "$ret" -eq 0 || echo_i "failed" 4200status=$((status+ret)) 4201 4202# Update the zone that requires a resign of the SOA RRset. 4203echo_i "update the zone with $zone IN TXT nsupdate added me one more time" 4204( 4205echo zone $zone 4206echo server 10.53.0.2 "$PORT" 4207echo update add $zone. 300 in txt "nsupdate added me one more time" 4208echo send 4209) | $NSUPDATE 4210n=$((n+1)) 4211test "$ret" -eq 0 || echo_i "failed" 4212status=$((status+ret)) 4213 4214# Redo the tests one more time. 4215for qtype in "DNSKEY" "CDNSKEY" "CDS" 4216do 4217 echo_i "checking $qtype RRset is signed with KSK only, new ZSK active (update-check-ksk, dnssec-ksk-only) ($n)" 4218 ret=0 4219 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4220 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4221 test "$lines" -eq 1 || ret=1 4222 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null || ret=1 4223 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4224 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null && ret=1 4225 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID3$" > /dev/null && ret=1 4226 n=$((n+1)) 4227 test "$ret" -eq 0 || echo_i "failed" 4228 status=$((status+ret)) 4229done 4230 4231for qtype in "SOA" "TXT" 4232do 4233 echo_i "checking $qtype RRset is signed with ZSK only, new ZSK active (update-check-ksk and dnssec-ksk-only) ($n)" 4234 ret=0 4235 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4236 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4237 test "$lines" -eq 1 || ret=1 4238 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null && ret=1 4239 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4240 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null && ret=1 4241 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID3$" > /dev/null || ret=1 4242 n=$((n+1)) 4243 test "$ret" -eq 0 || echo_i "failed" 4244 status=$((status+ret)) 4245done 4246 4247echo_i "checking secroots output with multiple views ($n)" 4248ret=0 4249rndccmd 10.53.0.4 secroots 2>&1 | sed 's/^/ns4 /' | cat_i 4250cp ns4/named.secroots named.secroots.test$n 4251check_secroots_layout named.secroots.test$n || ret=1 4252n=$((n+1)) 4253test "$ret" -eq 0 || echo_i "failed" 4254status=$((status+ret)) 4255 4256echo_i "checking sig-validity-interval second field hours vs days ($n)" 4257ret=0 4258# zone configured with 'sig-validity-interval 500 499;' 4259# 499 days in the future w/ a 20 minute runtime to now allowance 4260min=$(TZ=UTC $PERL -e '@lt=localtime(time() + 499*3600*24 - 20*60); printf "%.4d%0.2d%0.2d%0.2d%0.2d%0.2d\n",$lt[5]+1900,$lt[4]+1,$lt[3],$lt[2],$lt[1],$lt[0];') 4261dig_with_opts @10.53.0.2 hours-vs-days AXFR > dig.out.ns2.test$n 4262awk -v min=$min '$4 == "RRSIG" { if ($9 < min) { exit(1); } }' dig.out.ns2.test$n || ret=1 4263n=$((n+1)) 4264test "$ret" -eq 0 || echo_i "failed" 4265status=$((status+ret)) 4266 4267echo_i "checking validation succeeds during transition to signed ($n)" 4268ret=0 4269dig_with_opts @10.53.0.4 inprogress A > dig.out.ns4.test$n || ret=1 4270grep "flags: qr rd ra;" dig.out.ns4.test$n >/dev/null || ret=1 4271grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 4272grep 'A.10\.53\.0\.10' dig.out.ns4.test$n >/dev/null || ret=1 4273n=$((n+1)) 4274test "$ret" -eq 0 || echo_i "failed" 4275status=$((status+ret)) 4276 4277echo_i "exit status: $status" 4278[ $status -eq 0 ] || exit 1 4279