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 http://mozilla.org/MPL/2.0/. 8# 9# See the COPYRIGHT file distributed with this work for additional 10# information regarding copyright ownership. 11 12# test response policy zones (RPZ) 13 14# touch dnsrps-off to not test with DNSRPS 15# touch dnsrps-only to not test with classic RPZ 16 17SYSTEMTESTTOP=.. 18. $SYSTEMTESTTOP/conf.sh 19 20ns=10.53.0 21ns1=$ns.1 # root, defining the others 22ns2=$ns.2 # authoritative server whose records are rewritten 23ns3=$ns.3 # main rewriting resolver 24ns4=$ns.4 # another authoritative server that is rewritten 25ns5=$ns.5 # another rewriting resolver 26ns6=$ns.6 # a forwarding server 27ns7=$ns.7 # another rewriting resolver 28ns8=$ns.8 # another rewriting resolver 29 30HAVE_CORE= 31 32status=0 33t=0 34 35DEBUG= 36SAVE_RESULTS= 37ARGS= 38 39USAGE="$0: [-xS]" 40while getopts "xS:" c; do 41 case $c in 42 x) set -x; DEBUG=-x; ARGS="$ARGS -x";; 43 S) SAVE_RESULTS=-S; ARGS="$ARGS -S";; 44 *) echo "$USAGE" 1>&2; exit 1;; 45 esac 46done 47shift `expr $OPTIND - 1 || true` 48if test "$#" -ne 0; then 49 echo "$USAGE" 1>&2 50 exit 1 51fi 52# really quit on control-C 53trap 'exit 1' 1 2 15 54 55TS='%H:%M:%S ' 56TS= 57comment () { 58 if test -n "$TS"; then 59 date "+${TS}$*" | cat_i 60 fi 61} 62 63DNSRPSCMD=./dnsrps 64RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s" 65 66if test -x $DNSRPSCMD; then 67 # speed up the many delays for dnsrpzd by waiting only 0.1 seconds 68 WAIT_CMD="$DNSRPSCMD -w 0.1" 69 TEN_SECS=100 70else 71 WAIT_CMD="sleep 1" 72 TEN_SECS=10 73fi 74 75digcmd () { 76 if test "$1" = TCP; then 77 shift 78 fi 79 # Default to +noauth and @$ns3 80 # Also default to -bX where X is the @value so that OS X will choose 81 # the right IP source address. 82 digcmd_args=`echo "+nocookie +noadd +time=2 +tries=1 -p ${PORT} $*" | \ 83 sed -e "/@/!s/.*/& @$ns3/" \ 84 -e '/-b/!s/@\([^ ]*\)/@\1 -b\1/' \ 85 -e '/+n?o?auth/!s/.*/+noauth &/'` 86 #echo_i "dig $digcmd_args 1>&2 87 $DIG $digcmd_args 88} 89 90# set DIGNM=file name for dig output 91GROUP_NM= 92TEST_NUM=0 93make_dignm () { 94 TEST_NUM=`expr $TEST_NUM : '\([0-9]*\).*'` # trim '+' characters 95 TEST_NUM=`expr $TEST_NUM + 1` 96 DIGNM=dig.out$GROUP_NM-$TEST_NUM 97 while test -f $DIGNM; do 98 TEST_NUM="$TEST_NUM+" 99 DIGNM=dig.out$GROUP_NM-$TEST_NUM 100 done 101} 102 103setret () { 104 ret=1 105 status=`expr $status + 1` 106 echo_i "$*" 107} 108 109# set $SN to the SOA serial number of a zone 110# $1=domain 111# $2=DNS server and client IP address 112get_sn() { 113 SOA=`$DIG -p ${PORT} +short +norecurse soa "$1" "@$2" "-b$2"` 114 SN=`expr "$SOA" : '[^ ]* [^ ]* \([^ ]*\) .*'` 115 test "$SN" != "" && return 116 echo_i "no serial number from \`dig -p ${PORT} soa $1 @$2\` in \"$SOA\"" 117 exit 1 118} 119 120get_sn_fast () { 121 RSN=`$DNSRPSCMD -n "$1"` 122 #echo "dnsrps serial for $1 is $RSN" 123 if test -z "$RSN"; then 124 echo_i "dnsrps failed to get SOA serial number for $1" 125 exit 1 126 fi 127} 128 129# check that dnsrpzd has loaded its zones 130# $1=domain 131# $2=DNS server IP address 132FZONES=`sed -n -e 's/^zone "\(.*\)".*\(10.53.0..\).*/Z=\1;M=\2/p' dnsrpzd.conf` 133dnsrps_loaded() { 134 test "$mode" = dnsrps || return 135 n=0 136 for V in $FZONES; do 137 eval "$V" 138 get_sn $Z $M 139 while true; do 140 get_sn_fast "$Z" 141 if test "$SN" -eq "0$RSN"; then 142 #echo "$Z @$M serial=$SN" 143 break 144 fi 145 n=`expr $n + 1` 146 if test "$n" -gt $TEN_SECS; then 147 echo_i "dnsrps serial for $Z is $RSN instead of $SN" 148 exit 1 149 fi 150 $WAIT_CMD 151 done 152 done 153} 154 155# check the serial number in an SOA to ensure that a policy zone has 156# been (re)loaded 157# $1=serial number 158# $2=domain 159# $3=DNS server 160ck_soa() { 161 n=0 162 while true; do 163 if test "$mode" = dnsrps; then 164 get_sn_fast "$2" 165 test "$RSN" -eq "$1" && return 166 else 167 get_sn "$2" "$3" 168 test "$SN" -eq "$1" && return 169 fi 170 n=`expr $n + 1` 171 if test "$n" -gt $TEN_SECS; then 172 echo_i "got serial number \"$SN\" instead of \"$1\" from $2 @$3" 173 return 174 fi 175 $WAIT_CMD 176 done 177} 178 179# (re)load the reponse policy zones with the rules in the file $TEST_FILE 180load_db () { 181 if test -n "$TEST_FILE"; then 182 copy_setports $TEST_FILE tmp 183 if $NSUPDATE -v tmp; then : 184 $RNDCCMD $ns3 sync 185 else 186 echo_i "failed to update policy zone with $TEST_FILE" 187 $RNDCCMD $ns3 sync 188 exit 1 189 fi 190 rm -f tmp 191 fi 192} 193 194# restart name server 195# $1 ns number 196# $2 rebuild bl rpz zones if "rebuild-bl-rpz" 197restart () { 198 # try to ensure that the server really has stopped 199 # and won't mess with ns$1/name.pid 200 if test -z "$HAVE_CORE" -a -f ns$1/named.pid; then 201 $RNDCCMD $ns$1 halt >/dev/null 2>&1 202 if test -f ns$1/named.pid; then 203 sleep 1 204 PID=`cat ns$1/named.pid 2>/dev/null` 205 if test -n "$PID"; then 206 echo_i "killing ns$1 server $PID" 207 $KILL -9 $PID 208 fi 209 fi 210 fi 211 rm -f ns$1/*.jnl 212 if [ "$2" == "rebuild-bl-rpz" ]; then 213 if test -f ns$1/base.db; then 214 for NM in ns$1/bl*.db; do 215 cp -f ns$1/base.db $NM 216 done 217 fi 218 fi 219 $PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} rpz ns$1 220 load_db 221 dnsrps_loaded 222} 223 224# $1=server and irrelevant args 225# $2=error message 226ckalive () { 227 CKALIVE_NS=`expr "$1" : '.*@ns\([1-9]\).*'` 228 if test -z "$CKALIVE_NS"; then 229 CKALIVE_NS=3 230 fi 231 eval CKALIVE_IP=\$ns$CKALIVE_NS 232 $RNDCCMD $CKALIVE_IP status >/dev/null 2>&1 && return 0 233 HAVE_CORE=yes 234 setret "$2" 235 # restart the server to avoid stalling waiting for it to stop 236 restart $CKALIVE_NS "rebuild-bl-rpz" 237 return 1 238} 239 240resetstats () { 241 NSDIR=$1 242 eval "${NSDIR}_CNT=''" 243} 244 245ckstats () { 246 HOST=$1 247 LABEL="$2" 248 NSDIR="$3" 249 EXPECTED="$4" 250 $RNDCCMD $HOST stats 251 NEW_CNT=0`sed -n -e 's/[ ]*\([0-9]*\).response policy.*/\1/p' \ 252 $NSDIR/named.stats | tail -1` 253 eval "OLD_CNT=0\$${NSDIR}_CNT" 254 GOT=`expr $NEW_CNT - $OLD_CNT` 255 if test "$GOT" -ne "$EXPECTED"; then 256 setret "wrong $LABEL $NSDIR statistics of $GOT instead of $EXPECTED" 257 fi 258 eval "${NSDIR}_CNT=$NEW_CNT" 259} 260 261ckstatsrange () { 262 HOST=$1 263 LABEL="$2" 264 NSDIR="$3" 265 MIN="$4" 266 MAX="$5" 267 $RNDCCMD $HOST stats 268 NEW_CNT=0`sed -n -e 's/[ ]*\([0-9]*\).response policy.*/\1/p' \ 269 $NSDIR/named.stats | tail -1` 270 eval "OLD_CNT=0\$${NSDIR}_CNT" 271 GOT=`expr $NEW_CNT - $OLD_CNT` 272 if test "$GOT" -lt "$MIN" -o "$GOT" -gt "$MAX"; then 273 setret "wrong $LABEL $NSDIR statistics of $GOT instead of ${MIN}..${MAX}" 274 fi 275 eval "${NSDIR}_CNT=$NEW_CNT" 276} 277 278# $1=message 279# $2=optional test file name 280start_group () { 281 ret=0 282 t=`expr $t + 1` 283 test -n "$1" && date "+${TS}checking $1 (${t})" | cat_i 284 TEST_FILE=$2 285 if test -n "$TEST_FILE"; then 286 GROUP_NM="-$TEST_FILE" 287 load_db 288 else 289 GROUP_NM= 290 fi 291 dnsrps_loaded 292 TEST_NUM=0 293} 294 295end_group () { 296 if test -n "$TEST_FILE"; then 297 # remove the previous set of test rules 298 copy_setports $TEST_FILE tmp 299 sed -e 's/[ ]add[ ]/ delete /' tmp | $NSUPDATE 300 rm -f tmp 301 TEST_FILE= 302 fi 303 ckalive $ns3 "failed; ns3 server crashed and restarted" 304 dnsrps_loaded 305 GROUP_NM= 306} 307 308clean_result () { 309 if test -z "$SAVE_RESULTS"; then 310 rm -f $* 311 fi 312} 313 314# $1=dig args 315# $2=other dig output file 316ckresult () { 317 #ckalive "$1" "server crashed by 'dig $1'" || return 1 318 if grep "flags:.* aa .*ad;" $DIGNM; then 319 setret "'dig $1' AA and AD set;" 320 elif grep "flags:.* aa .*ad;" $DIGNM; then 321 setret "'dig $1' AD set;" 322 fi 323 if $PERL $SYSTEMTESTTOP/digcomp.pl $DIGNM $2 >/dev/null; then 324 NEED_TCP=`echo "$1" | sed -n -e 's/[Tt][Cc][Pp].*/TCP/p'` 325 RESULT_TCP=`sed -n -e 's/.*Truncated, retrying in TCP.*/TCP/p' $DIGNM` 326 if test "$NEED_TCP" != "$RESULT_TCP"; then 327 setret "'dig $1' wrong; no or unexpected truncation in $DIGNM" 328 return 1 329 fi 330 clean_result ${DIGNM}* 331 return 0 332 fi 333 setret "'dig $1' wrong; diff $DIGNM $2" 334 return 1 335} 336 337# check only that the server does not crash 338# $1=target domain 339# $2=optional query type 340nocrash () { 341 digcmd $* >/dev/null 342 ckalive "$*" "server crashed by 'dig $*'" 343} 344 345 346# check rewrite to NXDOMAIN 347# $1=target domain 348# $2=optional query type 349nxdomain () { 350 make_dignm 351 digcmd $* \ 352 | sed -e 's/^[a-z].* IN CNAME /;xxx &/' \ 353 -e 's/^[a-z].* IN RRSIG /;xxx &/' \ 354 >$DIGNM 355 ckresult "$*" proto.nxdomain 356} 357 358# check rewrite to NODATA 359# $1=target domain 360# $2=optional query type 361nodata () { 362 make_dignm 363 digcmd $* \ 364 | sed -e 's/^[a-z].* IN CNAME /;xxx &/' >$DIGNM 365 ckresult "$*" proto.nodata 366} 367 368# check rewrite to an address 369# modify the output so that it is easily compared, but save the original line 370# $1=IPv4 address 371# $2=digcmd args 372# $3=optional TTL 373addr () { 374 ADDR=$1 375 make_dignm 376 digcmd $2 >$DIGNM 377 #ckalive "$2" "server crashed by 'dig $2'" || return 1 378 ADDR_ESC=`echo "$ADDR" | sed -e 's/\./\\\\./g'` 379 ADDR_TTL=`tr -d '\r' < $DIGNM | sed -n -e "s/^[-.a-z0-9]\{1,\}[ ]*\([0-9]*\) IN AA* ${ADDR_ESC}\$/\1/p"` 380 if test -z "$ADDR_TTL"; then 381 setret "'dig $2' wrong; no address $ADDR record in $DIGNM" 382 return 1 383 fi 384 if test -n "$3" && test "$ADDR_TTL" -ne "$3"; then 385 setret "'dig $2' wrong; TTL=$ADDR_TTL instead of $3 in $DIGNM" 386 return 1 387 fi 388 clean_result ${DIGNM}* 389} 390 391# Check that a response is not rewritten 392# Use $ns1 instead of the authority for most test domains, $ns2 to prevent 393# spurious differences for `dig +norecurse` 394# $1=optional "TCP" 395# remaining args for dig 396nochange () { 397 make_dignm 398 digcmd $* >$DIGNM 399 digcmd $* @$ns1 >${DIGNM}_OK 400 ckresult "$*" ${DIGNM}_OK && clean_result ${DIGNM}_OK 401} 402 403# check against a 'here document' 404here () { 405 make_dignm 406 sed -e 's/^[ ]*//' >${DIGNM}_OK 407 digcmd $* >$DIGNM 408 ckresult "$*" ${DIGNM}_OK 409} 410 411# check dropped response 412DROPPED='^;; connection timed out; no servers could be reached' 413drop () { 414 make_dignm 415 digcmd $* >$DIGNM 416 if grep "$DROPPED" $DIGNM >/dev/null; then 417 clean_result ${DIGNM}* 418 return 0 419 fi 420 setret "'dig $1' wrong; response in $DIGNM" 421 return 1 422} 423 424nsd() { 425 $NSUPDATE -p ${PORT} << EOF 426 server $1 427 ttl 300 428 update $2 $3 IN CNAME . 429 update $2 $4 IN CNAME . 430 send 431EOF 432 sleep 2 433} 434 435for mode in native dnsrps; do 436 status=0 437 case ${mode} in 438 native) 439 if [ -e dnsrps-only ] ; then 440 echo_i "'dnsrps-only' found: skipping native RPZ sub-test" 441 continue 442 else 443 echo_i "running native RPZ sub-test" 444 fi 445 ;; 446 dnsrps) 447 if [ -e dnsrps-off ] ; then 448 echo_i "'dnsrps-off' found: skipping DNSRPS sub-test" 449 continue 450 fi 451 echo_i "attempting to configure servers with DNSRPS..." 452 $PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} rpz 453 $SHELL ./setup.sh -N -D $DEBUG 454 for server in ns*; do 455 resetstats $server 456 done 457 sed -n 's/^## //p' dnsrps.conf | cat_i 458 if grep '^#fail' dnsrps.conf >/dev/null; then 459 echo_i "exit status: 1" 460 exit 1 461 fi 462 if grep '^#skip' dnsrps.conf > /dev/null; then 463 echo_i "DNSRPS sub-test skipped" 464 continue 465 else 466 echo_i "running DNSRPS sub-test" 467 $PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} rpz 468 fi 469 ;; 470 esac 471 472 # make prototype files to check against rewritten results 473 digcmd nonexistent @$ns2 >proto.nxdomain 474 digcmd txt-only.tld2 @$ns2 >proto.nodata 475 476 start_group "QNAME rewrites" test1 477 nochange . # 1 do not crash or rewrite root 478 nxdomain a0-1.tld2 # 2 479 nodata a3-1.tld2 # 3 480 nodata a3-2.tld2 # 4 nodata at DNAME itself 481 nochange sub.a3-2.tld2 # 5 miss where DNAME might work 482 nxdomain a4-2.tld2 # 6 rewrite based on CNAME target 483 nxdomain a4-2-cname.tld2 # 7 484 nodata a4-3-cname.tld2 # 8 485 addr 12.12.12.12 a4-1.sub1.tld2 # 9 A replacement 486 addr 12.12.12.12 a4-1.sub2.tld2 # 10 A replacement with wildcard 487 addr 12.12.12.12 nxc1.sub1.tld2 # 11 replace NXDOMAIN with CNAME 488 addr 12.12.12.12 nxc2.sub1.tld2 # 12 replace NXDOMAIN with CNAME chain 489 addr 127.4.4.1 a4-4.tld2 # 13 prefer 1st conflicting QNAME zone 490 nochange a6-1.tld2 # 14 491 addr 127.6.2.1 a6-2.tld2 # 15 492 addr 56.56.56.56 a3-6.tld2 # 16 wildcard CNAME 493 addr 57.57.57.57 a3-7.sub1.tld2 # 17 wildcard CNAME 494 addr 127.0.0.16 a4-5-cname3.tld2 # 18 CNAME chain 495 addr 127.0.0.17 a4-6-cname3.tld2 # 19 stop short in CNAME chain 496 nochange a5-2.tld2 +norecurse # 20 check that RD=1 is required 497 nochange a5-3.tld2 +norecurse # 21 498 nochange a5-4.tld2 +norecurse # 22 499 nochange sub.a5-4.tld2 +norecurse # 23 500 nxdomain c1.crash2.tld3 # 24 assert in rbtdb.c 501 nxdomain a0-1.tld2 +dnssec # 25 simple DO=1 without signatures 502 nxdomain a0-1.tld2s +nodnssec # 26 simple DO=0 with signatures 503 nochange a0-1.tld2s +dnssec # 27 simple DO=1 with signatures 504 nxdomain a0-1s-cname.tld2s +dnssec # 28 DNSSEC too early in CNAME chain 505 nochange a0-1-scname.tld2 +dnssec # 29 DNSSEC on target in CNAME chain 506 nochange a0-1.tld2s srv +auth +dnssec # 30 no write for DNSSEC and no record 507 nxdomain a0-1.tld2s srv +nodnssec # 31 508 drop a3-8.tld2 any # 32 drop 509 nochange tcp a3-9.tld2 # 33 tcp-only 510 here x.servfail <<'EOF' # 34 qname-wait-recurse yes 511 ;; status: SERVFAIL, x 512EOF 513 addr 35.35.35.35 "x.servfail @$ns5" # 35 qname-wait-recurse no 514 end_group 515 ckstats $ns3 test1 ns3 22 516 ckstats $ns5 test1 ns5 1 517 ckstats $ns6 test1 ns6 0 518 519 start_group "NXDOMAIN/NODATA action on QNAME trigger" test1 520 nxdomain a0-1.tld2 @$ns6 # 1 521 nodata a3-1.tld2 @$ns6 # 2 522 nodata a3-2.tld2 @$ns6 # 3 nodata at DNAME itself 523 nxdomain a4-2.tld2 @$ns6 # 4 rewrite based on CNAME target 524 nxdomain a4-2-cname.tld2 @$ns6 # 5 525 nodata a4-3-cname.tld2 @$ns6 # 6 526 addr 12.12.12.12 "a4-1.sub1.tld2 @$ns6" # 7 A replacement 527 addr 12.12.12.12 "a4-1.sub2.tld2 @$ns6" # 8 A replacement with wildcard 528 addr 127.4.4.1 "a4-4.tld2 @$ns6" # 9 prefer 1st conflicting QNAME zone 529 addr 12.12.12.12 "nxc1.sub1.tld2 @$ns6" # 10 replace NXDOMAIN w/ CNAME 530 addr 12.12.12.12 "nxc2.sub1.tld2 @$ns6" # 11 replace NXDOMAIN w/ CNAME chain 531 addr 127.6.2.1 "a6-2.tld2 @$ns6" # 12 532 addr 56.56.56.56 "a3-6.tld2 @$ns6" # 13 wildcard CNAME 533 addr 57.57.57.57 "a3-7.sub1.tld2 @$ns6" # 14 wildcard CNAME 534 addr 127.0.0.16 "a4-5-cname3.tld2 @$ns6" # 15 CNAME chain 535 addr 127.0.0.17 "a4-6-cname3.tld2 @$ns6" # 16 stop short in CNAME chain 536 nxdomain c1.crash2.tld3 @$ns6 # 17 assert in rbtdb.c 537 nxdomain a0-1.tld2 +dnssec @$ns6 # 18 simple DO=1 without sigs 538 nxdomain a0-1s-cname.tld2s +dnssec @$ns6 # 19 539 drop a3-8.tld2 any @$ns6 # 20 drop 540 end_group 541 ckstatsrange $ns3 test1 ns3 22 30 542 ckstats $ns5 test1 ns5 0 543 ckstats $ns6 test1 ns6 0 544 545 start_group "IP rewrites" test2 546 nodata a3-1.tld2 # 1 NODATA 547 nochange a3-2.tld2 # 2 no policy record so no change 548 nochange a4-1.tld2 # 3 obsolete PASSTHRU record style 549 nxdomain a4-2.tld2 # 4 550 nochange a4-2.tld2 -taaaa # 5 no A => no policy rewrite 551 nochange a4-2.tld2 -ttxt # 6 no A => no policy rewrite 552 nxdomain a4-2.tld2 -tany # 7 no A => no policy rewrite 553 nodata a4-3.tld2 # 8 554 nxdomain a3-1.tld2 -taaaa # 9 IPv6 policy 555 nochange a4-1-aaaa.tld2 -taaaa # 10 556 addr 127.0.0.1 a5-1-2.tld2 # 11 prefer smallest policy address 557 addr 127.0.0.1 a5-3.tld2 # 12 prefer first conflicting IP zone 558 nochange a5-4.tld2 +norecurse # 13 check that RD=1 is required for #14 559 addr 14.14.14.14 a5-4.tld2 # 14 prefer QNAME to IP 560 nochange a4-4.tld2 # 15 PASSTHRU 561 nxdomain c2.crash2.tld3 # 16 assert in rbtdb.c 562 addr 127.0.0.17 "a4-4.tld2 -b $ns1" # 17 client-IP address trigger 563 nxdomain a7-1.tld2 # 18 slave policy zone (RT34450) 564 # updating an response zone policy 565 cp ns2/blv2.tld2.db.in ns2/bl.tld2.db 566 rndc_reload ns2 $ns2 bl.tld2 567 ck_soa 2 bl.tld2 $ns3 568 nochange a7-1.tld2 # 19 PASSTHRU 569 # ensure that a clock tick has occured so that named will do the reload 570 sleep 1 571 cp ns2/blv3.tld2.db.in ns2/bl.tld2.db 572 rndc_reload ns2 $ns2 bl.tld2 573 ck_soa 3 bl.tld2 $ns3 574 nxdomain a7-1.tld2 # 20 slave policy zone (RT34450) 575 end_group 576 ckstats $ns3 test2 ns3 12 577 578 # check that IP addresses for previous group were deleted from the radix tree 579 start_group "radix tree deletions" 580 nochange a3-1.tld2 581 nochange a3-2.tld2 582 nochange a4-1.tld2 583 nochange a4-2.tld2 584 nochange a4-2.tld2 -taaaa 585 nochange a4-2.tld2 -ttxt 586 nochange a4-2.tld2 -tany 587 nochange a4-3.tld2 588 nochange a3-1.tld2 -tAAAA 589 nochange a4-1-aaaa.tld2 -tAAAA 590 nochange a5-1-2.tld2 591 end_group 592 ckstats $ns3 'radix tree deletions' ns3 0 593 594 # these tests assume "min-ns-dots 0" 595 start_group "NSDNAME rewrites" test3 596 nochange a3-1.tld2 # 1 597 nochange a3-1.tld2 +dnssec # 2 this once caused problems 598 nxdomain a3-1.sub1.tld2 # 3 NXDOMAIN *.sub1.tld2 by NSDNAME 599 nxdomain a3-1.subsub.sub1.tld2 # 4 600 nxdomain a3-1.subsub.sub1.tld2 -tany # 5 601 addr 12.12.12.12 a4-2.subsub.sub2.tld2 # 6 walled garden for *.sub2.tld2 602 nochange a3-2.tld2. # 7 exempt rewrite by name 603 nochange a0-1.tld2. # 8 exempt rewrite by address block 604 addr 12.12.12.12 a4-1.tld2 # 9 prefer QNAME policy to NSDNAME 605 addr 127.0.0.1 a3-1.sub3.tld2 # 10 prefer policy for largest NSDNAME 606 addr 127.0.0.2 a3-1.subsub.sub3.tld2 # 11 607 nxdomain xxx.crash1.tld2 # 12 dns_db_detachnode() crash 608 if [ "$mode" = dnsrps ]; then 609 addr 12.12.12.12 as-ns.tld5. # 13 qname-as-ns 610 fi 611 end_group 612 if [ "$mode" = dnsrps ]; then 613 ckstats $ns3 test3 ns3 8 614 else 615 ckstats $ns3 test3 ns3 7 616 fi 617 618 # these tests assume "min-ns-dots 0" 619 start_group "NSIP rewrites" test4 620 nxdomain a3-1.tld2 # 1 NXDOMAIN for all of tld2 621 nochange a3-2.tld2. # 2 exempt rewrite by name 622 nochange a0-1.tld2. # 3 exempt rewrite by address block 623 nochange a3-1.tld4 # 4 different NS IP address 624 if [ "$mode" = dnsrps ]; then 625 addr 12.12.12.12 as-ns.tld5. # 5 ip-as-ns 626 fi 627 end_group 628 629 start_group "walled garden NSIP rewrites" test4a 630 addr 41.41.41.41 a3-1.tld2 # 1 walled garden for all of tld2 631 addr 2041::41 'a3-1.tld2 AAAA' # 2 walled garden for all of tld2 632 here a3-1.tld2 TXT <<'EOF' # 3 text message for all of tld2 633 ;; status: NOERROR, x 634 a3-1.tld2. x IN TXT "NSIP walled garden" 635EOF 636 end_group 637 if [ "$mode" = dnsrps ]; then 638 ckstats $ns3 test4 ns3 5 639 else 640 ckstats $ns3 test4 ns3 4 641 fi 642 643 # policies in ./test5 overridden by response-policy{} in ns3/named.conf 644 # and in ns5/named.conf 645 start_group "policy overrides" test5 646 addr 127.0.0.1 a3-1.tld2 # 1 bl-given 647 nochange a3-2.tld2 # 2 bl-passthru 648 nochange a3-3.tld2 # 3 bl-no-op (obsolete for passthru) 649 nochange a3-4.tld2 # 4 bl-disabled 650 nodata a3-5.tld2 # 5 bl-nodata zone recursive-only no 651 nodata a3-5.tld2 +norecurse # 6 bl-nodata zone recursive-only no 652 nodata a3-5.tld2 # 7 bl-nodata not needed 653 nxdomain a3-5.tld2 +norecurse @$ns5 # 8 bl-nodata global recursive-only no 654 nxdomain a3-5.tld2s @$ns5 # 9 bl-nodata global break-dnssec 655 nxdomain a3-5.tld2s +dnssec @$ns5 # 10 bl-nodata global break-dnssec 656 nxdomain a3-6.tld2 # 11 bl-nxdomain 657 here a3-7.tld2 -tany <<'EOF' # 12 658 ;; status: NOERROR, x 659 a3-7.tld2. x IN CNAME txt-only.tld2. 660 txt-only.tld2. x IN TXT "txt-only-tld2" 661EOF 662 addr 58.58.58.58 a3-8.tld2 # 13 bl_wildcname 663 addr 59.59.59.59 a3-9.sub9.tld2 # 14 bl_wildcname 664 addr 12.12.12.12 a3-15.tld2 # 15 bl-garden via CNAME to a12.tld2 665 addr 127.0.0.16 a3-16.tld2 100 # 16 bl max-policy-ttl 100 666 addr 17.17.17.17 "a3-17.tld2 @$ns5" 90 # 17 ns5 bl max-policy-ttl 90 667 drop a3-18.tld2 any # 18 bl-drop 668 nxdomain TCP a3-19.tld2 # 19 bl-tcp-only 669 end_group 670 ckstats $ns3 test5 ns3 12 671 ckstats $ns5 test5 ns5 4 672 673 # check that miscellaneous bugs are still absent 674 start_group "crashes" test6 675 for Q in RRSIG SIG ANY 'ANY +dnssec'; do 676 nocrash a3-1.tld2 -t$Q 677 nocrash a3-2.tld2 -t$Q 678 nocrash a3-5.tld2 -t$Q 679 nocrash www.redirect -t$Q 680 nocrash www.credirect -t$Q 681 done 682 683 # This is not a bug, because any data leaked by writing 24.4.3.2.10.rpz-ip 684 # (or whatever) is available by publishing "foo A 10.2.3.4" and then 685 # resolving foo. 686 # nxdomain 32.3.2.1.127.rpz-ip 687 end_group 688 ckstats $ns3 bugs ns3 8 689 690 # superficial test for major performance bugs 691 QPERF=`sh qperf.sh` 692 if test -n "$QPERF"; then 693 perf () { 694 date "+${TS}checking performance $1" | cat_i 695 # Dry run to prime everything 696 comment "before dry run $1" 697 $RNDCCMD $ns5 notrace 698 $QPERF -c -1 -l30 -d ns5/requests -s $ns5 -p ${PORT} >/dev/null 699 comment "before real test $1" 700 PFILE="ns5/$2.perf" 701 $QPERF -c -1 -l30 -d ns5/requests -s $ns5 -p ${PORT} >$PFILE 702 comment "after test $1" 703 X=`sed -n -e 's/.*Returned *\([^ ]*:\) *\([0-9]*\) .*/\1\2/p' $PFILE \ 704 | tr '\n' ' '` 705 if test "$X" != "$3"; then 706 setret "wrong results '$X' in $PFILE" 707 fi 708 ckalive $ns5 "failed; server #5 crashed" 709 } 710 trim () { 711 sed -n -e 's/.*Queries per second: *\([0-9]*\).*/\1/p' ns5/$1.perf 712 } 713 714 # get qps with rpz 715 perf 'with RPZ' rpz 'NOERROR:2900 NXDOMAIN:100 ' 716 RPZ=`trim rpz` 717 # turn off rpz and measure qps again 718 echo "# RPZ off" >ns5/rpz-switch 719 RNDCCMD_OUT=`$RNDCCMD $ns5 reload` 720 perf 'without RPZ' norpz 'NOERROR:3000 ' 721 NORPZ=`trim norpz` 722 723 PERCENT=`expr \( "$RPZ" \* 100 + \( $NORPZ / 2 \) \) / $NORPZ` 724 echo_i "$RPZ qps with RPZ is $PERCENT% of $NORPZ qps without RPZ" 725 726 MIN_PERCENT=30 727 if test "$PERCENT" -lt $MIN_PERCENT; then 728 echo_i "$RPZ qps with rpz or $PERCENT% is below $MIN_PERCENT% of $NORPZ qps" 729 fi 730 731 if test "$PERCENT" -ge 100; then 732 echo_i "$RPZ qps with RPZ or $PERCENT% of $NORPZ qps without RPZ is too high" 733 fi 734 735 ckstats $ns5 performance ns5 200 736 737 else 738 echo_i "performance not checked; queryperf not available" 739 fi 740 741 if [ "$mode" = dnsrps ]; then 742 echo_i "checking that dnsrpzd is automatically restarted" 743 OLD_PID=`cat dnsrpzd.pid` 744 $KILL "$OLD_PID" 745 n=0 746 while true; do 747 NEW_PID=`cat dnsrpzd.pid 2>/dev/null` 748 if test -n "$NEW_PID" -a "0$OLD_PID" -ne "0$NEW_PID"; then 749 #echo "OLD_PID=$OLD_PID NEW_PID=$NEW_PID" 750 break; 751 fi 752 $DIG -p ${PORT} +short +norecurse a0-1.tld2 @$ns3 >/dev/null 753 n=`expr $n + 1` 754 if test "$n" -gt $TEN_SECS; then 755 setret "dnsrpzd did not restart" 756 break 757 fi 758 $WAIT_CMD 759 done 760 fi 761 762 # reconfigure the ns5 master server without the fast-exire zone, so 763 # it can't be refreshed on ns3, and will expire in 5 seconds. 764 cat /dev/null > ns5/expire.conf 765 rndc_reconfig ns5 10.53.0.5 766 767 # restart the main test RPZ server to see if that creates a core file 768 if test -z "$HAVE_CORE"; then 769 $PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} rpz ns3 770 restart 3 "rebuild-bl-rpz" 771 HAVE_CORE=`find ns* -name '*core*' -print` 772 test -z "$HAVE_CORE" || setret "found $HAVE_CORE; memory leak?" 773 fi 774 775 # look for complaints from lib/dns/rpz.c and bin/name/query.c 776 for runfile in ns*/named.run; do 777 EMSGS=`nextpart $runfile | egrep -l 'invalid rpz|rpz.*failed'` 778 if test -n "$EMSGS"; then 779 setret "error messages in $runfile starting with:" 780 egrep 'invalid rpz|rpz.*failed' ns*/named.run | \ 781 sed -e '10,$d' -e 's/^//' | cat_i 782 fi 783 done 784 785 if [ native = "$mode" ]; then 786 # restart the main test RPZ server with a bad zone. 787 t=`expr $t + 1` 788 echo_i "checking that ns3 with broken rpz does not crash (${t})" 789 $PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} rpz ns3 790 cp ns3/broken.db.in ns3/bl.db 791 restart 3 # do not rebuild rpz zones 792 nocrash a3-1.tld2 -tA 793 $PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} rpz ns3 794 restart 3 "rebuild-bl-rpz" 795 796 # reload a RPZ zone that is now deliberately broken. 797 t=`expr $t + 1` 798 echo_i "checking rpz failed update will keep previous rpz rules (${t})" 799 $DIG -p ${PORT} @$ns3 walled.tld2 > dig.out.$t.before 800 grep "walled\.tld2\..*IN.*A.*10\.0\.0\.1" dig.out.$t.before > /dev/null || setret "failed" 801 cp ns3/broken.db.in ns3/manual-update-rpz.db 802 rndc_reload ns3 $ns3 manual-update-rpz 803 sleep 1 804 # ensure previous RPZ rules still apply. 805 $DIG -p ${PORT} @$ns3 walled.tld2 > dig.out.$t.after 806 grep "walled\.tld2\..*IN.*A.*10\.0\.0\.1" dig.out.$t.after > /dev/null || setret "failed" 807 fi 808 809 t=`expr $t + 1` 810 echo_i "checking that ttl values are not zeroed when qtype is '*' (${t})" 811 $DIG +noall +answer -p ${PORT} @$ns3 any a3-2.tld2 > dig.out.$t 812 ttl=`awk '/a3-2 tld2 text/ {print $2}' dig.out.$t` 813 if test ${ttl:=0} -eq 0; then setret "failed"; fi 814 815 t=`expr $t + 1` 816 echo_i "checking rpz updates/transfers with parent nodes added after children (${t})" 817 # regression test for RT #36272: the success condition 818 # is the slave server not crashing. 819 for i in 1 2 3 4 5; do 820 nsd $ns5 add example.com.policy1. '*.example.com.policy1.' 821 nsd $ns5 delete example.com.policy1. '*.example.com.policy1.' 822 done 823 for i in 1 2 3 4 5; do 824 nsd $ns5 add '*.example.com.policy1.' example.com.policy1. 825 nsd $ns5 delete '*.example.com.policy1.' example.com.policy1. 826 done 827 828 t=`expr $t + 1` 829 echo_i "checking that going from an empty policy zone works (${t})" 830 nsd $ns5 add '*.x.servfail.policy2.' x.servfail.policy2. 831 sleep 1 832 rndc_reload ns7 $ns7 policy2 833 $DIG z.x.servfail -p ${PORT} @$ns7 > dig.out.${t} 834 grep NXDOMAIN dig.out.${t} > /dev/null || setret "failed" 835 836 t=`expr $t + 1` 837 echo_i "checking that "add-soa no" at rpz zone level works (${t})" 838 $DIG z.x.servfail -p ${PORT} @$ns7 > dig.out.${t} 839 grep SOA dig.out.${t} > /dev/null && setret "failed" 840 841 if [ native = "$mode" ]; then 842 t=`expr $t + 1` 843 echo_i "checking that "add-soa yes" at response-policy level works (${t})" 844 $DIG walled.tld2 -p ${PORT} +noall +add @$ns3 > dig.out.${t} 845 grep "^manual-update-rpz\..*SOA" dig.out.${t} > /dev/null || setret "failed" 846 fi 847 848 if [ native = "$mode" ]; then 849 t=`expr $t + 1` 850 echo_i "checking that "add-soa unset" works (${t})" 851 $DIG walled.tld2 -p ${PORT} +noall +add @$ns8 > dig.out.${t} 852 grep "^manual-update-rpz\..*SOA" dig.out.${t} > /dev/null || setret "failed" 853 fi 854 855 # dnsrps does not allow NS RRs in policy zones, so this check 856 # with dnsrps results in no rewriting. 857 if [ native = "$mode" ]; then 858 t=`expr $t + 1` 859 echo_i "checking rpz with delegation fails correctly (${t})" 860 $DIG -p ${PORT} @$ns3 ns example.com > dig.out.$t 861 grep "status: SERVFAIL" dig.out.$t > /dev/null || setret "failed" 862 863 t=`expr $t + 1` 864 echo_i "checking policies from expired zone are no longer in effect ($t)" 865 $DIG -p ${PORT} @$ns3 a expired > dig.out.$t 866 grep "expired.*10.0.0.10" dig.out.$t > /dev/null && setret "failed" 867 grep "fast-expire/IN: response-policy zone expired" ns3/named.run > /dev/null || setret "failed" 868 fi 869 870 # RPZ 'CNAME *.' (NODATA) trumps DNS64. Test against various DNS64 senarios. 871 for label in a-only no-a-no-aaaa a-plus-aaaa 872 do 873 for type in AAAA A 874 do 875 t=`expr $t + 1` 876 case $label in 877 a-only) 878 echo_i "checking rpz 'CNAME *.' (NODATA) with dns64, $type lookup with A-only (${t})" 879 ;; 880 no-a-no-aaaa) 881 echo_i "checking rpz 'CNAME *.' (NODATA) with dns64, $type lookup with no A or AAAA (${t})" 882 ;; 883 a-plus-aaaa) 884 echo_i "checking rpz 'CNAME *.' (NODATA) with dns64, $type lookup with A and AAAA (${t})" 885 ;; 886 esac 887 ret=0 888 $DIG ${label}.example -p ${PORT} $type @10.53.0.9 > dig.out.${t} 889 grep "status: NOERROR" dig.out.$t > /dev/null || ret=1 890 grep "ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 2$" dig.out.$t > /dev/null || ret=1 891 grep "^rpz" dig.out.$t > /dev/null || ret=1 892 [ $ret -eq 0 ] || echo_i "failed" 893 status=`expr $status + $ret` 894 done 895 done 896 897 [ $status -ne 0 ] && pf=fail || pf=pass 898 case $mode in 899 native) 900 native=$status 901 echo_i "status (native RPZ sub-test): $status ($pf)";; 902 903 dnsrps) 904 dnsrps=$status 905 echo_i "status (DNSRPS sub-test): $status ($pf)";; 906 *) echo_i "invalid test mode";; 907 esac 908done 909status=`expr ${native:-0} + ${dnsrps:-0}` 910 911[ $status -eq 0 ] || exit 1 912