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 0 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 0 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 0 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 0 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_ic "check that dnssec-signzone rejects excessive NSEC3 iterations ($n)" 1398ret=0 1399( 1400cd signer/general || exit 0 1401rm -f signed.zone 1402$SIGNER -f signed.zone -3 - -H 151 -o example.com. test9.zone > signer.out.$n 1403test -f signed.zone 1404) && ret=1 1405n=$((n+1)) 1406test "$ret" -eq 0 || echo_i "failed" 1407status=$((status+ret)) 1408 1409echo_ic "check that dnssec-signzone accepts maximum NSEC3 iterations ($n)" 1410ret=0 1411( 1412cd signer/general || exit 1 1413rm -f signed.zone 1414$SIGNER -f signed.zone -3 - -H 150 -o example.com. test9.zone > signer.out.$n 1415test -f signed.zone 1416) || ret=1 1417n=$((n+1)) 1418test "$ret" -eq 0 || echo_i "failed" 1419status=$((status+ret)) 1420 1421echo_i "checking that a key using an unsupported algorithm cannot be generated ($n)" 1422ret=0 1423zone=example 1424# If dnssec-keygen fails, the test script will exit immediately. Prevent that 1425# from happening, and also trigger a test failure if dnssec-keygen unexpectedly 1426# succeeds, by using "&& ret=1". 1427$KEYGEN -a 255 $zone > dnssectools.out.test$n 2>&1 && ret=1 1428grep -q "unsupported algorithm: 255" dnssectools.out.test$n || ret=1 1429n=$((n+1)) 1430test "$ret" -eq 0 || echo_i "failed" 1431status=$((status+ret)) 1432 1433echo_i "checking that a DS record cannot be generated for a key using an unsupported algorithm ($n)" 1434ret=0 1435zone=example 1436# Fake an unsupported algorithm key 1437unsupportedkey=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") 1438awk '$3 == "DNSKEY" { $6 = 255 } { print }' ${unsupportedkey}.key > ${unsupportedkey}.tmp 1439mv ${unsupportedkey}.tmp ${unsupportedkey}.key 1440# If dnssec-dsfromkey fails, the test script will exit immediately. Prevent 1441# that from happening, and also trigger a test failure if dnssec-dsfromkey 1442# unexpectedly succeeds, by using "&& ret=1". 1443$DSFROMKEY ${unsupportedkey} > dnssectools.out.test$n 2>&1 && ret=1 1444grep -q "algorithm is unsupported" dnssectools.out.test$n || ret=1 1445n=$((n+1)) 1446test "$ret" -eq 0 || echo_i "failed" 1447status=$((status+ret)) 1448 1449echo_i "checking that a zone cannot be signed with a key using an unsupported algorithm ($n)" 1450ret=0 1451ret=0 1452cat signer/example.db.in "${unsupportedkey}.key" > signer/example.db 1453# If dnssec-signzone fails, the test script will exit immediately. Prevent that 1454# from happening, and also trigger a test failure if dnssec-signzone 1455# unexpectedly succeeds, by using "&& ret=1". 1456$SIGNER -o example signer/example.db ${unsupportedkey} > dnssectools.out.test$n 2>&1 && ret=1 1457grep -q "algorithm is unsupported" dnssectools.out.test$n || ret=1 1458n=$((n+1)) 1459test "$ret" -eq 0 || echo_i "failed" 1460status=$((status+ret)) 1461 1462get_rsasha1_key_ids_from_sigs() { 1463 tr -d '\r' < signer/example.db.signed | \ 1464 awk ' 1465 NF < 8 { next } 1466 $(NF-5) != "RRSIG" { next } 1467 $(NF-3) != "5" { next } 1468 $NF != "(" { next } 1469 { 1470 getline; 1471 print $3; 1472 } 1473 ' | \ 1474 sort -u 1475} 1476 1477echo_i "checking that we can sign a zone with out-of-zone records ($n)" 1478ret=0 1479zone=example 1480key1=$($KEYGEN -K signer -q -a NSEC3RSASHA1 -b 1024 -n zone $zone) 1481key2=$($KEYGEN -K signer -q -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone) 1482( 1483cd signer || exit 1 1484cat example.db.in "$key1.key" "$key2.key" > example.db 1485$SIGNER -o example -f example.db example.db > /dev/null 1486) || ret=1 1487n=$((n+1)) 1488test "$ret" -eq 0 || echo_i "failed" 1489status=$((status+ret)) 1490 1491echo_i "checking that we can sign a zone (NSEC3) with out-of-zone records ($n)" 1492ret=0 1493zone=example 1494key1=$($KEYGEN -K signer -q -a NSEC3RSASHA1 -b 1024 -n zone $zone) 1495key2=$($KEYGEN -K signer -q -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone) 1496( 1497cd signer || exit 1 1498cat example.db.in "$key1.key" "$key2.key" > example.db 1499$SIGNER -3 - -H 10 -o example -f example.db example.db > /dev/null 1500awk '/^IQF9LQTLK/ { 1501 printf("%s", $0); 1502 while (!index($0, ")")) { 1503 if (getline <= 0) 1504 break; 1505 printf (" %s", $0); 1506 } 1507 printf("\n"); 1508 }' example.db | sed 's/[ ][ ]*/ /g' > nsec3param.out 1509 1510grep "IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG.example. 0 IN NSEC3 1 0 10 - ( IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG A NS SOA RRSIG DNSKEY NSEC3PARAM )" nsec3param.out > /dev/null 1511) || ret=1 1512n=$((n+1)) 1513test "$ret" -eq 0 || echo_i "failed" 1514status=$((status+ret)) 1515 1516echo_i "checking NSEC3 signing with empty nonterminals above a delegation ($n)" 1517ret=0 1518zone=example 1519key1=$($KEYGEN -K signer -q -a NSEC3RSASHA1 -b 1024 -n zone $zone) 1520key2=$($KEYGEN -K signer -q -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone) 1521( 1522cd signer || exit 1 1523cat example.db.in "$key1.key" "$key2.key" > example3.db 1524echo "some.empty.nonterminal.nodes.example 60 IN NS ns.example.tld" >> example3.db 1525$SIGNER -3 - -A -H 10 -o example -f example3.db example3.db > /dev/null 1526awk '/^IQF9LQTLK/ { 1527 printf("%s", $0); 1528 while (!index($0, ")")) { 1529 if (getline <= 0) 1530 break; 1531 printf (" %s", $0); 1532 } 1533 printf("\n"); 1534 }' example.db | sed 's/[ ][ ]*/ /g' > nsec3param.out 1535 1536grep "IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG.example. 0 IN NSEC3 1 0 10 - ( IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG A NS SOA RRSIG DNSKEY NSEC3PARAM )" nsec3param.out > /dev/null 1537) || ret=1 1538n=$((n+1)) 1539test "$ret" -eq 0 || echo_i "failed" 1540status=$((status+ret)) 1541 1542echo_i "checking that dnssec-signzone updates originalttl on ttl changes ($n)" 1543ret=0 1544zone=example 1545key1=$($KEYGEN -K signer -q -a RSASHA1 -b 1024 -n zone $zone) 1546key2=$($KEYGEN -K signer -q -f KSK -a RSASHA1 -b 1024 -n zone $zone) 1547( 1548cd signer || exit 1 1549cat example.db.in "$key1.key" "$key2.key" > example.db 1550$SIGNER -o example -f example.db.before example.db > /dev/null 1551sed 's/60.IN.SOA./50 IN SOA /' example.db.before > example.db.changed 1552$SIGNER -o example -f example.db.after example.db.changed > /dev/null 1553) 1554grep "SOA 5 1 50" signer/example.db.after > /dev/null || ret=1 1555n=$((n+1)) 1556test "$ret" -eq 0 || echo_i "failed" 1557status=$((status+ret)) 1558 1559echo_i "checking dnssec-signzone keeps valid signatures from removed keys ($n)" 1560ret=0 1561zone=example 1562key1=$($KEYGEN -K signer -q -f KSK -a RSASHA1 -b 1024 -n zone $zone) 1563key2=$($KEYGEN -K signer -q -a RSASHA1 -b 1024 -n zone $zone) 1564keyid2=$(keyfile_to_key_id "$key2") 1565key3=$($KEYGEN -K signer -q -a RSASHA1 -b 1024 -n zone $zone) 1566keyid3=$(keyfile_to_key_id "$key3") 1567( 1568cd signer || exit 1 1569cat example.db.in "$key1.key" "$key2.key" > example.db 1570$SIGNER -D -o example example.db > /dev/null 1571 1572# now switch out key2 for key3 and resign the zone 1573cat example.db.in "$key1.key" "$key3.key" > example.db 1574echo "\$INCLUDE \"example.db.signed\"" >> example.db 1575$SIGNER -D -o example example.db > /dev/null 1576) || ret=1 1577get_rsasha1_key_ids_from_sigs | grep "^$keyid2$" > /dev/null || ret=1 1578get_rsasha1_key_ids_from_sigs | grep "^$keyid3$" > /dev/null || ret=1 1579n=$((n+1)) 1580test "$ret" -eq 0 || echo_i "failed" 1581status=$((status+ret)) 1582 1583echo_i "checking dnssec-signzone -R purges signatures from removed keys ($n)" 1584ret=0 1585( 1586cd signer || exit 1 1587$SIGNER -RD -o example example.db > /dev/null 1588) || ret=1 1589get_rsasha1_key_ids_from_sigs | grep "^$keyid2$" > /dev/null && ret=1 1590get_rsasha1_key_ids_from_sigs | grep "^$keyid3$" > /dev/null || ret=1 1591n=$((n+1)) 1592test "$ret" -eq 0 || echo_i "failed" 1593status=$((status+ret)) 1594 1595echo_i "checking dnssec-signzone keeps valid signatures from inactive keys ($n)" 1596ret=0 1597zone=example 1598( 1599cd signer || exit 1 1600cp -f example.db.in example.db 1601$SIGNER -SD -o example example.db > /dev/null 1602echo "\$INCLUDE \"example.db.signed\"" >> example.db 1603# now retire key2 and resign the zone 1604$SETTIME -I now "$key2" > /dev/null 2>&1 1605$SIGNER -SD -o example example.db > /dev/null 1606) || ret=1 1607get_rsasha1_key_ids_from_sigs | grep "^$keyid2$" > /dev/null || ret=1 1608get_rsasha1_key_ids_from_sigs | grep "^$keyid3$" > /dev/null || ret=1 1609n=$((n+1)) 1610test "$ret" -eq 0 || echo_i "failed" 1611status=$((status+ret)) 1612 1613echo_i "checking dnssec-signzone -Q purges signatures from inactive keys ($n)" 1614ret=0 1615( 1616cd signer || exit 1 1617$SIGNER -SDQ -o example example.db > /dev/null 1618) || ret=1 1619get_rsasha1_key_ids_from_sigs | grep "^$keyid2$" > /dev/null && ret=1 1620get_rsasha1_key_ids_from_sigs | grep "^$keyid3$" > /dev/null || ret=1 1621n=$((n+1)) 1622test "$ret" -eq 0 || echo_i "failed" 1623status=$((status+ret)) 1624 1625echo_i "checking dnssec-signzone retains unexpired signatures ($n)" 1626ret=0 1627( 1628cd signer || exit 1 1629$SIGNER -Sxt -o example example.db > signer.out.1 1630$SIGNER -Sxt -o example -f example.db.signed example.db.signed > signer.out.2 1631) || ret=1 1632gen1=$(awk '/generated/ {print $3}' signer/signer.out.1) 1633retain1=$(awk '/retained/ {print $3}' signer/signer.out.1) 1634gen2=$(awk '/generated/ {print $3}' signer/signer.out.2) 1635retain2=$(awk '/retained/ {print $3}' signer/signer.out.2) 1636drop2=$(awk '/dropped/ {print $3}' signer/signer.out.2) 1637[ "$retain2" -eq $((gen1+retain1)) ] || ret=1 1638[ "$gen2" -eq 0 ] || ret=1 1639[ "$drop2" -eq 0 ] || ret=1 1640n=$((n+1)) 1641test "$ret" -eq 0 || echo_i "failed" 1642status=$((status+ret)) 1643 1644echo_i "checking dnssec-signzone purges RRSIGs from formerly-owned glue (nsec) ($n)" 1645ret=0 1646( 1647cd signer || exit 1 1648# remove NSEC-only keys 1649rm -f Kexample.+005* 1650cp -f example.db.in example2.db 1651cat << EOF >> example2.db 1652sub1.example. IN A 10.53.0.1 1653ns.sub2.example. IN A 10.53.0.2 1654EOF 1655echo "\$INCLUDE \"example2.db.signed\"" >> example2.db 1656touch example2.db.signed 1657$SIGNER -DS -O full -f example2.db.signed -o example example2.db > /dev/null 1658) || ret=1 1659grep "^sub1\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 || ret=1 1660grep "^ns\\.sub2\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 || ret=1 1661( 1662cd signer || exit 1 1663cp -f example.db.in example2.db 1664cat << EOF >> example2.db 1665sub1.example. IN NS sub1.example. 1666sub1.example. IN A 10.53.0.1 1667sub2.example. IN NS ns.sub2.example. 1668ns.sub2.example. IN A 10.53.0.2 1669EOF 1670echo "\$INCLUDE \"example2.db.signed\"" >> example2.db 1671$SIGNER -DS -O full -f example2.db.signed -o example example2.db > /dev/null 1672) || ret=1 1673grep "^sub1\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 && ret=1 1674grep "^ns\\.sub2\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 && ret=1 1675n=$((n+1)) 1676test "$ret" -eq 0 || echo_i "failed" 1677status=$((status+ret)) 1678 1679echo_i "checking dnssec-signzone purges RRSIGs from formerly-owned glue (nsec3) ($n)" 1680ret=0 1681( 1682cd signer || exit 1 1683rm -f example2.db.signed 1684cp -f example.db.in example2.db 1685cat << EOF >> example2.db 1686sub1.example. IN A 10.53.0.1 1687ns.sub2.example. IN A 10.53.0.2 1688EOF 1689echo "\$INCLUDE \"example2.db.signed\"" >> example2.db 1690touch example2.db.signed 1691$SIGNER -DS -3 feedabee -O full -f example2.db.signed -o example example2.db > /dev/null 1692) || ret=1 1693grep "^sub1\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 || ret=1 1694grep "^ns\\.sub2\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 || ret=1 1695( 1696cd signer || exit 1 1697cp -f example.db.in example2.db 1698cat << EOF >> example2.db 1699sub1.example. IN NS sub1.example. 1700sub1.example. IN A 10.53.0.1 1701sub2.example. IN NS ns.sub2.example. 1702ns.sub2.example. IN A 10.53.0.2 1703EOF 1704echo "\$INCLUDE \"example2.db.signed\"" >> example2.db 1705$SIGNER -DS -3 feedabee -O full -f example2.db.signed -o example example2.db > /dev/null 1706) || ret=1 1707grep "^sub1\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 && ret=1 1708grep "^ns\\.sub2\\.example\\..*RRSIG[ ]A[ ]" signer/example2.db.signed > /dev/null 2>&1 && ret=1 1709n=$((n+1)) 1710test "$ret" -eq 0 || echo_i "failed" 1711status=$((status+ret)) 1712 1713echo_i "checking dnssec-signzone output format ($n)" 1714ret=0 1715( 1716cd signer || exit 1 1717$SIGNER -O full -f - -Sxt -o example example.db > signer.out.3 2> /dev/null 1718$SIGNER -O text -f - -Sxt -o example example.db > signer.out.4 2> /dev/null 1719$SIGNER -O raw -f signer.out.5 -Sxt -o example example.db > /dev/null 1720$SIGNER -O raw=0 -f signer.out.6 -Sxt -o example example.db > /dev/null 1721$SIGNER -O raw -f - -Sxt -o example example.db > signer.out.7 2> /dev/null 1722) || ret=1 1723awk '/IN *SOA/ {if (NF != 11) exit(1)}' signer/signer.out.3 || ret=1 1724awk '/IN *SOA/ {if (NF != 7) exit(1)}' signer/signer.out.4 || ret=1 1725israw1 signer/signer.out.5 || ret=1 1726israw0 signer/signer.out.6 || ret=1 1727israw1 signer/signer.out.7 || ret=1 1728n=$((n+1)) 1729test "$ret" -eq 0 || echo_i "failed" 1730status=$((status+ret)) 1731 1732echo_i "checking TTLs are capped by dnssec-signzone -M ($n)" 1733ret=0 1734( 1735cd signer || exit 1 1736$SIGNER -O full -f signer.out.8 -S -M 30 -o example example.db > /dev/null 1737) || ret=1 1738awk '/^;/ { next; } $2 > 30 { exit 1; }' signer/signer.out.8 || ret=1 1739n=$((n+1)) 1740test "$ret" -eq 0 || echo_i "failed" 1741status=$((status+ret)) 1742 1743echo_i "checking dnssec-signzone -N date ($n)" 1744ret=0 1745( 1746cd signer || exit 1 1747TZ=UTC $SIGNER -O full -f signer.out.9 -S -N date -o example example2.db > /dev/null 1748) || ret=1 1749# shellcheck disable=SC2016 1750now=$(TZ=UTC $PERL -e '@lt=localtime(); printf "%.4d%0.2d%0.2d00\n",$lt[5]+1900,$lt[4]+1,$lt[3];') 1751serial=$(awk '/^;/ { next; } $4 == "SOA" { print $7 }' signer/signer.out.9) 1752[ "$now" -eq "$serial" ] || ret=1 1753n=$((n+1)) 1754test "$ret" -eq 0 || echo_i "failed" 1755status=$((status+ret)) 1756 1757echo_i "checking validated data are not cached longer than originalttl ($n)" 1758ret=0 1759dig_with_opts +ttl +noauth a.ttlpatch.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1 1760dig_with_opts +ttl +noauth a.ttlpatch.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 1761grep "3600.IN" dig.out.ns3.test$n > /dev/null || ret=1 1762grep "300.IN" dig.out.ns3.test$n > /dev/null && ret=1 1763grep "300.IN" dig.out.ns4.test$n > /dev/null || ret=1 1764grep "3600.IN" dig.out.ns4.test$n > /dev/null && ret=1 1765n=$((n+1)) 1766test "$ret" -eq 0 || echo_i "failed" 1767status=$((status+ret)) 1768 1769# Test that "rndc secroots" is able to dump trusted keys 1770echo_i "checking rndc secroots ($n)" 1771ret=0 1772keyid=$(cat ns1/managed.key.id) 1773rndccmd 10.53.0.4 secroots 2>&1 | sed 's/^/ns4 /' | cat_i 1774cp ns4/named.secroots named.secroots.test$n 1775check_secroots_layout named.secroots.test$n || ret=1 1776linecount=$(grep -c "./${DEFAULT_ALGORITHM}/$keyid ; static" named.secroots.test$n || true) 1777[ "$linecount" -eq 1 ] || ret=1 1778linecount=$(< named.secroots.test$n wc -l) 1779[ "$linecount" -eq 9 ] || ret=1 1780n=$((n+1)) 1781test "$ret" -eq 0 || echo_i "failed" 1782status=$((status+ret)) 1783 1784# Check direct query for RRSIG. If we first ask for normal (non RRSIG) 1785# record, the corresponding RRSIG should be cached and subsequent query 1786# for RRSIG will be returned with the cached record. 1787echo_i "checking RRSIG query from cache ($n)" 1788ret=0 1789dig_with_opts normalthenrrsig.secure.example. @10.53.0.4 a > /dev/null || ret=1 1790ans=$(dig_with_opts +short normalthenrrsig.secure.example. @10.53.0.4 rrsig) || ret=1 1791expect=$(dig_with_opts +short normalthenrrsig.secure.example. @10.53.0.3 rrsig | grep '^A' ) || ret=1 1792test "$ans" = "$expect" || ret=1 1793# also check that RA is set 1794dig_with_opts normalthenrrsig.secure.example. @10.53.0.4 rrsig > dig.out.ns4.test$n || ret=1 1795grep "flags:.*ra.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 1796n=$((n+1)) 1797test "$ret" -eq 0 || echo_i "failed" 1798status=$((status+ret)) 1799 1800# Check direct query for RRSIG: If it's not cached with other records, 1801# it should result in an empty response. 1802echo_i "checking RRSIG query not in cache ($n)" 1803ret=0 1804ans=$(dig_with_opts +short rrsigonly.secure.example. @10.53.0.4 rrsig) || ret=1 1805test -z "$ans" || ret=1 1806# also check that RA is cleared 1807dig_with_opts rrsigonly.secure.example. @10.53.0.4 rrsig > dig.out.ns4.test$n || ret=1 1808grep "flags:.*ra.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 1809n=$((n+1)) 1810test "$ret" -eq 0 || echo_i "failed" 1811status=$((status+ret)) 1812 1813# 1814# RT21868 regression test. 1815# 1816echo_i "checking NSEC3 zone with mismatched NSEC3PARAM / NSEC parameters ($n)" 1817ret=0 1818dig_with_opts non-exist.badparam. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 1819grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 1820n=$((n+1)) 1821test "$ret" -eq 0 || echo_i "failed" 1822status=$((status+ret)) 1823 1824# 1825# RT22007 regression test. 1826# 1827echo_i "checking optout NSEC3 referral with only insecure delegations ($n)" 1828ret=0 1829dig_with_opts +norec delegation.single-nsec3. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 1830grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 1831grep "3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN.*NSEC3 1 1 1 - 3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN" dig.out.ns2.test$n > /dev/null || ret=1 1832n=$((n+1)) 1833test "$ret" -eq 0 || echo_i "failed" 1834status=$((status+ret)) 1835 1836echo_i "checking optout NSEC3 NXDOMAIN with only insecure delegations ($n)" 1837ret=0 1838dig_with_opts +norec nonexist.single-nsec3. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 1839grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1 1840grep "3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN.*NSEC3 1 1 1 - 3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN" dig.out.ns2.test$n > /dev/null || ret=1 1841n=$((n+1)) 1842test "$ret" -eq 0 || echo_i "failed" 1843 1844status=$((status+ret)) 1845echo_i "checking optout NSEC3 nodata with only insecure delegations ($n)" 1846ret=0 1847dig_with_opts +norec single-nsec3. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 1848grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 1849grep "3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN.*NSEC3 1 1 1 - 3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN" dig.out.ns2.test$n > /dev/null || ret=1 1850n=$((n+1)) 1851test "$ret" -eq 0 || echo_i "failed" 1852status=$((status+ret)) 1853 1854echo_i "checking that a zone finishing the transition from $ALTERNATIVE_ALGORITHM to $DEFAULT_ALGORITHM validates secure ($n)" 1855ret=0 1856dig_with_opts ns algroll. @10.53.0.4 > dig.out.ns4.test$n || ret=1 1857grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 1858grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n > /dev/null || ret=1 1859n=$((n+1)) 1860test "$ret" -eq 0 || echo_i "failed" 1861status=$((status+ret)) 1862 1863echo_i "checking validate-except in an insecure local domain ($n)" 1864ret=0 1865dig_with_opts ns www.corp @10.53.0.4 > dig.out.ns4.test$n || ret=1 1866grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 1867grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n > /dev/null && ret=1 1868n=$((n+1)) 1869test "$ret" -eq 0 || echo_i "failed" 1870status=$((status+ret)) 1871 1872echo_i "checking positive and negative validation with negative trust anchors ($n)" 1873ret=0 1874 1875# 1876# check correct initial behavior 1877# 1878dig_with_opts a.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.1 || ret=1 1879grep "status: SERVFAIL" dig.out.ns4.test$n.1 > /dev/null || ret=1 1880dig_with_opts badds.example. soa @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1 1881grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null || ret=1 1882dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.3 || ret=1 1883grep "status: SERVFAIL" dig.out.ns4.test$n.3 > /dev/null && ret=1 1884grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.3 > /dev/null || ret=1 1885 1886if [ "$ret" -ne 0 ]; then echo_i "failed - checking initial state"; fi 1887status=$((status+ret)) 1888ret=0 1889 1890# 1891# add negative trust anchors 1892# 1893rndccmd 10.53.0.4 nta -f -l 20s bogus.example 2>&1 | sed 's/^/ns4 /' | cat_i 1894rndccmd 10.53.0.4 nta badds.example 2>&1 | sed 's/^/ns4 /' | cat_i 1895# reconfig should maintain NTAs 1896rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i 1897rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 1898lines=$(wc -l < rndc.out.ns4.test$n.1) 1899[ "$lines" -eq 2 ] || ret=1 1900rndccmd 10.53.0.4 nta secure.example 2>&1 | sed 's/^/ns4 /' | cat_i 1901rndccmd 10.53.0.4 nta fakenode.secure.example 2>&1 | sed 's/^/ns4 /' | cat_i 1902# reload should maintain NTAs 1903rndc_reload ns4 10.53.0.4 1904rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.2 1905lines=$(wc -l < rndc.out.ns4.test$n.2) 1906[ "$lines" -eq 4 ] || ret=1 1907# shellcheck disable=SC2016 1908start=$($PERL -e 'print time()."\n";') 1909 1910if [ "$ret" -ne 0 ]; then echo_i "failed - adding NTA's failed"; fi 1911status=$((status+ret)) 1912ret=0 1913 1914# 1915# check behavior with NTA's in place 1916# 1917dig_with_opts a.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.4 || ret=1 1918grep "status: SERVFAIL" dig.out.ns4.test$n.4 > /dev/null && ret=1 1919grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.4 > /dev/null && ret=1 1920dig_with_opts badds.example. soa @10.53.0.4 > dig.out.ns4.test$n.5 || ret=1 1921grep "status: SERVFAIL" dig.out.ns4.test$n.5 > /dev/null && ret=1 1922grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.5 > /dev/null && ret=1 1923dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.6 || ret=1 1924grep "status: SERVFAIL" dig.out.ns4.test$n.6 > /dev/null && ret=1 1925grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.6 > /dev/null && ret=1 1926dig_with_opts a.fakenode.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.7 || ret=1 1927grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.7 > /dev/null && ret=1 1928echo_i "dumping secroots" 1929rndccmd 10.53.0.4 secroots | sed 's/^/ns4 /' | cat_i 1930cp ns4/named.secroots named.secroots.test$n 1931check_secroots_layout named.secroots.test$n || ret=1 1932grep "bogus.example: expiry" named.secroots.test$n > /dev/null || ret=1 1933grep "badds.example: expiry" named.secroots.test$n > /dev/null || ret=1 1934grep "secure.example: expiry" named.secroots.test$n > /dev/null || ret=1 1935grep "fakenode.secure.example: expiry" named.secroots.test$n > /dev/null || ret=1 1936 1937if [ "$ret" -ne 0 ]; then echo_i "failed - with NTA's in place failed"; fi 1938status=$((status+ret)) 1939ret=0 1940 1941echo_i "waiting for NTA rechecks/expirations" 1942 1943# 1944# secure.example and badds.example used default nta-duration 1945# (configured as 12s in ns4/named1.conf), but nta recheck interval 1946# is configured to 9s, so at t=10 the NTAs for secure.example and 1947# fakenode.secure.example should both be lifted, but badds.example 1948# should still be going. 1949# 1950# shellcheck disable=SC2016 1951$PERL -e 'my $delay = '"$start"' + 10 - time(); select(undef, undef, undef, $delay) if ($delay > 0);' 1952dig_with_opts b.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.8 || ret=1 1953grep "status: SERVFAIL" dig.out.ns4.test$n.8 > /dev/null && ret=1 1954grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.8 > /dev/null || ret=1 1955dig_with_opts b.fakenode.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.9 || ret=1 1956grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.9 > /dev/null || ret=1 1957grep "status: NXDOMAIN" dig.out.ns4.test$n.9 > /dev/null || ret=1 1958dig_with_opts badds.example. soa @10.53.0.4 > dig.out.ns4.test$n.10 || ret=1 1959grep "status: SERVFAIL" dig.out.ns4.test$n.10 > /dev/null && ret=1 1960grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.10 > /dev/null && ret=1 1961 1962if [ "$ret" -ne 0 ]; then echo_i "failed - checking that default nta's were lifted due to recheck"; fi 1963status=$((status+ret)) 1964ret=0 1965 1966# 1967# bogus.example was set to expire in 20s, so at t=13 1968# it should still be NTA'd, but badds.example used the default 1969# lifetime of 12s, so it should revert to SERVFAIL now. 1970# 1971# shellcheck disable=SC2016 1972$PERL -e 'my $delay = '"$start"' + 13 - time(); select(undef, undef, undef, $delay) if ($delay > 0);' 1973# check nta table 1974rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n._11 1975lines=$(grep -c " expiry " rndc.out.ns4.test$n._11 || true) 1976[ "$lines" -le 2 ] || ret=1 1977grep "bogus.example/_default: expiry" rndc.out.ns4.test$n._11 > /dev/null || ret=1 1978grep "badds.example/_default: expiry" rndc.out.ns4.test$n._11 > /dev/null && ret=1 1979dig_with_opts b.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.11 || ret=1 1980grep "status: SERVFAIL" dig.out.ns4.test$n.11 > /dev/null && ret=1 1981dig_with_opts a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.12 || ret=1 1982grep "status: SERVFAIL" dig.out.ns4.test$n.12 > /dev/null || ret=1 1983grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.12 > /dev/null && ret=1 1984dig_with_opts c.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.13 || ret=1 1985grep "status: SERVFAIL" dig.out.ns4.test$n.13 > /dev/null && ret=1 1986grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.13 > /dev/null || ret=1 1987 1988if [ "$ret" -ne 0 ]; then echo_i "failed - checking that default nta's were lifted due to lifetime"; fi 1989status=$((status+ret)) 1990ret=0 1991 1992# 1993# at t=21, all the NTAs should have expired. 1994# 1995# shellcheck disable=SC2016 1996$PERL -e 'my $delay = '"$start"' + 21 - time(); select(undef, undef, undef, $delay) if ($delay > 0);' 1997# check correct behavior after bogus.example expiry 1998dig_with_opts d.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.14 || ret=1 1999grep "status: SERVFAIL" dig.out.ns4.test$n.14 > /dev/null && ret=1 2000grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.14 > /dev/null || ret=1 2001dig_with_opts c.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.15 || ret=1 2002grep "status: SERVFAIL" dig.out.ns4.test$n.15 > /dev/null || ret=1 2003# check nta table has been cleaned up now 2004rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.3 2005lines=$(grep -c " expiry " rndc.out.ns4.test$n.3 || true) 2006[ "$lines" -eq 0 ] || ret=1 2007n=$((n+1)) 2008if [ "$ret" -ne 0 ]; then echo_i "failed - checking that all nta's have been lifted"; fi 2009status=$((status+ret)) 2010ret=0 2011 2012echo_i "testing NTA removals ($n)" 2013rndccmd 10.53.0.4 nta badds.example 2>&1 | sed 's/^/ns4 /' | cat_i 2014rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 2015grep "badds.example/_default: expiry" rndc.out.ns4.test$n.1 > /dev/null || ret=1 2016dig_with_opts a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.1 || ret=1 2017grep "status: SERVFAIL" dig.out.ns4.test$n.1 > /dev/null && ret=1 2018grep "^a.badds.example." dig.out.ns4.test$n.1 > /dev/null || ret=1 2019rndccmd 10.53.0.4 nta -remove badds.example > rndc.out.ns4.test$n.2 2020grep "Negative trust anchor removed: badds.example/_default" rndc.out.ns4.test$n.2 > /dev/null || ret=1 2021rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.3 2022grep "badds.example/_default: expiry" rndc.out.ns4.test$n.3 > /dev/null && ret=1 2023dig_with_opts a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1 2024grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null || ret=1 2025test "$ret" -eq 0 || echo_i "failed" 2026status=$((status+ret)) 2027ret=0 2028 2029echo_i "remove non-existent NTA three times" 2030rndccmd 10.53.0.4 nta -r foo > rndc.out.ns4.test$n.4 2>&1 2031rndccmd 10.53.0.4 nta -remove foo > rndc.out.ns4.test$n.5 2>&1 2032rndccmd 10.53.0.4 nta -r foo > rndc.out.ns4.test$n.6 2>&1 2033grep "not found" rndc.out.ns4.test$n.6 > /dev/null || ret=1 2034test "$ret" -eq 0 || echo_i "failed" 2035status=$((status+ret)) 2036ret=0 2037 2038n=$((n+1)) 2039echo_i "testing NTA with bogus lifetimes ($n)" 2040echo_i "check with no nta lifetime specified" 2041rndccmd 10.53.0.4 nta -l "" foo > rndc.out.ns4.test$n.1 2>&1 || true 2042grep "'nta' failed: bad ttl" rndc.out.ns4.test$n.1 > /dev/null || ret=1 2043test "$ret" -eq 0 || echo_i "failed" 2044status=$((status+ret)) 2045ret=0 2046 2047echo_i "check with bad nta lifetime" 2048rndccmd 10.53.0.4 nta -l garbage foo > rndc.out.ns4.test$n.2 2>&1 || true 2049grep "'nta' failed: bad ttl" rndc.out.ns4.test$n.2 > /dev/null || ret=1 2050test "$ret" -eq 0 || echo_i "failed" 2051status=$((status+ret)) 2052ret=0 2053 2054echo_i "check with too long nta lifetime" 2055rndccmd 10.53.0.4 nta -l 7d1h foo > rndc.out.ns4.test$n.3 2>&1 || true 2056grep "'nta' failed: out of range" rndc.out.ns4.test$n.3 > /dev/null || ret=1 2057test "$ret" -eq 0 || echo_i "failed" 2058status=$((status+ret)) 2059ret=0 2060 2061# 2062# check NTA persistence across restarts 2063# 2064n=$((n+1)) 2065echo_i "testing NTA persistence across restarts ($n)" 2066rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 2067lines=$(grep -c " expiry " rndc.out.ns4.test$n.1 || true) 2068[ "$lines" -eq 0 ] || ret=1 2069rndccmd 10.53.0.4 nta -f -l 30s bogus.example 2>&1 | sed 's/^/ns4 /' | cat_i 2070rndccmd 10.53.0.4 nta -f -l 10s badds.example 2>&1 | sed 's/^/ns4 /' | cat_i 2071rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.2 2072lines=$(grep -c " expiry " rndc.out.ns4.test$n.2 || true) 2073[ "$lines" -eq 2 ] || ret=1 2074# shellcheck disable=SC2016 2075start=$($PERL -e 'print time()."\n";') 2076 2077if [ "$ret" -ne 0 ]; then echo_i "failed - NTA persistence: adding NTA's failed"; fi 2078status=$((status+ret)) 2079ret=0 2080 2081echo_i "killing ns4 with SIGTERM" 2082$KILL -TERM "$(cat ns4/named.pid)" 2083rm -f ns4/named.pid 2084 2085# 2086# ns4 has now shutdown. wait until t=14 when badds.example's NTA 2087# (lifetime=10s) would have expired, and then restart ns4. 2088# 2089echo_i "waiting till 14s have passed since NTAs were added before restarting ns4" 2090# shellcheck disable=SC2016 2091$PERL -e 'my $delay = '"$start"' + 14 - time(); select(undef, undef, undef, $delay) if ($delay > 0);' 2092 2093if 2094 $PERL "$SYSTEMTESTTOP/start.pl" --noclean --restart --port "$PORT" dnssec ns4 2095then 2096 echo_i "restarted server ns4" 2097else 2098 echo_i "could not restart server ns4" 2099 exit 1 2100fi 2101 2102echo_i "sleeping for an additional 4 seconds for ns4 to fully startup" 2103sleep 4 2104 2105# 2106# ns4 should be back up now. The NTA for bogus.example should still be 2107# valid, whereas badds.example should not have been added during named 2108# startup (as it had already expired), the fact that it's ignored should 2109# be logged. 2110# 2111rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.3 2112lines=$(wc -l < rndc.out.ns4.test$n.3) 2113[ "$lines" -eq 1 ] || ret=1 2114grep "bogus.example/_default: expiry" rndc.out.ns4.test$n.3 > /dev/null || ret=1 2115dig_with_opts b.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.4 || ret=1 2116grep "status: SERVFAIL" dig.out.ns4.test$n.4 > /dev/null && ret=1 2117grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.4 > /dev/null && ret=1 2118dig_with_opts a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.5 || ret=1 2119grep "status: SERVFAIL" dig.out.ns4.test$n.5 > /dev/null || ret=1 2120grep "ignoring expired NTA at badds.example" ns4/named.run > /dev/null || ret=1 2121 2122# cleanup 2123rndccmd 10.53.0.4 nta -remove bogus.example > rndc.out.ns4.test$n.6 2124 2125if [ "$ret" -ne 0 ]; then echo_i "failed - NTA persistence: restoring NTA failed"; fi 2126status=$((status+ret)) 2127ret=0 2128 2129# 2130# check "regular" attribute in NTA file works as expected at named 2131# startup. 2132# 2133n=$((n+1)) 2134echo_i "testing loading regular attribute from NTA file ($n)" 2135rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 2>/dev/null 2136lines=$(wc -l < rndc.out.ns4.test$n.1) 2137[ "$lines" -eq 0 ] || ret=1 2138# initially, secure.example. validates with AD=1 2139dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1 2140grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null && ret=1 2141grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.2 > /dev/null || ret=1 2142 2143echo_i "killing ns4 with SIGTERM" 2144$KILL -TERM "$(cat ns4/named.pid)" 2145rm -f ns4/named.pid 2146 2147echo_i "sleeping for an additional 4 seconds for ns4 to fully shutdown" 2148sleep 4 2149 2150# 2151# ns4 has now shutdown. add NTA for secure.example. directly into the 2152# _default.nta file with the regular attribute and some future timestamp. 2153# 2154future="$(($(date +%Y)+20))0101010000" 2155echo "secure.example. regular $future" > ns4/_default.nta 2156# shellcheck disable=SC2016 2157start=$($PERL -e 'print time()."\n";') 2158 2159if 2160 $PERL "$SYSTEMTESTTOP/start.pl" --noclean --restart --port "$PORT" dnssec ns4 2161then 2162 echo_i "restarted server ns4" 2163else 2164 echo_i "could not restart server ns4" 2165 exit 1 2166fi 2167 2168# nta-recheck is configured as 9s, so at t=12 the NTAs for 2169# secure.example. should be lifted as it is not a forced NTA. 2170echo_i "waiting till 12s have passed after ns4 was restarted" 2171# shellcheck disable=SC2016 2172$PERL -e 'my $delay = '"$start"' + 12 - time(); select(undef, undef, undef, $delay) if ($delay > 0);' 2173 2174# secure.example. should now return an AD=1 answer (still validates) as 2175# the NTA has been lifted. 2176dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.3 || ret=1 2177grep "status: SERVFAIL" dig.out.ns4.test$n.3 > /dev/null && ret=1 2178grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.3 > /dev/null || ret=1 2179 2180# cleanup 2181rndccmd 10.53.0.4 nta -remove secure.example > rndc.out.ns4.test$n.4 2>/dev/null 2182 2183if [ "$ret" -ne 0 ]; then echo_i "failed - NTA persistence: loading regular NTAs failed"; fi 2184status=$((status+ret)) 2185ret=0 2186 2187# 2188# check "forced" attribute in NTA file works as expected at named 2189# startup. 2190# 2191n=$((n+1)) 2192echo_i "testing loading forced attribute from NTA file ($n)" 2193rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 2>/dev/null 2194lines=$(wc -l < rndc.out.ns4.test$n.1) 2195[ "$lines" -eq 0 ] || ret=1 2196# initially, secure.example. validates with AD=1 2197dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1 2198grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null && ret=1 2199grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.2 > /dev/null || ret=1 2200 2201echo_i "killing ns4 with SIGTERM" 2202$KILL -TERM "$(cat ns4/named.pid)" 2203rm -f named.pid 2204 2205echo_i "sleeping for an additional 4 seconds for ns4 to fully shutdown" 2206sleep 4 2207 2208# 2209# ns4 has now shutdown. add NTA for secure.example. directly into the 2210# _default.nta file with the forced attribute and some future timestamp. 2211# 2212echo "secure.example. forced $future" > ns4/_default.nta 2213start=$($PERL -e 'print time()."\n";') 2214 2215if 2216 $PERL "$SYSTEMTESTTOP/start.pl" --noclean --restart --port "$PORT" dnssec ns4 2217then 2218 echo_i "restarted server ns4" 2219else 2220 echo_i "could not restart server ns4" 2221 exit 1 2222fi 2223 2224# nta-recheck is configured as 9s, but even at t=12 the NTAs for 2225# secure.example. should not be lifted as it is a forced NTA. 2226echo_i "waiting till 12s have passed after ns4 was restarted" 2227# shellcheck disable=SC2016 2228$PERL -e 'my $delay = '"$start"' + 12 - time(); select(undef, undef, undef, $delay) if ($delay > 0);' 2229 2230# secure.example. should now return an AD=0 answer (non-authenticated) 2231# as the NTA is still there. 2232dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.3 || ret=1 2233grep "status: SERVFAIL" dig.out.ns4.test$n.3 > /dev/null && ret=1 2234grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.3 > /dev/null && ret=1 2235 2236# cleanup 2237rndccmd 10.53.0.4 nta -remove secure.example > rndc.out.ns4.test$n.4 2>/dev/null 2238 2239if [ "$ret" -ne 0 ]; then echo_i "failed - NTA persistence: loading forced NTAs failed"; fi 2240status=$((status+ret)) 2241ret=0 2242 2243# 2244# check that NTA lifetime read from file is clamped to 1 week. 2245# 2246n=$((n+1)) 2247echo_i "testing loading out of bounds lifetime from NTA file ($n)" 2248 2249echo_i "killing ns4 with SIGTERM" 2250$KILL -TERM "$(cat ns4/named.pid)" 2251rm -f ns4/named.pid 2252 2253echo_i "sleeping for an additional 4 seconds for ns4 to fully shutdown" 2254sleep 4 2255 2256# 2257# ns4 has now shutdown. add NTA for secure.example. directly into the 2258# _default.nta file with a lifetime well into the future. 2259# 2260echo "secure.example. forced $future" > ns4/_default.nta 2261added=$($PERL -e 'print time()."\n";') 2262 2263if 2264 $PERL "$SYSTEMTESTTOP/start.pl" --noclean --restart --port "$PORT" dnssec ns4 2265then 2266 echo_i "restarted server ns4" 2267else 2268 echo_i "could not restart server ns4" 2269 exit 1 2270fi 2271 2272echo_i "sleeping for an additional 4 seconds for ns4 to fully startup" 2273sleep 4 2274 2275# dump the NTA to a file (omit validate-except entries) 2276echo_i "testing 'rndc nta'" 2277rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 2>/dev/null 2278# "corp" is configured as a validate-except domain and thus should be 2279# omitted. only "secure.example" should be in the dump at this point. 2280lines=$(wc -l < rndc.out.ns4.test$n.1) 2281[ "$lines" -eq 1 ] || ret=1 2282grep 'secure.example' rndc.out.ns4.test$n.1 > /dev/null || ret=1 2283ts=$(awk '{print $3" "$4}' < rndc.out.ns4.test$n.1) 2284# rndc nta outputs localtime, so append the timezone 2285ts_with_zone="$ts $(date +%z)" 2286echo "ts=$ts" > rndc.out.ns4.test$n.2 2287echo "ts_with_zone=$ts_with_zone" >> rndc.out.ns4.test$n.2 2288echo "added=$added" >> rndc.out.ns4.test$n.2 2289if $PERL -e 'use Time::Piece; use Time::Seconds;' 2>/dev/null 2290then 2291 # ntadiff.pl computes $ts_with_zone - ($added + 1week) 2292 d=$($PERL ./ntadiff.pl "$ts_with_zone" "$added") 2293 echo "d=$d" >> rndc.out.ns4.test$n.2 2294 # diff from $added(now) + 1week to the clamped NTA lifetime should be 2295 # less than a few seconds (handle daylight saving changes by adding 3600). 2296 [ "$d" -lt 3610 ] || ret=1 2297else 2298 echo_i "skipped ntadiff test; install PERL module Time::Piece" 2299fi 2300 2301# cleanup 2302rndccmd 10.53.0.4 nta -remove secure.example > rndc.out.ns4.test$n.3 2>/dev/null 2303 2304n=$((n+1)) 2305if [ "$ret" -ne 0 ]; then echo_i "failed - NTA lifetime clamping failed"; fi 2306status=$((status+ret)) 2307 2308echo_i "checking that NTAs work with 'forward only;' to a validating resolver ($n)" 2309ret=0 2310# Sanity check behavior without an NTA in place. 2311dig_with_opts @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.1 || ret=1 2312grep "SERVFAIL" dig.out.ns9.test$n.1 > /dev/null || ret=1 2313grep "ANSWER: 0" dig.out.ns9.test$n.1 > /dev/null || ret=1 2314grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.1 > /dev/null && ret=1 2315# Add an NTA, expecting that to cause resolution to succeed. 2316rndccmd 10.53.0.9 nta badds.example > rndc.out.ns9.test$n.1 2>&1 || ret=1 2317dig_with_opts @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.2 || ret=1 2318grep "NOERROR" dig.out.ns9.test$n.2 > /dev/null || ret=1 2319grep "ANSWER: 2" dig.out.ns9.test$n.2 > /dev/null || ret=1 2320grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.2 > /dev/null && ret=1 2321# Remove the NTA, expecting that to cause resolution to fail again. 2322rndccmd 10.53.0.9 nta -remove badds.example > rndc.out.ns9.test$n.2 2>&1 || ret=1 2323dig_with_opts @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.3 || ret=1 2324grep "SERVFAIL" dig.out.ns9.test$n.3 > /dev/null || ret=1 2325grep "ANSWER: 0" dig.out.ns9.test$n.3 > /dev/null || ret=1 2326grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.3 > /dev/null && ret=1 2327if [ "$ret" -ne 0 ]; then echo_i "failed"; fi 2328status=$((status+ret)) 2329 2330echo_i "completed NTA tests" 2331 2332# Run a minimal update test if possible. This is really just 2333# a regression test for RT #2399; more tests should be added. 2334 2335if $PERL -e 'use Net::DNS;' 2>/dev/null 2336then 2337 echo_i "running DNSSEC update test" 2338 ret=0 2339 output=$($PERL dnssec_update_test.pl -s 10.53.0.3 -p "$PORT" dynamic.example.) 2340 test "$?" -eq 0 || ret=1 2341 echo "$output" | cat_i 2342 [ $ret -eq 1 ] && status=1 2343else 2344 echo_i "The DNSSEC update test requires the Net::DNS library." >&2 2345fi 2346 2347n=$((n+1)) 2348echo_i "checking managed key maintenance has not started yet ($n)" 2349ret=0 2350[ -f "ns4/managed-keys.bind.jnl" ] && ret=1 2351n=$((n+1)) 2352test "$ret" -eq 0 || echo_i "failed" 2353status=$((status+ret)) 2354 2355# Reconfigure caching server to use "dnssec-validation auto", and repeat 2356# some of the DNSSEC validation tests to ensure that it works correctly. 2357echo_i "switching to automatic root key configuration" 2358copy_setports ns4/named2.conf.in ns4/named.conf 2359rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i 2360sleep 5 2361 2362echo_i "checking managed key maintenance timer has now started ($n)" 2363ret=0 2364[ -f "ns4/managed-keys.bind.jnl" ] || ret=1 2365n=$((n+1)) 2366test "$ret" -eq 0 || echo_i "failed" 2367status=$((status+ret)) 2368 2369echo_i "checking positive validation NSEC ($n)" 2370ret=0 2371dig_with_opts +noauth a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 2372dig_with_opts +noauth a.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 2373digcomp dig.out.ns2.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 positive validation NSEC3 ($n)" 2380ret=0 2381dig_with_opts +noauth a.nsec3.example. \ 2382 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 2383dig_with_opts +noauth a.nsec3.example. \ 2384 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 2385digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 2386grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 2387n=$((n+1)) 2388test "$ret" -eq 0 || echo_i "failed" 2389status=$((status+ret)) 2390 2391echo_i "checking positive validation OPTOUT ($n)" 2392ret=0 2393dig_with_opts +noauth a.optout.example. \ 2394 @10.53.0.3 a > dig.out.ns3.test$n || ret=1 2395dig_with_opts +noauth a.optout.example. \ 2396 @10.53.0.4 a > dig.out.ns4.test$n || ret=1 2397digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 2398grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 2399n=$((n+1)) 2400test "$ret" -eq 0 || echo_i "failed" 2401status=$((status+ret)) 2402 2403echo_i "checking negative validation ($n)" 2404ret=0 2405dig_with_opts +noauth q.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 2406dig_with_opts +noauth q.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 2407digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 2408grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 2409grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 2410n=$((n+1)) 2411test "$ret" -eq 0 || echo_i "failed" 2412status=$((status+ret)) 2413 2414echo_i "checking that root DS queries validate ($n)" 2415ret=0 2416dig_with_opts +noauth . @10.53.0.1 ds > dig.out.ns1.test$n || ret=1 2417dig_with_opts +noauth . @10.53.0.4 ds > dig.out.ns4.test$n || ret=1 2418digcomp dig.out.ns1.test$n dig.out.ns4.test$n || ret=1 2419grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 2420grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2421n=$((n+1)) 2422test "$ret" -eq 0 || echo_i "failed" 2423status=$((status+ret)) 2424 2425echo_i "checking that DS at a RFC 1918 empty zone lookup succeeds ($n)" 2426ret=0 2427dig_with_opts +noauth 10.in-addr.arpa ds @10.53.0.2 >dig.out.ns2.test$n || ret=1 2428dig_with_opts +noauth 10.in-addr.arpa ds @10.53.0.4 >dig.out.ns6.test$n || ret=1 2429digcomp dig.out.ns2.test$n dig.out.ns6.test$n || ret=1 2430grep "status: NOERROR" dig.out.ns6.test$n > /dev/null || ret=1 2431n=$((n+1)) 2432test "$ret" -eq 0 || echo_i "failed" 2433status=$((status+ret)) 2434 2435echo_i "checking expired signatures remain with "'"allow-update { none; };"'" and no keys available ($n)" 2436ret=0 2437dig_with_opts +noauth expired.example. +dnssec @10.53.0.3 soa > dig.out.ns3.test$n || ret=1 2438grep "RRSIG.SOA" dig.out.ns3.test$n > /dev/null || ret=1 2439n=$((n+1)) 2440test "$ret" -eq 0 || echo_i "failed" 2441 2442status=$((status+ret)) 2443echo_i "checking expired signatures do not validate ($n)" 2444ret=0 2445dig_with_opts +noauth expired.example. +dnssec @10.53.0.4 soa > dig.out.ns4.test$n || ret=1 2446grep "SERVFAIL" dig.out.ns4.test$n > /dev/null || ret=1 2447grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 2448grep "expired.example/.*: RRSIG has expired" ns4/named.run > /dev/null || ret=1 2449n=$((n+1)) 2450test "$ret" -eq 0 || echo_i "failed" 2451status=$((status+ret)) 2452 2453echo_i "checking that the NSEC3 record for the apex is properly signed when a DNSKEY is added via UPDATE ($n)" 2454ret=0 2455( 2456cd ns3 || exit 1 2457kskname=$($KEYGEN -q -3 -a RSASHA1 -fk update-nsec3.example) 2458( 2459echo zone update-nsec3.example 2460echo server 10.53.0.3 "$PORT" 2461grep DNSKEY "${kskname}.key" | sed -e 's/^/update add /' -e 's/IN/300 IN/' 2462echo send 2463) | $NSUPDATE 2464) 2465dig_with_opts +dnssec a update-nsec3.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2466grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2467grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1 2468grep "NSEC3 .* TYPE65534" dig.out.ns4.test$n > /dev/null || ret=1 2469n=$((n+1)) 2470test "$ret" -eq 0 || echo_i "failed" 2471status=$((status+ret)) 2472 2473echo_i "checking that the NSEC record is properly generated when DNSKEY are added via auto-dnssec ($n)" 2474ret=0 2475dig_with_opts +dnssec a auto-nsec.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2476grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2477grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1 2478grep "IN.NSEC[^3].* DNSKEY" dig.out.ns4.test$n > /dev/null || ret=1 2479n=$((n+1)) 2480test "$ret" -eq 0 || echo_i "failed" 2481status=$((status+ret)) 2482 2483echo_i "checking that the NSEC3 record is properly generated when DNSKEY are added via auto-dnssec ($n)" 2484ret=0 2485dig_with_opts +dnssec a auto-nsec3.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2486grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2487grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1 2488grep "IN.NSEC3 .* DNSKEY" dig.out.ns4.test$n > /dev/null || ret=1 2489n=$((n+1)) 2490test "$ret" -eq 0 || echo_i "failed" 2491status=$((status+ret)) 2492 2493echo_i "checking that signing records have been marked as complete ($n)" 2494ret=0 2495checkprivate dynamic.example 10.53.0.3 || ret=1 2496checkprivate update-nsec3.example 10.53.0.3 || ret=1 2497checkprivate auto-nsec3.example 10.53.0.3 || ret=1 2498checkprivate expiring.example 10.53.0.3 || ret=1 2499checkprivate auto-nsec.example 10.53.0.3 || ret=1 2500n=$((n+1)) 2501test "$ret" -eq 0 || echo_i "failed" 2502status=$((status+ret)) 2503 2504echo_i "check that 'rndc signing' without arguments is handled ($n)" 2505ret=0 2506rndccmd 10.53.0.3 signing > /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 -list' without zone is handled ($n)" 2513ret=0 2514rndccmd 10.53.0.3 signing -list > /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 -clear' without additional arguments is handled ($n)" 2521ret=0 2522rndccmd 10.53.0.3 signing -clear > /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 -clear all' without zone is handled ($n)" 2529ret=0 2530rndccmd 10.53.0.3 signing -clear all > /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' without additional arguments is handled ($n)" 2537ret=0 2538rndccmd 10.53.0.3 signing -nsec3param > /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 none' without zone is handled ($n)" 2545ret=0 2546rndccmd 10.53.0.3 signing -nsec3param none > /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' without additional arguments is handled ($n)" 2553ret=0 2554rndccmd 10.53.0.3 signing -nsec3param 1 > /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 1 0' without additional arguments is handled ($n)" 2561ret=0 2562rndccmd 10.53.0.3 signing -nsec3param 1 0 > /dev/null 2>&1 && ret=1 2563rndccmd 10.53.0.3 status > /dev/null || ret=1 2564n=$((n+1)) 2565test "$ret" -eq 0 || echo_i "failed" 2566status=$((status+ret)) 2567 2568echo_i "check that 'rndc signing -nsec3param 1 0 0' without additional arguments is handled ($n)" 2569ret=0 2570rndccmd 10.53.0.3 signing -nsec3param 1 0 0 > /dev/null 2>&1 && ret=1 2571rndccmd 10.53.0.3 status > /dev/null || ret=1 2572n=$((n+1)) 2573test "$ret" -eq 0 || echo_i "failed" 2574status=$((status+ret)) 2575 2576echo_i "check that 'rndc signing -nsec3param 1 0 0 -' without zone is handled ($n)" 2577ret=0 2578rndccmd 10.53.0.3 signing -nsec3param 1 0 0 - > /dev/null 2>&1 && ret=1 2579rndccmd 10.53.0.3 status > /dev/null || ret=1 2580n=$((n+1)) 2581test "$ret" -eq 0 || echo_i "failed" 2582status=$((status+ret)) 2583 2584echo_i "check that 'rndc signing -nsec3param' works with salt ($n)" 2585ret=0 2586rndccmd 10.53.0.3 signing -nsec3param 1 0 0 ffff inline.example > /dev/null 2>&1 || ret=1 2587rndccmd 10.53.0.3 status > /dev/null || ret=1 2588for i in 1 2 3 4 5 6 7 8 9 10 ; do 2589 salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}') 2590 if [ "$salt" = "FFFF" ]; then 2591 break; 2592 fi 2593 echo_i "sleeping ...." 2594 sleep 1 2595done; 2596[ "$salt" = "FFFF" ] || ret=1 2597n=$((n+1)) 2598test "$ret" -eq 0 || echo_i "failed" 2599status=$((status+ret)) 2600 2601echo_i "check that 'rndc signing -nsec3param' works without salt ($n)" 2602ret=0 2603rndccmd 10.53.0.3 signing -nsec3param 1 0 0 - inline.example > /dev/null 2>&1 || ret=1 2604rndccmd 10.53.0.3 status > /dev/null || ret=1 2605for i in 1 2 3 4 5 6 7 8 9 10 ; do 2606 salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}') 2607 if [ "$salt" = "-" ]; then 2608 break; 2609 fi 2610 echo_i "sleeping ...." 2611 sleep 1 2612done; 2613[ "$salt" = "-" ] || ret=1 2614n=$((n+1)) 2615test "$ret" -eq 0 || echo_i "failed" 2616status=$((status+ret)) 2617 2618echo_i "check that 'rndc signing -nsec3param' works with 'auto' as salt ($n)" 2619ret=0 2620rndccmd 10.53.0.3 signing -nsec3param 1 0 0 auto inline.example > /dev/null 2>&1 || ret=1 2621rndccmd 10.53.0.3 status > /dev/null || ret=1 2622for i in 1 2 3 4 5 6 7 8 9 10 ; do 2623 salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}') 2624 [ -n "$salt" ] && [ "$salt" != "-" ] && break 2625 echo_i "sleeping ...." 2626 sleep 1 2627done; 2628[ "$salt" != "-" ] || ret=1 2629[ "${#salt}" -eq 16 ] || ret=1 2630n=$((n+1)) 2631test "$ret" -eq 0 || echo_i "failed" 2632status=$((status+ret)) 2633 2634echo_i "check that 'rndc signing -nsec3param' with 'auto' as salt again generates a different salt ($n)" 2635ret=0 2636oldsalt=$salt 2637rndccmd 10.53.0.3 signing -nsec3param 1 0 0 auto inline.example > /dev/null 2>&1 || ret=1 2638rndccmd 10.53.0.3 status > /dev/null || ret=1 2639for i in 1 2 3 4 5 6 7 8 9 10 ; do 2640 salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}') 2641 [ -n "$salt" ] && [ "$salt" != "$oldsalt" ] && break 2642 echo_i "sleeping ...." 2643 sleep 1 2644done; 2645[ "$salt" != "$oldsalt" ] || ret=1 2646[ "${#salt}" -eq 16 ] || ret=1 2647n=$((n+1)) 2648test "$ret" -eq 0 || echo_i "failed" 2649status=$((status+ret)) 2650 2651echo_i "check rndc signing -list output ($n)" 2652ret=0 2653{ rndccmd 10.53.0.3 signing -list dynamic.example > signing.out; } 2>&1 2654grep -q "No signing records found" signing.out || { 2655 ret=1 2656 sed 's/^/ns3 /' signing.out | cat_i 2657} 2658{ rndccmd 10.53.0.3 signing -list update-nsec3.example > signing.out; } 2>&1 2659grep -q "Done signing with key .*/NSEC3RSASHA1" signing.out || { 2660 ret=1 2661 sed 's/^/ns3 /' signing.out | cat_i 2662} 2663n=$((n+1)) 2664test "$ret" -eq 0 || echo_i "failed" 2665status=$((status+ret)) 2666 2667echo_i "clear signing records ($n)" 2668{ rndccmd 10.53.0.3 signing -clear all update-nsec3.example > /dev/null; } 2>&1 || ret=1 2669check_no_signing_record_found() { 2670 { rndccmd 10.53.0.3 signing -list update-nsec3.example > signing.out; } 2>&1 2671 grep -q "No signing records found" signing.out || { 2672 sed 's/^/ns3 /' signing.out | cat_i 2673 return 1 2674 } 2675 return 0 2676} 2677retry_quiet 5 check_no_signing_record_found || ret=1 2678n=$((n+1)) 2679test "$ret" -eq 0 || echo_i "failed" 2680status=$((status+ret)) 2681 2682echo_i "checking that a insecure zone beneath a cname resolves ($n)" 2683ret=0 2684dig_with_opts soa insecure.below-cname.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2685grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2686grep "ANSWER: 1," dig.out.ns4.test$n > /dev/null || ret=1 2687n=$((n+1)) 2688test "$ret" -eq 0 || echo_i "failed" 2689status=$((status+ret)) 2690 2691echo_i "checking that a secure zone beneath a cname resolves ($n)" 2692ret=0 2693dig_with_opts soa secure.below-cname.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2694grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2695grep "ANSWER: 2," dig.out.ns4.test$n > /dev/null || ret=1 2696grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1 2697n=$((n+1)) 2698test "$ret" -eq 0 || echo_i "failed" 2699status=$((status+ret)) 2700 2701my_dig() { 2702 "$DIG" +noadd +nosea +nostat +noquest +nocomm +nocmd -p "$PORT" @10.53.0.4 "$@" 2703} 2704 2705echo_i "checking DNSKEY query with no data still gets put in cache ($n)" 2706ret=0 2707firstVal=$(my_dig insecure.example. dnskey| awk '$1 != ";;" { print $2 }') 2708sleep 1 2709secondVal=$(my_dig insecure.example. dnskey| awk '$1 != ";;" { print $2 }') 2710if [ "${firstVal:-0}" -eq "${secondVal:-0}" ] 2711then 2712 sleep 1 2713 thirdVal=$(my_dig insecure.example. dnskey|awk '$1 != ";;" { print $2 }') 2714 if [ "${firstVal:-0}" -eq "${thirdVal:-0}" ] 2715 then 2716 echo_i "cannot confirm query answer still in cache" 2717 ret=1 2718 fi 2719fi 2720n=$((n+1)) 2721test "$ret" -eq 0 || echo_i "failed" 2722status=$((status+ret)) 2723 2724echo_i "check that a split dnssec dnssec-signzone work ($n)" 2725ret=0 2726dig_with_opts soa split-dnssec.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2727grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2728grep "ANSWER: 2," dig.out.ns4.test$n > /dev/null || ret=1 2729grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1 2730n=$((n+1)) 2731test "$ret" -eq 0 || echo_i "failed" 2732status=$((status+ret)) 2733 2734echo_i "check that a smart split dnssec dnssec-signzone work ($n)" 2735ret=0 2736dig_with_opts soa split-smart.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1 2737grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 2738grep "ANSWER: 2," dig.out.ns4.test$n > /dev/null || ret=1 2739grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1 2740n=$((n+1)) 2741test "$ret" -eq 0 || echo_i "failed" 2742status=$((status+ret)) 2743 2744echo_i "check that NOTIFY is sent at the end of NSEC3 chain generation ($n)" 2745ret=0 2746( 2747echo zone nsec3chain-test 2748echo server 10.53.0.2 "$PORT" 2749echo update add nsec3chain-test. 0 nsec3param 1 0 1 123456 2750echo send 2751) | $NSUPDATE 2752for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 2753do 2754 dig_with_opts nsec3param nsec3chain-test @10.53.0.2 > dig.out.ns2.test$n || ret=1 2755 if grep "ANSWER: 3," dig.out.ns2.test$n >/dev/null 2756 then 2757 break; 2758 fi 2759 echo_i "sleeping ...." 2760 sleep 3 2761done 2762grep "ANSWER: 3," dig.out.ns2.test$n > /dev/null || ret=1 2763if [ "$ret" -ne 0 ]; then echo_i "nsec3 chain generation not complete"; fi 2764dig_with_opts +noauth +nodnssec soa nsec3chain-test @10.53.0.2 > dig.out.ns2.test$n || ret=1 2765s2=$(awk '$4 == "SOA" { print $7}' dig.out.ns2.test$n) 2766for i in 1 2 3 4 5 6 7 8 9 10 2767do 2768 dig_with_opts +noauth +nodnssec soa nsec3chain-test @10.53.0.3 > dig.out.ns3.test$n || ret=1 2769 s3=$(awk '$4 == "SOA" { print $7}' dig.out.ns3.test$n) 2770 test "$s2" = "$s3" && break 2771 sleep 1 2772done 2773digcomp dig.out.ns2.test$n dig.out.ns3.test$n || ret=1 2774n=$((n+1)) 2775test "$ret" -eq 0 || echo_i "failed" 2776status=$((status+ret)) 2777 2778echo_i "check dnssec-dsfromkey from stdin ($n)" 2779ret=0 2780dig_with_opts dnskey algroll. @10.53.0.2 | \ 2781 $DSFROMKEY -f - algroll. > dig.out.ns2.test$n || ret=1 2782NF=$(awk '{print NF}' dig.out.ns2.test$n | sort -u) 2783[ "${NF}" = 7 ] || ret=1 2784# make canonical 2785awk '{ 2786 for (i=1;i<7;i++) printf("%s ", $i); 2787 for (i=7;i<=NF;i++) printf("%s", $i); 2788 printf("\n"); 2789}' < dig.out.ns2.test$n > canonical1.$n || ret=1 2790awk '{ 2791 for (i=1;i<7;i++) printf("%s ", $i); 2792 for (i=7;i<=NF;i++) printf("%s", $i); 2793 printf("\n"); 2794}' < ns1/dsset-algroll$TP > canonical2.$n || ret=1 2795$DIFF -b canonical1.$n canonical2.$n > /dev/null 2>&1 || ret=1 2796n=$((n+1)) 2797test "$ret" -eq 0 || echo_i "failed" 2798status=$((status+ret)) 2799 2800# Intentionally strip ".key" from keyfile name to ensure the error message 2801# includes it anyway to avoid confusion (RT #21731) 2802echo_i "check dnssec-dsfromkey error message when keyfile is not found ($n)" 2803ret=0 2804key=$($KEYGEN -a RSASHA1 -q example.) || ret=1 2805mv "$key.key" "$key" 2806$DSFROMKEY "$key" > dsfromkey.out.$n 2>&1 && ret=1 2807grep "$key.key: file not found" dsfromkey.out.$n > /dev/null || ret=1 2808n=$((n+1)) 2809test "$ret" -eq 0 || echo_i "failed" 2810status=$((status+ret)) 2811 2812echo_i "testing soon-to-expire RRSIGs without a replacement private key ($n)" 2813ret=0 2814dig_with_answeropts +nottlid expiring.example ns @10.53.0.3 | grep RRSIG > dig.out.ns3.test$n 2>&1 2815# there must be a signature here 2816[ -s dig.out.ns3.test$n ] || ret=1 2817n=$((n+1)) 2818test "$ret" -eq 0 || echo_i "failed" 2819status=$((status+ret)) 2820 2821echo_i "testing new records are signed with 'no-resign' ($n)" 2822ret=0 2823( 2824echo zone nosign.example 2825echo server 10.53.0.3 "$PORT" 2826echo update add new.nosign.example 300 in txt "hi there" 2827echo send 2828) | $NSUPDATE 2829sleep 1 2830dig_with_answeropts +nottlid txt new.nosign.example @10.53.0.3 \ 2831 > dig.out.ns3.test$n 2>&1 2832grep RRSIG dig.out.ns3.test$n > /dev/null 2>&1 || ret=1 2833n=$((n+1)) 2834test "$ret" -eq 0 || echo_i "failed" 2835status=$((status+ret)) 2836 2837echo_i "testing expiring records aren't resigned with 'no-resign' ($n)" 2838ret=0 2839dig_with_answeropts +nottlid nosign.example ns @10.53.0.3 | \ 2840 grep RRSIG | sed 's/[ ][ ]*/ /g' > dig.out.ns3.test$n 2>&1 2841# the NS RRSIG should not be changed 2842$DIFF nosign.before dig.out.ns3.test$n > /dev/null|| ret=1 2843n=$((n+1)) 2844test "$ret" -eq 0 || echo_i "failed" 2845status=$((status+ret)) 2846 2847echo_i "testing updates fail with no private key ($n)" 2848ret=0 2849rm -f ns3/Knosign.example.*.private 2850( 2851echo zone nosign.example 2852echo server 10.53.0.3 "$PORT" 2853echo update add fail.nosign.example 300 in txt "reject me" 2854echo send 2855) | $NSUPDATE > /dev/null 2>&1 && ret=1 2856dig_with_answeropts +nottlid fail.nosign.example txt @10.53.0.3 \ 2857 > dig.out.ns3.test$n 2>&1 2858[ -s dig.out.ns3.test$n ] && ret=1 2859n=$((n+1)) 2860test "$ret" -eq 0 || echo_i "failed" 2861status=$((status+ret)) 2862 2863echo_i "testing legacy upper case signer name validation ($n)" 2864ret=0 2865$DIG +tcp +noadd +noauth +dnssec -p "$PORT" soa upper.example @10.53.0.4 \ 2866 > dig.out.ns4.test$n 2>&1 2867grep "flags:.* ad;" dig.out.ns4.test$n > /dev/null || ret=1 2868grep "RRSIG.*SOA.* UPPER\\.EXAMPLE\\. " dig.out.ns4.test$n > /dev/null || ret=1 2869n=$((n+1)) 2870test "$ret" -eq 0 || echo_i "failed" 2871status=$((status+ret)) 2872 2873echo_i "testing that we lower case signer name ($n)" 2874ret=0 2875$DIG +tcp +noadd +noauth +dnssec -p "$PORT" soa LOWER.EXAMPLE @10.53.0.4 \ 2876 > dig.out.ns4.test$n 2>&1 2877grep "flags:.* ad;" dig.out.ns4.test$n > /dev/null || ret=1 2878grep "RRSIG.*SOA.* lower\\.example\\. " dig.out.ns4.test$n > /dev/null || ret=1 2879n=$((n+1)) 2880test "$ret" -eq 0 || echo_i "failed" 2881status=$((status+ret)) 2882 2883echo_i "testing TTL is capped at RRSIG expiry time ($n)" 2884ret=0 2885rndccmd 10.53.0.3 freeze expiring.example 2>&1 | sed 's/^/ns3 /' | cat_i 2886( 2887cd ns3 || exit 1 2888for file in K*.moved; do 2889 mv "$file" "$(basename "$file" .moved)" 2890done 2891$SIGNER -S -N increment -e now+1mi -o expiring.example expiring.example.db > /dev/null 2892) || ret=1 2893rndc_reload ns3 10.53.0.3 expiring.example 2894 2895rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i 2896dig_with_answeropts +cd expiring.example soa @10.53.0.4 > dig.out.ns4.1.$n 2897dig_with_answeropts expiring.example soa @10.53.0.4 > dig.out.ns4.2.$n 2898ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n) 2899ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n) 2900for ttl in ${ttls:-0}; do 2901 [ "${ttl}" -eq 300 ] || ret=1 2902done 2903for ttl in ${ttls2:-0}; do 2904 [ "${ttl}" -le 60 ] || ret=1 2905done 2906n=$((n+1)) 2907test "$ret" -eq 0 || echo_i "failed" 2908status=$((status+ret)) 2909 2910echo_i "testing TTL is capped at RRSIG expiry time for records in the additional section (NS) ($n)" 2911ret=0 2912rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i 2913sleep 1 2914dig_with_additionalopts +cd expiring.example ns @10.53.0.4 > dig.out.ns4.1.$n 2915dig_with_additionalopts expiring.example ns @10.53.0.4 > dig.out.ns4.2.$n 2916ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n) 2917ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n) 2918for ttl in ${ttls:-300}; do 2919 [ "$ttl" -le 300 ] && [ "$ttl" -gt 240 ] || ret=1 2920done 2921for ttl in ${ttls2:-0}; do 2922 [ "$ttl" -le 60 ] || ret=1 2923done 2924n=$((n+1)) 2925test "$ret" -eq 0 || echo_i "failed" 2926status=$((status+ret)) 2927 2928echo_i "testing TTL is capped at RRSIG expiry time for records in the additional section (MX) ($n)" 2929ret=0 2930rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i 2931sleep 1 2932dig_with_additionalopts +cd expiring.example mx @10.53.0.4 > dig.out.ns4.1.$n 2933dig_with_additionalopts expiring.example mx @10.53.0.4 > dig.out.ns4.2.$n 2934ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n) 2935ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n) 2936for ttl in ${ttls:-300}; do 2937 [ "$ttl" -le 300 ] && [ "$ttl" -gt 240 ] || ret=1 2938done 2939for ttl in ${ttls2:-0}; do 2940 [ "$ttl" -le 60 ] || ret=1 2941done 2942n=$((n+1)) 2943test "$ret" -eq 0 || echo_i "failed" 2944status=$((status+ret)) 2945 2946copy_setports ns4/named3.conf.in ns4/named.conf 2947rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i 2948sleep 3 2949 2950echo_i "testing TTL of about to expire RRsets with dnssec-accept-expired yes; ($n)" 2951ret=0 2952rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i 2953dig_with_answeropts +cd expiring.example soa @10.53.0.4 > dig.out.ns4.1.$n 2954dig_with_answeropts expiring.example soa @10.53.0.4 > dig.out.ns4.2.$n 2955ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n) 2956ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n) 2957for ttl in ${ttls:-0}; do 2958 [ "$ttl" -eq 300 ] || ret=1 2959done 2960for ttl in ${ttls2:-0}; do 2961 [ "$ttl" -eq 120 ] || ret=1 2962done 2963n=$((n+1)) 2964test "$ret" -eq 0 || echo_i "failed" 2965status=$((status+ret)) 2966 2967echo_i "testing TTL of expired RRsets with dnssec-accept-expired yes; ($n)" 2968ret=0 2969dig_with_answeropts +cd expired.example soa @10.53.0.4 > dig.out.ns4.1.$n 2970dig_with_answeropts expired.example soa @10.53.0.4 > dig.out.ns4.2.$n 2971ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n) 2972ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n) 2973for ttl in ${ttls:-0}; do 2974 [ "$ttl" -eq 300 ] || ret=1 2975done 2976for ttl in ${ttls2:-0}; do 2977 [ "$ttl" -eq 120 ] || ret=1 2978done 2979n=$((n+1)) 2980test "$ret" -eq 0 || echo_i "failed" 2981status=$((status+ret)) 2982 2983echo_i "testing TTL is capped at RRSIG expiry time for records in the additional section with dnssec-accept-expired yes; ($n)" 2984ret=0 2985rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i 2986dig_with_additionalopts +cd expiring.example mx @10.53.0.4 > dig.out.ns4.1.$n 2987dig_with_additionalopts expiring.example mx @10.53.0.4 > dig.out.ns4.2.$n 2988ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n) 2989ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n) 2990for ttl in ${ttls:-300}; do 2991 [ "$ttl" -le 300 ] && [ "$ttl" -gt 240 ] || ret=1 2992done 2993for ttl in ${ttls2:-0}; do 2994 [ "$ttl" -le 120 ] && [ "$ttl" -gt 60 ] || ret=1 2995done 2996n=$((n+1)) 2997test "$ret" -eq 0 || echo_i "failed" 2998status=$((status+ret)) 2999 3000echo_i "testing DNSKEY lookup via CNAME ($n)" 3001ret=0 3002dig_with_opts +noauth cnameandkey.secure.example. \ 3003 @10.53.0.3 dnskey > dig.out.ns3.test$n || ret=1 3004dig_with_opts +noauth cnameandkey.secure.example. \ 3005 @10.53.0.4 dnskey > dig.out.ns4.test$n || ret=1 3006digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 3007grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3008grep "CNAME" dig.out.ns4.test$n > /dev/null || ret=1 3009n=$((n+1)) 3010test "$ret" -eq 0 || echo_i "failed" 3011status=$((status+ret)) 3012 3013echo_i "testing KEY lookup at CNAME (present) ($n)" 3014ret=0 3015dig_with_opts +noauth cnameandkey.secure.example. \ 3016 @10.53.0.3 key > dig.out.ns3.test$n || ret=1 3017dig_with_opts +noauth cnameandkey.secure.example. \ 3018 @10.53.0.4 key > dig.out.ns4.test$n || ret=1 3019digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 3020grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3021grep "CNAME" dig.out.ns4.test$n > /dev/null && ret=1 3022n=$((n+1)) 3023test "$ret" -eq 0 || echo_i "failed" 3024status=$((status+ret)) 3025 3026echo_i "testing KEY lookup at CNAME (not present) ($n)" 3027ret=0 3028dig_with_opts +noauth cnamenokey.secure.example. \ 3029 @10.53.0.3 key > dig.out.ns3.test$n || ret=1 3030dig_with_opts +noauth cnamenokey.secure.example. \ 3031 @10.53.0.4 key > dig.out.ns4.test$n || ret=1 3032digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 3033grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3034grep "CNAME" dig.out.ns4.test$n > /dev/null && ret=1 3035n=$((n+1)) 3036test "$ret" -eq 0 || echo_i "failed" 3037status=$((status+ret)) 3038 3039echo_i "testing DNSKEY lookup via DNAME ($n)" 3040ret=0 3041dig_with_opts a.dnameandkey.secure.example. \ 3042 @10.53.0.3 dnskey > dig.out.ns3.test$n || ret=1 3043dig_with_opts a.dnameandkey.secure.example. \ 3044 @10.53.0.4 dnskey > dig.out.ns4.test$n || ret=1 3045digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 3046grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3047grep "CNAME" dig.out.ns4.test$n > /dev/null || ret=1 3048grep "DNAME" dig.out.ns4.test$n > /dev/null || ret=1 3049n=$((n+1)) 3050test "$ret" -eq 0 || echo_i "failed" 3051status=$((status+ret)) 3052 3053echo_i "testing KEY lookup via DNAME ($n)" 3054ret=0 3055dig_with_opts b.dnameandkey.secure.example. \ 3056 @10.53.0.3 key > dig.out.ns3.test$n || ret=1 3057dig_with_opts b.dnameandkey.secure.example. \ 3058 @10.53.0.4 key > dig.out.ns4.test$n || ret=1 3059digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1 3060grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3061grep "DNAME" dig.out.ns4.test$n > /dev/null || ret=1 3062n=$((n+1)) 3063test "$ret" -eq 0 || echo_i "failed" 3064status=$((status+ret)) 3065 3066echo_i "check that named doesn't loop when all private keys are not available ($n)" 3067ret=0 3068lines=$(grep -c "reading private key file expiring.example" ns3/named.run || true) 3069test "${lines:-1000}" -lt 15 || ret=1 3070n=$((n+1)) 3071test "$ret" -eq 0 || echo_i "failed" 3072status=$((status+ret)) 3073 3074echo_i "check against against missing nearest provable proof ($n)" 3075dig_with_opts +norec b.c.d.optout-tld. \ 3076 @10.53.0.6 ds > dig.out.ds.ns6.test$n || ret=1 3077nsec3=$(grep -c "IN.NSEC3" dig.out.ds.ns6.test$n || true) 3078[ "$nsec3" -eq 2 ] || ret=1 3079dig_with_opts +norec b.c.d.optout-tld. \ 3080 @10.53.0.6 A > dig.out.ns6.test$n || ret=1 3081nsec3=$(grep -c "IN.NSEC3" dig.out.ns6.test$n || true) 3082[ "$nsec3" -eq 1 ] || ret=1 3083dig_with_opts optout-tld. \ 3084 @10.53.0.4 SOA > dig.out.soa.ns4.test$n || ret=1 3085grep "flags:.*ad.*QUERY" dig.out.soa.ns4.test$n > /dev/null || ret=1 3086dig_with_opts b.c.d.optout-tld. \ 3087 @10.53.0.4 A > dig.out.ns4.test$n || ret=1 3088grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 3089grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 3090n=$((n+1)) 3091test "$ret" -eq 0 || echo_i "failed" 3092status=$((status+ret)) 3093 3094echo_i "check that key id are logged when dumping the cache ($n)" 3095ret=0 3096rndc_dumpdb ns4 3097grep "; key id = " ns4/named_dump.db.test$n > /dev/null || ret=1 3098n=$((n+1)) 3099test "$ret" -eq 0 || echo_i "failed" 3100status=$((status+ret)) 3101 3102echo_i "check KEYDATA records are printed in human readable form in key zone ($n)" 3103# force the managed-keys zone to be written out 3104rndccmd 10.53.0.4 managed-keys sync 2>&1 | sed 's/^/ns4 /' | cat_i 3105for i in 1 2 3 4 5 6 7 8 9 3106do 3107 ret=0 3108 if test -f ns4/managed-keys.bind 3109 then 3110 grep KEYDATA ns4/managed-keys.bind > /dev/null && 3111 grep "next refresh:" ns4/managed-keys.bind > /dev/null && 3112 break 3113 fi 3114 ret=1 3115 sleep 1 3116done 3117n=$((n+1)) 3118test "$ret" -eq 0 || echo_i "failed" 3119status=$((status+ret)) 3120 3121echo_i "check dig's +nocrypto flag ($n)" 3122ret=0 3123dig_with_opts +norec +nocrypto DNSKEY . \ 3124 @10.53.0.1 > dig.out.dnskey.ns1.test$n || ret=1 3125grep -E "256 [0-9]+ $DEFAULT_ALGORITHM_NUMBER \\[key id = [1-9][0-9]*]" dig.out.dnskey.ns1.test$n > /dev/null || ret=1 3126grep -E "RRSIG.* \\[omitted]" dig.out.dnskey.ns1.test$n > /dev/null || ret=1 3127dig_with_opts +norec +nocrypto DS example \ 3128 @10.53.0.1 > dig.out.ds.ns1.test$n || ret=1 3129grep -E "DS.* [0-9]+ [12] \[omitted]" dig.out.ds.ns1.test$n > /dev/null || ret=1 3130n=$((n+1)) 3131test "$ret" -eq 0 || echo_i "failed" 3132status=$((status+ret)) 3133 3134echo_i "check simultaneous inactivation and publishing of dnskeys removes inactive signature ($n)" 3135ret=0 3136cnt=0 3137while : 3138do 3139dig_with_opts publish-inactive.example @10.53.0.3 dnskey > dig.out.ns3.test$n 3140keys=$(awk '$5 == 257 { print; }' dig.out.ns3.test$n | wc -l) 3141test "$keys" -gt 2 && break 3142cnt=$((cnt+1)) 3143test "$cnt" -gt 120 && break 3144sleep 1 3145done 3146test "$keys" -gt 2 || ret=1 3147sigs=$(grep -c RRSIG dig.out.ns3.test$n || true) 3148n=$((n+1)) 3149test "$sigs" -eq 2 || ret=1 3150if test "$ret" -ne 0 ; then echo_i "failed"; fi 3151status=$((status+ret)) 3152 3153echo_i "check that increasing the sig-validity-interval resigning triggers re-signing ($n)" 3154ret=0 3155before=$($DIG axfr siginterval.example -p "$PORT" @10.53.0.3 | grep RRSIG.SOA) 3156cp ns3/siginterval2.conf ns3/siginterval.conf 3157rndccmd 10.53.0.3 reconfig 2>&1 | sed 's/^/ns3 /' | cat_i 3158i=10 3159while [ "$i" -ge 0 ]; do 3160after=$($DIG axfr siginterval.example -p "$PORT" @10.53.0.3 | grep RRSIG.SOA) 3161test "$before" != "$after" && break 3162sleep 1 3163i=$((i-1)) 3164done 3165n=$((n+1)) 3166if test "$before" = "$after" ; then echo_i "failed"; ret=1; fi 3167status=$((status+ret)) 3168 3169if [ -x "$PYTHON" ]; then 3170 echo_i "check dnskey-sig-validity sets longer expiry for DNSKEY ($n)" 3171 ret=0 3172 rndccmd 10.53.0.3 sign siginterval.example 2>&1 | sed 's/^/ns3 /' | cat_i 3173 # convert expiry date to a comma-separated list of integers python can 3174 # use as input to date(). strip leading 0s in months and days so 3175 # python3 will recognize them as integers. 3176 $DIG +dnssec +short -p "$PORT" @10.53.0.3 soa siginterval.example > dig.out.soa.test$n 3177 soaexpire=$(awk '$1 ~ /SOA/ { print $5 }' dig.out.soa.test$n | 3178 sed 's/\(....\)\(..\)\(..\).*/\1, \2, \3/' | 3179 sed 's/ 0/ /g') 3180 $DIG +dnssec +short -p "$PORT" @10.53.0.3 dnskey siginterval.example > dig.out.dnskey.test$n 3181 dnskeyexpire=$(awk '$1 ~ /DNSKEY/ { print $5; exit 0 }' dig.out.dnskey.test$n | 3182 sed 's/\(....\)\(..\)\(..\).*/\1, \2, \3/' | 3183 sed 's/ 0/ /g') 3184 $PYTHON > python.out.$n <<EOF 3185from datetime import date; 3186ke=date($dnskeyexpire) 3187se=date($soaexpire) 3188print((ke-se).days); 3189EOF 3190 diff=$(cat python.out.$n) 3191 [ "$diff" -ge 55 ] || ret=1 3192 n=$((n+1)) 3193 test "$ret" -eq 0 || echo_i "failed" 3194 status=$((status+ret)) 3195fi 3196 3197copy_setports ns4/named4.conf.in ns4/named.conf 3198rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i 3199sleep 3 3200 3201echo_i "check insecure delegation between static-stub zones ($n)" 3202ret=0 3203dig_with_opts ns insecure.secure.example \ 3204 @10.53.0.4 > dig.out.ns4.1.test$n || ret=1 3205grep "SERVFAIL" dig.out.ns4.1.test$n > /dev/null && ret=1 3206dig_with_opts ns secure.example \ 3207 @10.53.0.4 > dig.out.ns4.2.test$n || ret=1 3208grep "SERVFAIL" dig.out.ns4.2.test$n > /dev/null && ret=1 3209n=$((n+1)) 3210test "$ret" -eq 0 || echo_i "failed" 3211status=$((status+ret)) 3212 3213echo_i "check the acceptance of seconds as inception and expiration times ($n)" 3214ret=0 3215in="NSEC 8 0 86400 1390003200 1389394800 33655 . NYWjZYBV1b+h4j0yu/SmPOOylR8P4IXKDzHX3NwEmU1SUp27aJ91dP+i+UBcnPmBib0hck4DrFVvpflCEpCnVQd2DexcN0GX+3PM7XobxhtDlmnU X1L47zJlbdHNwTqHuPaMM6Xy9HGMXps7O5JVyfggVhTz2C+G5OVxBdb2rOo=" 3216 3217exp="NSEC 8 0 86400 20140118000000 20140110230000 33655 . NYWjZYBV1b+h4j0yu/SmPOOylR8P4IXKDzHX3NwEmU1SUp27aJ91dP+i +UBcnPmBib0hck4DrFVvpflCEpCnVQd2DexcN0GX+3PM7XobxhtDlmnU X1L47zJlbdHNwTqHuPaMM6Xy9HGMXps7O5JVyfggVhTz2C+G5OVxBdb2 rOo=" 3218 3219out=$(echo "IN RRSIG $in" | $RRCHECKER -p | sed 's/^IN.RRSIG.//') 3220[ "$out" = "$exp" ] || ret=1 3221n=$((n+1)) 3222test "$ret" -eq 0 || echo_i "failed" 3223status=$((status+ret)) 3224 3225echo_i "check the correct resigning time is reported in zonestatus ($n)" 3226ret=0 3227rndccmd 10.53.0.3 \ 3228 zonestatus secure.example > rndc.out.ns3.test$n 3229# next resign node: secure.example/DNSKEY 3230qname=$(awk '/next resign node:/ { print $4 }' rndc.out.ns3.test$n | sed 's,/.*,,') 3231qtype=$(awk '/next resign node:/ { print $4 }' rndc.out.ns3.test$n | sed 's,.*/,,') 3232# next resign time: Thu, 24 Apr 2014 10:38:16 GMT 3233time=$(awk 'BEGIN { m["Jan"] = "01"; m["Feb"] = "02"; m["Mar"] = "03"; 3234 m["Apr"] = "04"; m["May"] = "05"; m["Jun"] = "06"; 3235 m["Jul"] = "07"; m["Aug"] = "08"; m["Sep"] = "09"; 3236 m["Oct"] = "10"; m["Nov"] = "11"; m["Dec"] = "12";} 3237 /next resign time:/ { printf "%d%s%02d%s\n", $7, m[$6], $5, $8 }' rndc.out.ns3.test$n | sed 's/://g') 3238dig_with_opts +noall +answer "$qname" "$qtype" @10.53.0.3 > dig.out.test$n 3239expire=$(awk '$4 == "RRSIG" { print $9 }' dig.out.test$n) 3240inception=$(awk '$4 == "RRSIG" { print $10 }' dig.out.test$n) 3241$PERL -e 'exit(0) if ("'"$time"'" lt "'"$expire"'" && "'"$time"'" gt "'"$inception"'"); exit(1);' || ret=1 3242n=$((n+1)) 3243test "$ret" -eq 0 || echo_i "failed" 3244status=$((status+ret)) 3245 3246echo_i "check that split rrsigs are handled ($n)" 3247ret=0 3248dig_with_opts split-rrsig soa @10.53.0.7 > dig.out.test$n || ret=1 3249awk 'BEGIN { ok=0; } $4 == "SOA" { if ($7 > 1) ok=1; } END { if (!ok) exit(1); }' dig.out.test$n || ret=1 3250n=$((n+1)) 3251test "$ret" -eq 0 || echo_i "failed" 3252status=$((status+ret)) 3253 3254echo_i "check that not-at-zone-apex RRSIG(SOA) RRsets are removed from the zone after load ($n)" 3255ret=0 3256dig_with_opts split-rrsig AXFR @10.53.0.7 > dig.out.test$n || ret=1 3257grep -q "not-at-zone-apex.*RRSIG.*SOA" dig.out.test$n && ret=1 3258n=$((n+1)) 3259test "$ret" -eq 0 || echo_i "failed" 3260status=$((status+ret)) 3261 3262echo_i "check that 'dnssec-keygen -S' works for all supported algorithms ($n)" 3263ret=0 3264alg=1 3265until test $alg -eq 256 3266do 3267 zone="keygen-$alg." 3268 case $alg in 3269 2) # Diffie Helman 3270 alg=$((alg+1)) 3271 continue;; 3272 157|160|161|162|163|164|165) # private - non standard 3273 alg=$((alg+1)) 3274 continue;; 3275 1|5|7|8|10) # RSA algorithms 3276 key1=$($KEYGEN -a "$alg" -b "1024" -n zone "$zone" 2> "keygen-$alg.err" || true) 3277 ;; 3278 15|16) 3279 key1=$($KEYGEN -a "$alg" -n zone "$zone" 2> "keygen-$alg.err" || true) 3280 # Soft-fail in case HSM doesn't support Edwards curves 3281 if grep "not found" "keygen-$alg.err" > /dev/null && [ "$CRYPTO" = "pkcs11" ]; then 3282 echo_i "Algorithm $alg not supported by HSM: skipping" 3283 alg=$((alg+1)) 3284 continue 3285 fi 3286 ;; 3287 *) 3288 key1=$($KEYGEN -a "$alg" -n zone "$zone" 2> "keygen-$alg.err" || true) 3289 esac 3290 if grep "unsupported algorithm" "keygen-$alg.err" > /dev/null 3291 then 3292 alg=$((alg+1)) 3293 continue 3294 fi 3295 if test -z "$key1" 3296 then 3297 echo_i "'$KEYGEN -a $alg': failed" 3298 cat "keygen-$alg.err" 3299 ret=1 3300 alg=$((alg+1)) 3301 continue 3302 fi 3303 $SETTIME -I now+4d "$key1.private" > /dev/null 3304 key2=$($KEYGEN -v 10 -i 3d -S "$key1.private" 2> /dev/null) 3305 test -f "$key2.key" -a -f "$key2.private" || { 3306 ret=1 3307 echo_i "'dnssec-keygen -S' failed for algorithm: $alg" 3308 } 3309 alg=$((alg+1)) 3310done 3311n=$((n+1)) 3312test "$ret" -eq 0 || echo_i "failed" 3313status=$((status+ret)) 3314 3315echo_i "check that CDS records are signed using KSK by dnssec-signzone ($n)" 3316ret=0 3317dig_with_opts +noall +answer @10.53.0.2 cds cds.secure > dig.out.test$n 3318lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3319test "$lines" -eq 2 || ret=1 3320n=$((n+1)) 3321test "$ret" -eq 0 || echo_i "failed" 3322status=$((status+ret)) 3323 3324echo_i "check that CDS records are not signed using ZSK by dnssec-signzone -x ($n)" 3325ret=0 3326dig_with_opts +noall +answer @10.53.0.2 cds cds-x.secure > dig.out.test$n 3327lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3328test "$lines" -eq 2 || ret=1 3329n=$((n+1)) 3330test "$ret" -eq 0 || echo_i "failed" 3331status=$((status+ret)) 3332 3333echo_i "checking that positive unknown NSEC3 hash algorithm does validate ($n)" 3334ret=0 3335dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 nsec3-unknown.example SOA > dig.out.ns3.test$n 3336dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 nsec3-unknown.example SOA > dig.out.ns4.test$n 3337grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3338grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1 3339grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3340grep "ANSWER: 1," dig.out.ns4.test$n > /dev/null || ret=1 3341n=$((n+1)) 3342test "$ret" -eq 0 || echo_i "failed" 3343status=$((status+ret)) 3344 3345echo_i "check that CDS records are signed using KSK by with dnssec-auto ($n)" 3346ret=0 3347dig_with_opts +noall +answer @10.53.0.2 cds cds-auto.secure > dig.out.test$n 3348lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3349test "$lines" -eq 2 || ret=1 3350n=$((n+1)) 3351test "$ret" -eq 0 || echo_i "failed" 3352status=$((status+ret)) 3353 3354echo_i "check that a CDS deletion record is accepted ($n)" 3355ret=0 3356( 3357echo zone cds-update.secure 3358echo server 10.53.0.2 "$PORT" 3359echo update delete cds-update.secure CDS 3360echo update add cds-update.secure 0 CDS 0 0 0 00 3361echo send 3362) | $NSUPDATE > nsupdate.out.test$n 2>&1 3363dig_with_opts +noall +answer @10.53.0.2 cds cds-update.secure > dig.out.test$n 3364lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l) 3365test "${lines:-10}" -eq 1 || ret=1 3366lines=$(tr -d '\r' < dig.out.test$n | awk '$4 == "CDS" && $5 == "0" && $6 == "0" && $7 == "0" && $8 == "00" {print}' | wc -l) 3367test "$lines" -eq 1 || ret=1 3368n=$((n+1)) 3369test "$ret" -eq 0 || echo_i "failed" 3370status=$((status+ret)) 3371 3372echo_i "check that CDS records are signed using KSK when added by nsupdate ($n)" 3373ret=0 3374( 3375echo zone cds-update.secure 3376echo server 10.53.0.2 "$PORT" 3377echo update delete cds-update.secure CDS 3378echo send 3379dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure | 3380grep "DNSKEY.257" | 3381$DSFROMKEY -12 -C -f - -T 1 cds-update.secure | 3382sed "s/^/update add /" 3383echo send 3384) | $NSUPDATE 3385dig_with_opts +noall +answer @10.53.0.2 cds cds-update.secure > dig.out.test$n 3386lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3387test "$lines" -eq 2 || ret=1 3388lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l) 3389test "$lines" -eq 2 || ret=1 3390n=$((n+1)) 3391test "$ret" -eq 0 || echo_i "failed" 3392status=$((status+ret)) 3393 3394echo_i "check that CDS records are signed only using KSK when added by" 3395echo_ic "nsupdate when dnssec-dnskey-kskonly is yes ($n)" 3396ret=0 3397keyid=$(cat ns2/cds-kskonly.secure.id) 3398( 3399echo zone cds-kskonly.secure 3400echo server 10.53.0.2 "$PORT" 3401echo update delete cds-kskonly.secure CDS 3402echo send 3403dig_with_opts +noall +answer @10.53.0.2 dnskey cds-kskonly.secure | 3404grep "DNSKEY.257" | 3405$DSFROMKEY -12 -C -f - -T 1 cds-kskonly.secure | 3406sed "s/^/update add /" 3407echo send 3408) | $NSUPDATE 3409dig_with_opts +noall +answer @10.53.0.2 cds cds-kskonly.secure > dig.out.test$n 3410lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3411test "$lines" -eq 1 || ret=1 3412lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDS" && $11 == id {print}' dig.out.test$n | wc -l) 3413test "$lines" -eq 1 || ret=1 3414lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l) 3415test "$lines" -eq 2 || ret=1 3416n=$((n+1)) 3417test "$ret" -eq 0 || echo_i "failed" 3418status=$((status+ret)) 3419 3420echo_i "check that CDS deletion records are signed only using KSK when added by" 3421echo_ic "nsupdate when dnssec-dnskey-kskonly is yes ($n)" 3422ret=0 3423keyid=$(cat ns2/cds-kskonly.secure.id) 3424( 3425echo zone cds-kskonly.secure 3426echo server 10.53.0.2 "$PORT" 3427echo update delete cds-kskonly.secure CDS 3428echo update add cds-kskonly.secure 0 CDS 0 0 0 00 3429echo send 3430) | $NSUPDATE 3431dig_with_opts +noall +answer @10.53.0.2 cds cds-kskonly.secure > dig.out.test$n 3432lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3433test "$lines" -eq 1 || ret=1 3434lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDS" && $11 == id {print}' dig.out.test$n | wc -l) 3435test "$lines" -eq 1 || ret=1 3436lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l) 3437test "$lines" -eq 1 || ret=1 3438lines=$(tr -d '\r' < dig.out.test$n | awk '$4 == "CDS" && $5 == "0" && $6 == "0" && $7 == "0" && $8 == "00" {print}' | wc -l) 3439test "$lines" -eq 1 || ret=1 3440n=$((n+1)) 3441test "$ret" -eq 0 || echo_i "failed" 3442status=$((status+ret)) 3443 3444echo_i "checking that positive unknown NSEC3 hash algorithm with OPTOUT does validate ($n)" 3445ret=0 3446dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 optout-unknown.example SOA > dig.out.ns3.test$n 3447dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 optout-unknown.example SOA > dig.out.ns4.test$n 3448grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3449grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1 3450grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3451grep "ANSWER: 1," dig.out.ns4.test$n > /dev/null || ret=1 3452n=$((n+1)) 3453test "$ret" -eq 0 || echo_i "failed" 3454status=$((status+ret)) 3455 3456echo_i "check that a non matching CDS record is accepted with a matching CDS record ($n)" 3457ret=0 3458( 3459echo zone cds-update.secure 3460echo server 10.53.0.2 "$PORT" 3461echo update delete cds-update.secure CDS 3462echo send 3463dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure | 3464grep "DNSKEY.257" | 3465$DSFROMKEY -12 -C -f - -T 1 cds-update.secure | 3466sed "s/^/update add /" 3467dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure | 3468grep "DNSKEY.257" | sed 's/DNSKEY.257/DNSKEY 258/' | 3469$DSFROMKEY -12 -C -A -f - -T 1 cds-update.secure | 3470sed "s/^/update add /" 3471echo send 3472) | $NSUPDATE 3473dig_with_opts +noall +answer @10.53.0.2 cds cds-update.secure > dig.out.test$n 3474lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l) 3475test "$lines" -eq 2 || ret=1 3476lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l) 3477test "$lines" -eq 4 || ret=1 3478n=$((n+1)) 3479test "$ret" -eq 0 || echo_i "failed" 3480status=$((status+ret)) 3481 3482echo_i "checking that negative unknown NSEC3 hash algorithm does not validate ($n)" 3483ret=0 3484dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 nsec3-unknown.example A > dig.out.ns3.test$n 3485dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 nsec3-unknown.example A > dig.out.ns4.test$n 3486grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3487grep "status: SERVFAIL," dig.out.ns4.test$n > /dev/null || ret=1 3488n=$((n+1)) 3489test "$ret" -eq 0 || echo_i "failed" 3490status=$((status+ret)) 3491 3492echo_i "check that CDNSKEY records are signed using KSK by dnssec-signzone ($n)" 3493ret=0 3494dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey.secure > dig.out.test$n 3495lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3496test "$lines" -eq 2 || ret=1 3497n=$((n+1)) 3498test "$ret" -eq 0 || echo_i "failed" 3499status=$((status+ret)) 3500 3501echo_i "check that CDNSKEY records are not signed using ZSK by dnssec-signzone -x ($n)" 3502ret=0 3503dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-x.secure > dig.out.test$n 3504lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3505test "$lines" -eq 2 || ret=1 3506n=$((n+1)) 3507test "$ret" -eq 0 || echo_i "failed" 3508status=$((status+ret)) 3509 3510echo_i "checking that negative unknown NSEC3 hash algorithm with OPTOUT does not validate ($n)" 3511ret=0 3512dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 optout-unknown.example A > dig.out.ns3.test$n 3513dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 optout-unknown.example A > dig.out.ns4.test$n 3514grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3515grep "status: SERVFAIL," dig.out.ns4.test$n > /dev/null || ret=1 3516n=$((n+1)) 3517test "$ret" -eq 0 || echo_i "failed" 3518status=$((status+ret)) 3519 3520echo_i "check that CDNSKEY records are signed using KSK by with dnssec-auto ($n)" 3521ret=0 3522dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-auto.secure > dig.out.test$n 3523lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3524test "$lines" -eq 2 || ret=1 3525n=$((n+1)) 3526test "$ret" -eq 0 || echo_i "failed" 3527status=$((status+ret)) 3528 3529echo_i "checking that unknown DNSKEY algorithm validates as insecure ($n)" 3530ret=0 3531dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 dnskey-unknown.example A > dig.out.ns3.test$n 3532dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 dnskey-unknown.example A > dig.out.ns4.test$n 3533grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3534grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1 3535grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 3536n=$((n+1)) 3537test "$ret" -eq 0 || echo_i "failed" 3538status=$((status+ret)) 3539 3540echo_i "checking that unsupported DNSKEY algorithm validates as insecure ($n)" 3541ret=0 3542dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 dnskey-unsupported.example A > dig.out.ns3.test$n 3543dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 dnskey-unsupported.example A > dig.out.ns4.test$n 3544grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3545grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1 3546grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 3547n=$((n+1)) 3548test "$ret" -eq 0 || echo_i "failed" 3549status=$((status+ret)) 3550 3551echo_i "checking that unsupported DNSKEY algorithm is in DNSKEY RRset ($n)" 3552ret=0 3553dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 dnskey-unsupported-2.example DNSKEY > dig.out.test$n 3554grep "status: NOERROR," dig.out.test$n > /dev/null || ret=1 3555grep "dnskey-unsupported-2\.example\..*IN.*DNSKEY.*257 3 255" dig.out.test$n > /dev/null || ret=1 3556n=$((n+1)) 3557test "$ret" -eq 0 || echo_i "failed" 3558status=$((status+ret)) 3559 3560# TODO: test case for GL #1689. 3561# If we allow the dnssec tools to use deprecated algorithms (such as RSAMD5) 3562# we could write a test that signs a zone with supported and unsupported 3563# algorithm, apply a fixed rrset order such that the unsupported algorithm 3564# precedes the supported one in the DNSKEY RRset, and verify the result still 3565# validates succesfully. 3566 3567echo_i "check that a CDNSKEY deletion record is accepted ($n)" 3568ret=0 3569( 3570echo zone cdnskey-update.secure 3571echo server 10.53.0.2 "$PORT" 3572echo update delete cdnskey-update.secure CDNSKEY 3573echo update add cdnskey-update.secure 0 CDNSKEY 0 3 0 AA== 3574echo send 3575) | $NSUPDATE > nsupdate.out.test$n 2>&1 3576dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-update.secure > dig.out.test$n 3577lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3578test "${lines:-10}" -eq 1 || ret=1 3579lines=$(tr -d '\r' < dig.out.test$n | awk '$4 == "CDNSKEY" && $5 == "0" && $6 == "3" && $7 == "0" && $8 == "AA==" {print}' | wc -l) 3580test "${lines:-10}" -eq 1 || ret=1 3581n=$((n+1)) 3582test "$ret" -eq 0 || echo_i "failed" 3583status=$((status+ret)) 3584 3585echo_i "checking that unknown DNSKEY algorithm + unknown NSEC3 has algorithm validates as insecure ($n)" 3586ret=0 3587dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 dnskey-nsec3-unknown.example A > dig.out.ns3.test$n 3588dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 dnskey-nsec3-unknown.example A > dig.out.ns4.test$n 3589grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3590grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1 3591grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 3592n=$((n+1)) 3593test "$ret" -eq 0 || echo_i "failed" 3594status=$((status+ret)) 3595 3596echo_i "check that CDNSKEY records are signed using KSK when added by nsupdate ($n)" 3597ret=0 3598( 3599echo zone cdnskey-update.secure 3600echo server 10.53.0.2 "$PORT" 3601echo update delete cdnskey-update.secure CDNSKEY 3602dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-update.secure | 3603sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 257/p' 3604echo send 3605) | $NSUPDATE 3606dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-update.secure > dig.out.test$n 3607lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3608test "$lines" -eq 2 || ret=1 3609lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3610test "$lines" -eq 1 || ret=1 3611n=$((n+1)) 3612test "$ret" -eq 0 || echo_i "failed" 3613status=$((status+ret)) 3614 3615echo_i "check that CDNSKEY records are signed only using KSK when added by" 3616echo_ic "nsupdate when dnssec-dnskey-kskonly is yes ($n)" 3617ret=0 3618keyid=$(cat ns2/cdnskey-kskonly.secure.id) 3619( 3620echo zone cdnskey-kskonly.secure 3621echo server 10.53.0.2 "$PORT" 3622echo update delete cdnskey-kskonly.secure CDNSKEY 3623dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-kskonly.secure | 3624sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 257/p' 3625echo send 3626) | $NSUPDATE 3627dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-kskonly.secure > dig.out.test$n 3628lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3629test "$lines" -eq 1 || ret=1 3630lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDNSKEY" && $11 == id {print}' dig.out.test$n | wc -l) 3631test "$lines" -eq 1 || ret=1 3632lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3633test "$lines" -eq 1 || ret=1 3634n=$((n+1)) 3635test "$ret" -eq 0 || echo_i "failed" 3636status=$((status+ret)) 3637 3638echo_i "check that CDNSKEY deletion records are signed only using KSK when added by" 3639echo_ic "nsupdate when dnssec-dnskey-kskonly is yes ($n)" 3640ret=0 3641keyid=$(cat ns2/cdnskey-kskonly.secure.id) 3642( 3643echo zone cdnskey-kskonly.secure 3644echo server 10.53.0.2 "$PORT" 3645echo update delete cdnskey-kskonly.secure CDNSKEY 3646echo update add cdnskey-kskonly.secure 0 CDNSKEY 0 3 0 AA== 3647echo send 3648) | $NSUPDATE 3649dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-kskonly.secure > dig.out.test$n 3650lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3651test "$lines" -eq 1 || ret=1 3652lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDNSKEY" && $11 == id {print}' dig.out.test$n | wc -l) 3653test "$lines" -eq 1 || ret=1 3654lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3655test "$lines" -eq 1 || ret=1 3656lines=$(tr -d '\r' < dig.out.test$n | awk '$4 == "CDNSKEY" && $5 == "0" && $6 == "3" && $7 == "0" && $8 == "AA==" {print}' | wc -l) 3657test "${lines:-10}" -eq 1 || ret=1 3658n=$((n+1)) 3659test "$ret" -eq 0 || echo_i "failed" 3660status=$((status+ret)) 3661 3662echo_i "checking initialization with a revoked managed key ($n)" 3663ret=0 3664copy_setports ns5/named2.conf.in ns5/named.conf 3665rndccmd 10.53.0.5 reconfig 2>&1 | sed 's/^/ns5 /' | cat_i 3666sleep 3 3667dig_with_opts +dnssec @10.53.0.5 SOA . > dig.out.ns5.test$n 3668grep "status: SERVFAIL" dig.out.ns5.test$n > /dev/null || ret=1 3669n=$((n+1)) 3670test "$ret" -eq 0 || echo_i "failed" 3671status=$((status+ret)) 3672 3673echo_i "check that a non matching CDNSKEY record is accepted with a matching CDNSKEY record ($n)" 3674ret=0 3675( 3676echo zone cdnskey-update.secure 3677echo server 10.53.0.2 "$PORT" 3678echo update delete cdnskey-update.secure CDNSKEY 3679dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-update.secure | 3680sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 257/p' 3681dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-update.secure | 3682sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 258/p' 3683echo send 3684) | $NSUPDATE 3685dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-update.secure > dig.out.test$n 3686lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3687test "$lines" -eq 2 || ret=1 3688lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l) 3689test "$lines" -eq 2 || ret=1 3690n=$((n+1)) 3691test "$ret" -eq 0 || echo_i "failed" 3692status=$((status+ret)) 3693 3694echo_i "check that RRSIGs are correctly removed from apex when RRset is removed NSEC ($n)" 3695ret=0 3696# generate signed zone with MX and AAAA records at apex. 3697( 3698cd signer || exit 1 3699$KEYGEN -q -a RSASHA1 -3 -fK remove > /dev/null 3700$KEYGEN -q -a RSASHA1 -33 remove > /dev/null 3701echo > remove.db.signed 3702$SIGNER -S -o remove -D -f remove.db.signed remove.db.in > signer.out.1.$n 3703) 3704grep "RRSIG MX" signer/remove.db.signed > /dev/null || { 3705 ret=1 ; cp signer/remove.db.signed signer/remove.db.signed.pre$n; 3706} 3707# re-generate signed zone without MX and AAAA records at apex. 3708( 3709cd signer || exit 1 3710$SIGNER -S -o remove -D -f remove.db.signed remove2.db.in > signer.out.2.$n 3711) 3712grep "RRSIG MX" signer/remove.db.signed > /dev/null && { 3713 ret=1 ; cp signer/remove.db.signed signer/remove.db.signed.post$n; 3714} 3715n=$((n+1)) 3716test "$ret" -eq 0 || echo_i "failed" 3717status=$((status+ret)) 3718 3719echo_i "check that RRSIGs are correctly removed from apex when RRset is removed NSEC3 ($n)" 3720ret=0 3721# generate signed zone with MX and AAAA records at apex. 3722( 3723cd signer || exit 1 3724echo > remove.db.signed 3725$SIGNER -3 - -S -o remove -D -f remove.db.signed remove.db.in > signer.out.1.$n 3726) 3727grep "RRSIG MX" signer/remove.db.signed > /dev/null || { 3728 ret=1 ; cp signer/remove.db.signed signer/remove.db.signed.pre$n; 3729} 3730# re-generate signed zone without MX and AAAA records at apex. 3731( 3732cd signer || exit 1 3733$SIGNER -3 - -S -o remove -D -f remove.db.signed remove2.db.in > signer.out.2.$n 3734) 3735grep "RRSIG MX" signer/remove.db.signed > /dev/null && { 3736 ret=1 ; cp signer/remove.db.signed signer/remove.db.signed.post$n; 3737} 3738n=$((n+1)) 3739test "$ret" -eq 0 || echo_i "failed" 3740status=$((status+ret)) 3741 3742echo_i "check that a named managed zone that was signed 'in-the-future' is re-signed when loaded ($n)" 3743ret=0 3744dig_with_opts managed-future.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 3745grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 3746grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 3747n=$((n+1)) 3748test "$ret" -eq 0 || echo_i "failed" 3749status=$((status+ret)) 3750 3751echo_i "check that trust-anchor-telemetry queries are logged ($n)" 3752ret=0 3753grep "sending trust-anchor-telemetry query '_ta-[0-9a-f]*/NULL" ns6/named.run > /dev/null || ret=1 3754n=$((n+1)) 3755test "$ret" -eq 0 || echo_i "failed" 3756status=$((status+ret)) 3757 3758echo_i "check that _ta-XXXX trust-anchor-telemetry queries are logged ($n)" 3759ret=0 3760grep "trust-anchor-telemetry '_ta-[0-9a-f]*/IN' from" ns1/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-AAAA trust-anchor-telemetry are not sent when disabled ($n)" 3766ret=0 3767grep "sending trust-anchor-telemetry query '_ta-[0-9a-f]*/IN" 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 KEY-TAG trust-anchor-telemetry queries are logged ($n)" 3773ret=0 3774dig_with_opts . dnskey +ednsopt=KEY-TAG:ffff @10.53.0.1 > dig.out.ns1.test$n || ret=1 3775grep "trust-anchor-telemetry './IN' from .* 65535" ns1/named.run > /dev/null || ret=1 3776n=$((n+1)) 3777test "$ret" -eq 0 || echo_i "failed" 3778status=$((status+ret)) 3779 3780echo_i "check that multiple KEY-TAG trust-anchor-telemetry options don't leak memory ($n)" 3781ret=0 3782dig_with_opts . dnskey +ednsopt=KEY-TAG:fffe +ednsopt=KEY-TAG:fffd @10.53.0.1 > dig.out.ns1.test$n || ret=1 3783grep "trust-anchor-telemetry './IN' from .* 65534" ns1/named.run > /dev/null || ret=1 3784grep "trust-anchor-telemetry './IN' from .* 65533" ns1/named.run > /dev/null && ret=1 3785$PERL $SYSTEMTESTTOP/stop.pl dnssec ns1 || ret=1 3786nextpart ns1/named.run > /dev/null 3787$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} dnssec ns1 || ret=1 3788n=$(($n+1)) 3789test "$ret" -eq 0 || echo_i "failed" 3790status=$((status+ret)) 3791 3792echo_i "waiting for root server to finish reloading ($n)" 3793ret=0 3794wait_for_log 20 "all zones loaded" ns1/named.run || ret=1 3795n=$(($n+1)) 3796test "$ret" -eq 0 || echo_i "failed" 3797status=$((status+ret)) 3798 3799echo_i "check that the view is logged in messages from the validator when using views ($n)" 3800ret=0 3801grep "view rec: *validat" ns4/named.run > /dev/null || ret=1 3802n=$((n+1)) 3803test "$ret" -eq 0 || echo_i "failed" 3804status=$((status+ret)) 3805 3806echo_i "check that DNAME at apex with NSEC3 is correctly signed (dnssec-signzone) ($n)" 3807ret=0 3808dig_with_opts txt dname-at-apex-nsec3.example @10.53.0.3 > dig.out.ns3.test$n || ret=1 3809grep "RRSIG.NSEC3 ${DEFAULT_ALGORITHM_NUMBER} 3 600" dig.out.ns3.test$n > /dev/null || ret=1 3810n=$((n+1)) 3811test "$ret" -eq 0 || echo_i "failed" 3812status=$((status+ret)) 3813 3814echo_i "check that DNSKEY and other occluded data are excluded from the delegating bitmap ($n)" 3815ret=0 3816dig_with_opts axfr occluded.example @10.53.0.3 > dig.out.ns3.test$n || ret=1 3817grep "^delegation.occluded.example..*NSEC.*NS KEY DS RRSIG NSEC$" dig.out.ns3.test$n > /dev/null || ret=1 3818grep "^delegation.occluded.example..*DNSKEY.*" dig.out.ns3.test$n > /dev/null || ret=1 3819grep "^delegation.occluded.example..*AAAA.*" dig.out.ns3.test$n > /dev/null || ret=1 3820n=$((n+1)) 3821test "$ret" -eq 0 || echo_i "failed" 3822status=$((status+ret)) 3823 3824echo_i "checking DNSSEC records are occluded from ANY in an insecure zone ($n)" 3825ret=0 3826dig_with_opts any x.insecure.example. @10.53.0.3 > dig.out.ns3.1.test$n || ret=1 3827grep "status: NOERROR" dig.out.ns3.1.test$n > /dev/null || ret=1 3828grep "ANSWER: 0," dig.out.ns3.1.test$n > /dev/null || ret=1 3829dig_with_opts any zz.secure.example. @10.53.0.3 > dig.out.ns3.2.test$n || ret=1 3830grep "status: NOERROR" dig.out.ns3.2.test$n > /dev/null || ret=1 3831# DNSKEY+RRSIG, NSEC+RRSIG 3832grep "ANSWER: 4," dig.out.ns3.2.test$n > /dev/null || ret=1 3833n=$((n+1)) 3834test "$ret" -eq 0 || echo_i "failed" 3835status=$((status+ret)) 3836 3837# 3838# DNSSEC tests related to unsupported, disabled and revoked trust anchors. 3839# 3840 3841# This nameserver (ns8) is loaded with a bunch of trust anchors. Some of 3842# them are good (enabled.managed, enabled.trusted, secure.managed, 3843# secure.trusted), and some of them are bad (disabled.managed, 3844# revoked.managed, unsupported.managed, disabled.trusted, revoked.trusted, 3845# unsupported.trusted). Make sure that the bad trust anchors are ignored. 3846# This is tested by looking for the corresponding lines in the logfile. 3847echo_i "checking that keys with unsupported algorithms and disabled algorithms are ignored ($n)" 3848ret=0 3849grep -q "ignoring static-key for 'disabled\.trusted\.': algorithm is disabled" ns8/named.run || ret=1 3850grep -q "ignoring static-key for 'unsupported\.trusted\.': algorithm is unsupported" ns8/named.run || ret=1 3851grep -q "ignoring static-key for 'revoked\.trusted\.': bad key type" ns8/named.run || ret=1 3852grep -q "ignoring initial-key for 'disabled\.managed\.': algorithm is disabled" ns8/named.run || ret=1 3853grep -q "ignoring initial-key for 'unsupported\.managed\.': algorithm is unsupported" ns8/named.run || ret=1 3854grep -q "ignoring initial-key for 'revoked\.managed\.': bad key type" ns8/named.run || ret=1 3855n=$((n+1)) 3856test "$ret" -eq 0 || echo_i "failed" 3857status=$((status+ret)) 3858 3859# The next two tests are fairly normal DNSSEC queries to signed zones with a 3860# default algorithm. First, a query is made against the server that is 3861# authoritative for the given zone (ns3). Second, a query is made against a 3862# resolver with trust anchors for the given zone (ns8). Both are expected to 3863# return an authentic data positive response. 3864echo_i "checking that a trusted key using a supported algorithm validates as secure ($n)" 3865ret=0 3866dig_with_opts @10.53.0.3 a.secure.trusted A > dig.out.ns3.test$n 3867dig_with_opts @10.53.0.8 a.secure.trusted A > dig.out.ns8.test$n 3868grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3869grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3870grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 3871n=$((n+1)) 3872test "$ret" -eq 0 || echo_i "failed" 3873status=$((status+ret)) 3874 3875echo_i "checking that a managed key using a supported algorithm validates as secure ($n)" 3876ret=0 3877dig_with_opts @10.53.0.3 a.secure.managed A > dig.out.ns3.test$n 3878dig_with_opts @10.53.0.8 a.secure.managed A > dig.out.ns8.test$n 3879grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3880grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3881grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 3882n=$((n+1)) 3883test "$ret" -eq 0 || echo_i "failed" 3884status=$((status+ret)) 3885 3886# The next two queries ensure that a zone signed with a DNSKEY with an unsupported 3887# algorithm will yield insecure positive responses. These trust anchors in ns8 are 3888# ignored and so this domain is treated as insecure. The AD bit should not be set 3889# in the response. 3890echo_i "checking that a trusted key using an unsupported algorithm validates as insecure ($n)" 3891ret=0 3892dig_with_opts @10.53.0.3 a.unsupported.trusted A > dig.out.ns3.test$n 3893dig_with_opts @10.53.0.8 a.unsupported.trusted A > dig.out.ns8.test$n 3894grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3895grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3896grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 3897n=$((n+1)) 3898test "$ret" -eq 0 || echo_i "failed" 3899status=$((status+ret)) 3900 3901echo_i "checking that a managed key using an unsupported algorithm validates as insecure ($n)" 3902ret=0 3903dig_with_opts @10.53.0.3 a.unsupported.managed A > dig.out.ns3.test$n 3904dig_with_opts @10.53.0.8 a.unsupported.managed A > dig.out.ns8.test$n 3905grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3906grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3907grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 3908n=$((n+1)) 3909test "$ret" -eq 0 || echo_i "failed" 3910status=$((status+ret)) 3911 3912# The next two queries ensure that a zone signed with a DNSKEY that the nameserver 3913# has a disabled algorithm match for will yield insecure positive responses. 3914# These trust anchors in ns8 are ignored and so this domain is treated as insecure. 3915# The AD bit should not be set in the response. 3916echo_i "checking that a trusted key using a disabled algorithm validates as insecure ($n)" 3917ret=0 3918dig_with_opts @10.53.0.3 a.disabled.trusted A > dig.out.ns3.test$n 3919dig_with_opts @10.53.0.8 a.disabled.trusted A > dig.out.ns8.test$n 3920grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3921grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3922grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 3923n=$((n+1)) 3924test "$ret" -eq 0 || echo_i "failed" 3925status=$((status+ret)) 3926 3927echo_i "checking that a managed key using a disabled algorithm validates as insecure ($n)" 3928ret=0 3929dig_with_opts @10.53.0.3 a.disabled.managed A > dig.out.ns3.test$n 3930dig_with_opts @10.53.0.8 a.disabled.managed A > dig.out.ns8.test$n 3931grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3932grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3933grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 3934n=$((n+1)) 3935test "$ret" -eq 0 || echo_i "failed" 3936status=$((status+ret)) 3937 3938# The next two queries ensure that a zone signed with a DNSKEY that the 3939# nameserver has a disabled algorithm for, but for a different domain, will 3940# yield secure positive responses. Since "enabled.trusted." and 3941# "enabled.managed." do not match the "disable-algorithms" option, no 3942# special rules apply and these zones should validate as secure, with the AD 3943# bit set. 3944echo_i "checking that a trusted key using an algorithm disabled for another domain validates as secure ($n)" 3945ret=0 3946dig_with_opts @10.53.0.3 a.enabled.trusted A > dig.out.ns3.test$n 3947dig_with_opts @10.53.0.8 a.enabled.trusted A > dig.out.ns8.test$n 3948grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3949grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3950grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 3951n=$((n+1)) 3952test "$ret" -eq 0 || echo_i "failed" 3953status=$((status+ret)) 3954 3955echo_i "checking that a managed key using an algorithm disabled for another domain validates as secure ($n)" 3956ret=0 3957dig_with_opts @10.53.0.3 a.enabled.managed A > dig.out.ns3.test$n 3958dig_with_opts @10.53.0.8 a.enabled.managed A > dig.out.ns8.test$n 3959grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3960grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3961grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1 3962n=$((n+1)) 3963test "$ret" -eq 0 || echo_i "failed" 3964status=$((status+ret)) 3965 3966# A configured revoked trust anchor is ignored and thus the two queries below 3967# should result in insecure responses, since no trust points for the 3968# "revoked.trusted." and "revoked.managed." zones are created. 3969echo_i "checking that a trusted key that is revoked validates as insecure ($n)" 3970ret=0 3971dig_with_opts @10.53.0.3 a.revoked.trusted A > dig.out.ns3.test$n 3972dig_with_opts @10.53.0.8 a.revoked.trusted A > dig.out.ns8.test$n 3973grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3974grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3975grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 3976n=$((n+1)) 3977test "$ret" -eq 0 || echo_i "failed" 3978status=$((status+ret)) 3979 3980echo_i "checking that a managed key that is revoked validates as insecure ($n)" 3981ret=0 3982dig_with_opts @10.53.0.3 a.revoked.managed A > dig.out.ns3.test$n 3983dig_with_opts @10.53.0.8 a.revoked.managed A > dig.out.ns8.test$n 3984grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1 3985grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1 3986grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1 3987n=$((n+1)) 3988test "$ret" -eq 0 || echo_i "failed" 3989status=$((status+ret)) 3990 3991### 3992### Additional checks for when the KSK is offline. 3993### 3994 3995# Save some useful information 3996zone="updatecheck-kskonly.secure" 3997KSK=`cat ns2/${zone}.ksk.key` 3998ZSK=`cat ns2/${zone}.zsk.key` 3999KSK_ID=`cat ns2/${zone}.ksk.id` 4000ZSK_ID=`cat ns2/${zone}.zsk.id` 4001SECTIONS="+answer +noauthority +noadditional" 4002echo_i "testing zone $zone KSK=$KSK_ID ZSK=$ZSK_ID" 4003 4004# Print IDs of keys used for generating RRSIG records for RRsets of type $1 4005# found in dig output file $2. 4006get_keys_which_signed() { 4007 qtype=$1 4008 output=$2 4009 # The key ID is the 11th column of the RRSIG record line. 4010 awk -v qt="$qtype" '$4 == "RRSIG" && $5 == qt {print $11}' < "$output" 4011} 4012 4013# Basic checks to make sure everything is fine before the KSK is made offline. 4014for qtype in "DNSKEY" "CDNSKEY" "CDS" 4015do 4016 echo_i "checking $qtype RRset is signed with KSK only (update-check-ksk, dnssec-ksk-only) ($n)" 4017 ret=0 4018 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4019 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4020 test "$lines" -eq 1 || ret=1 4021 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null || ret=1 4022 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4023 n=$((n+1)) 4024 test "$ret" -eq 0 || echo_i "failed" 4025 status=$((status+ret)) 4026done 4027 4028echo_i "checking SOA RRset is signed with ZSK only (update-check-ksk and dnssec-ksk-only) ($n)" 4029ret=0 4030dig_with_opts $SECTIONS @10.53.0.2 soa $zone > dig.out.test$n 4031lines=$(get_keys_which_signed "SOA" dig.out.test$n | wc -l) 4032test "$lines" -eq 1 || ret=1 4033get_keys_which_signed "SOA" dig.out.test$n | grep "^$KSK_ID$" > /dev/null && ret=1 4034get_keys_which_signed "SOA" dig.out.test$n | grep "^$ZSK_ID$" > /dev/null || ret=1 4035n=$((n+1)) 4036test "$ret" -eq 0 || echo_i "failed" 4037status=$((status+ret)) 4038 4039# Roll the ZSK. 4040zsk2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -K ns2 -n zone "$zone") 4041keyfile_to_key_id "$zsk2" > ns2/$zone.zsk.id2 4042ZSK_ID2=`cat ns2/$zone.zsk.id2` 4043 4044echo_i "load new ZSK $ZSK_ID2 for $zone ($n)" 4045ret=0 4046dnssec_loadkeys_on 2 $zone || ret=1 4047n=$((n+1)) 4048test "$ret" -eq 0 || echo_i "failed" 4049status=$((status+ret)) 4050 4051# Make new ZSK active. 4052echo_i "make ZSK $ZSK_ID inactive and make new ZSK $ZSK_ID2 active for zone $zone ($n)" 4053ret=0 4054$SETTIME -I now -K ns2 $ZSK > /dev/null 4055$SETTIME -A now -K ns2 $zsk2 > /dev/null 4056dnssec_loadkeys_on 2 $zone || ret=1 4057n=$((n+1)) 4058test "$ret" -eq 0 || echo_i "failed" 4059status=$((status+ret)) 4060 4061# Remove the KSK from disk. 4062echo_i "remove the KSK $KSK_ID for zone $zone from disk" 4063mv ns2/$KSK.key ns2/$KSK.key.bak 4064mv ns2/$KSK.private ns2/$KSK.private.bak 4065 4066# Update the zone that requires a resign of the SOA RRset. 4067echo_i "update the zone with $zone IN TXT nsupdate added me" 4068( 4069echo zone $zone 4070echo server 10.53.0.2 "$PORT" 4071echo update add $zone. 300 in txt "nsupdate added me" 4072echo send 4073) | $NSUPDATE 4074 4075# Redo the tests now that the zone is updated and the KSK is offline. 4076for qtype in "DNSKEY" "CDNSKEY" "CDS" 4077do 4078 echo_i "checking $qtype RRset is signed with KSK only, KSK offline (update-check-ksk, dnssec-ksk-only) ($n)" 4079 ret=0 4080 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4081 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4082 test "$lines" -eq 1 || ret=1 4083 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null || ret=1 4084 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4085 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null && ret=1 4086 n=$((n+1)) 4087 test "$ret" -eq 0 || echo_i "failed" 4088 status=$((status+ret)) 4089done 4090 4091for qtype in "SOA" "TXT" 4092do 4093 echo_i "checking $qtype RRset is signed with ZSK only, KSK offline (update-check-ksk and dnssec-ksk-only) ($n)" 4094 ret=0 4095 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4096 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4097 test "$lines" -eq 1 || ret=1 4098 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null && ret=1 4099 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4100 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null || ret=1 4101 n=$((n+1)) 4102 test "$ret" -eq 0 || echo_i "failed" 4103 status=$((status+ret)) 4104done 4105 4106# Put back the KSK. 4107echo_i "put back the KSK $KSK_ID for zone $zone from disk" 4108mv ns2/$KSK.key.bak ns2/$KSK.key 4109mv ns2/$KSK.private.bak ns2/$KSK.private 4110 4111# Roll the ZSK again. 4112zsk3=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -K ns2 -n zone "$zone") 4113keyfile_to_key_id "$zsk3" > ns2/$zone.zsk.id3 4114ZSK_ID3=`cat ns2/$zone.zsk.id3` 4115 4116# Schedule the new ZSK (ZSK3) to become active. 4117echo_i "delete old ZSK $ZSK_ID schedule ZSK $ZSK_ID2 inactive and new ZSK $ZSK_ID3 active for zone $zone ($n)" 4118$SETTIME -D now -K ns2 $ZSK > /dev/null 4119$SETTIME -I +3600 -K ns2 $zsk2 > /dev/null 4120$SETTIME -A +3600 -K ns2 $zsk3 > /dev/null 4121dnssec_loadkeys_on 2 $zone || ret=1 4122n=$((n+1)) 4123test "$ret" -eq 0 || echo_i "failed" 4124status=$((status+ret)) 4125 4126# Remove the KSK from disk. 4127echo_i "remove the KSK $KSK_ID for zone $zone from disk" 4128mv ns2/$KSK.key ns2/$KSK.key.bak 4129mv ns2/$KSK.private ns2/$KSK.private.bak 4130 4131# Update the zone that requires a resign of the SOA RRset. 4132echo_i "update the zone with $zone IN TXT nsupdate added me again" 4133( 4134echo zone $zone 4135echo server 10.53.0.2 "$PORT" 4136echo update add $zone. 300 in txt "nsupdate added me again" 4137echo send 4138) | $NSUPDATE 4139 4140# Redo the tests now that the ZSK roll has deleted the old key. 4141for qtype in "DNSKEY" "CDNSKEY" "CDS" 4142do 4143 echo_i "checking $qtype RRset is signed with KSK only, old ZSK deleted (update-check-ksk, dnssec-ksk-only) ($n)" 4144 ret=0 4145 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4146 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4147 test "$lines" -eq 1 || ret=1 4148 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null || ret=1 4149 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4150 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null && ret=1 4151 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID3$" > /dev/null && ret=1 4152 n=$((n+1)) 4153 test "$ret" -eq 0 || echo_i "failed" 4154 status=$((status+ret)) 4155done 4156 4157for qtype in "SOA" "TXT" 4158do 4159 echo_i "checking $qtype RRset is signed with ZSK only, old ZSK deleted (update-check-ksk and dnssec-ksk-only) ($n)" 4160 ret=0 4161 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4162 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4163 test "$lines" -eq 1 || ret=1 4164 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null && ret=1 4165 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4166 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null || ret=1 4167 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID3$" > /dev/null && ret=1 4168 n=$((n+1)) 4169 test "$ret" -eq 0 || echo_i "failed" 4170 status=$((status+ret)) 4171done 4172 4173# Make the new ZSK (ZSK3) active. 4174echo_i "make new ZSK $ZSK_ID3 active for zone $zone ($n)" 4175$SETTIME -I +1 -K ns2 $zsk2 > /dev/null 4176$SETTIME -A +1 -K ns2 $zsk3 > /dev/null 4177dnssec_loadkeys_on 2 $zone || ret=1 4178n=$((n+1)) 4179test "$ret" -eq 0 || echo_i "failed" 4180status=$((status+ret)) 4181 4182# Wait for newest ZSK to become active. 4183echo_i "wait until new ZSK $ZSK_ID3 active and ZSK $ZSK_ID2 inactive" 4184for i in 1 2 3 4 5 6 7 8 9 10; do 4185 ret=0 4186 grep "DNSKEY $zone/$DEFAULT_ALGORITHM/$ZSK_ID3 (ZSK) is now active" ns2/named.run > /dev/null || ret=1 4187 grep "DNSKEY $zone/$DEFAULT_ALGORITHM/$ZSK_ID2 (ZSK) is now inactive" ns2/named.run > /dev/null || ret=1 4188 [ "$ret" -eq 0 ] && break 4189 sleep 1 4190done 4191n=$((n+1)) 4192test "$ret" -eq 0 || echo_i "failed" 4193status=$((status+ret)) 4194 4195# Update the zone that requires a resign of the SOA RRset. 4196echo_i "update the zone with $zone IN TXT nsupdate added me one more time" 4197( 4198echo zone $zone 4199echo server 10.53.0.2 "$PORT" 4200echo update add $zone. 300 in txt "nsupdate added me one more time" 4201echo send 4202) | $NSUPDATE 4203n=$((n+1)) 4204test "$ret" -eq 0 || echo_i "failed" 4205status=$((status+ret)) 4206 4207# Redo the tests one more time. 4208for qtype in "DNSKEY" "CDNSKEY" "CDS" 4209do 4210 echo_i "checking $qtype RRset is signed with KSK only, new ZSK active (update-check-ksk, dnssec-ksk-only) ($n)" 4211 ret=0 4212 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4213 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4214 test "$lines" -eq 1 || ret=1 4215 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null || ret=1 4216 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4217 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null && ret=1 4218 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID3$" > /dev/null && ret=1 4219 n=$((n+1)) 4220 test "$ret" -eq 0 || echo_i "failed" 4221 status=$((status+ret)) 4222done 4223 4224for qtype in "SOA" "TXT" 4225do 4226 echo_i "checking $qtype RRset is signed with ZSK only, new ZSK active (update-check-ksk and dnssec-ksk-only) ($n)" 4227 ret=0 4228 dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n 4229 lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l) 4230 test "$lines" -eq 1 || ret=1 4231 get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null && ret=1 4232 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1 4233 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null && ret=1 4234 get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID3$" > /dev/null || ret=1 4235 n=$((n+1)) 4236 test "$ret" -eq 0 || echo_i "failed" 4237 status=$((status+ret)) 4238done 4239 4240echo_i "checking secroots output with multiple views ($n)" 4241ret=0 4242rndccmd 10.53.0.4 secroots 2>&1 | sed 's/^/ns4 /' | cat_i 4243cp ns4/named.secroots named.secroots.test$n 4244check_secroots_layout named.secroots.test$n || ret=1 4245n=$((n+1)) 4246test "$ret" -eq 0 || echo_i "failed" 4247status=$((status+ret)) 4248 4249echo_i "checking sig-validity-interval second field hours vs days ($n)" 4250ret=0 4251# zone configured with 'sig-validity-interval 500 499;' 4252# 499 days in the future w/ a 20 minute runtime to now allowance 4253min=$(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];') 4254dig_with_opts @10.53.0.2 hours-vs-days AXFR > dig.out.ns2.test$n 4255awk -v min=$min '$4 == "RRSIG" { if ($9 < min) { exit(1); } }' dig.out.ns2.test$n || ret=1 4256n=$((n+1)) 4257test "$ret" -eq 0 || echo_i "failed" 4258status=$((status+ret)) 4259 4260echo_i "checking validation succeeds during transition to signed ($n)" 4261ret=0 4262dig_with_opts @10.53.0.4 inprogress A > dig.out.ns4.test$n || ret=1 4263grep "flags: qr rd ra;" dig.out.ns4.test$n >/dev/null || ret=1 4264grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 4265grep 'A.10\.53\.0\.10' dig.out.ns4.test$n >/dev/null || ret=1 4266n=$((n+1)) 4267test "$ret" -eq 0 || echo_i "failed" 4268status=$((status+ret)) 4269 4270echo_i "checking excessive NSEC3 iteration warnings in named.run ($n)" 4271ret=0 4272grep "zone too-many-iterations/IN: excessive NSEC3PARAM iterations [0-9]* > 150" ns2/named.run >/dev/null 2>&1 || ret=1 4273grep "zone too-many-iterations/IN: excessive NSEC3PARAM iterations [0-9]* > 150" ns3/named.run >/dev/null 2>&1 || ret=1 4274n=$((n+1)) 4275test "$ret" -eq 0 || echo_i "failed" 4276status=$((status+ret)) 4277 4278# Check that the validating resolver will fallback to insecure if the answer 4279# contains NSEC3 records with high iteration count. 4280echo_i "checking fallback to insecure when NSEC3 iterations is too high (nxdomain) ($n)" 4281ret=0 4282dig_with_opts @10.53.0.2 does-not-exist.too-many-iterations > dig.out.ns2.test$n || ret=1 4283dig_with_opts @10.53.0.4 does-not-exist.too-many-iterations > dig.out.ns4.test$n || ret=1 4284digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 4285grep "flags: qr rd ra;" dig.out.ns4.test$n >/dev/null || ret=1 4286grep "status: NXDOMAIN" dig.out.ns4.test$n >/dev/null || ret=1 4287grep "ANSWER: 0, AUTHORITY: 6" dig.out.ns4.test$n > /dev/null || ret=1 4288n=$((n+1)) 4289test "$ret" -eq 0 || echo_i "failed" 4290status=$((status+ret)) 4291 4292echo_i "checking fallback to insecure when NSEC3 iterations is too high (nodata) ($n)" 4293ret=0 4294dig_with_opts @10.53.0.2 a.too-many-iterations txt > dig.out.ns2.test$n || ret=1 4295dig_with_opts @10.53.0.4 a.too-many-iterations txt > dig.out.ns4.test$n || ret=1 4296digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 4297grep "flags: qr rd ra;" dig.out.ns4.test$n >/dev/null || ret=1 4298grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 4299grep "ANSWER: 0, AUTHORITY: 4" dig.out.ns4.test$n > /dev/null || ret=1 4300n=$((n+1)) 4301test "$ret" -eq 0 || echo_i "failed" 4302status=$((status+ret)) 4303 4304echo_i "checking fallback to insecure when NSEC3 iterations is too high (wildcard) ($n)" 4305ret=0 4306dig_with_opts @10.53.0.2 wild.a.too-many-iterations > dig.out.ns2.test$n || ret=1 4307dig_with_opts @10.53.0.4 wild.a.too-many-iterations > dig.out.ns4.test$n || ret=1 4308digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 4309grep "flags: qr rd ra;" dig.out.ns4.test$n >/dev/null || ret=1 4310grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 4311grep 'wild\.a\.too-many-iterations\..*A.10\.0\.0\.3' dig.out.ns4.test$n >/dev/null || ret=1 4312grep "ANSWER: 2, AUTHORITY: 4" dig.out.ns4.test$n > /dev/null || ret=1 4313n=$((n+1)) 4314test "$ret" -eq 0 || echo_i "failed" 4315status=$((status+ret)) 4316 4317echo_i "checking fallback to insecure when NSEC3 iterations is too high (wildcard nodata) ($n)" 4318ret=0 4319dig_with_opts @10.53.0.2 type100 wild.a.too-many-iterations > dig.out.ns2.test$n || ret=1 4320dig_with_opts @10.53.0.4 type100 wild.a.too-many-iterations > dig.out.ns4.test$n || ret=1 4321digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1 4322grep "flags: qr rd ra;" dig.out.ns4.test$n >/dev/null || ret=1 4323grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 4324grep "ANSWER: 0, AUTHORITY: 8" dig.out.ns4.test$n > /dev/null || ret=1 4325n=$((n+1)) 4326test "$ret" -eq 0 || echo_i "failed" 4327status=$((status+ret)) 4328 4329echo_i "exit status: $status" 4330[ $status -eq 0 ] || exit 1 4331