From bb5b41ad95579915492297f9502d3af30f539905 Mon Sep 17 00:00:00 2001 From: Tom Krizek Date: Tue, 24 Oct 2023 10:36:48 +0200 Subject: [PATCH 1/3] Split up the dnsrps and native variants of rpz system tests Previously, dnsrps test was executed as an optional part of the rpz and rpzrecurse system tests. This was conceptually problematic, as the test took the responsibility of running parts of the test framework - cleaning files and setting up servers again. Instead, allow these tests to execute either the native variant, or the dnsrps one. To ensure the same test coverage, trigger both of these variants as separate test cases from pytest. (cherry picked from commit cb55fb2cae866758750f4d5312e04bbc66af54fc) --- bin/tests/system/isctest/mark.py | 18 + bin/tests/system/rpz/clean.sh | 50 +- bin/tests/system/rpz/setup.sh | 33 +- bin/tests/system/rpz/tests.sh | 1030 ++++++++--------- bin/tests/system/rpz/tests_sh_rpz_dnsrps.py | 20 + bin/tests/system/rpzrecurse/setup.sh | 30 +- bin/tests/system/rpzrecurse/tests.sh | 846 +++++++------- .../rpzrecurse/tests_sh_rpzrecurse_dnsrps.py | 20 + 8 files changed, 955 insertions(+), 1092 deletions(-) create mode 100644 bin/tests/system/rpz/tests_sh_rpz_dnsrps.py create mode 100644 bin/tests/system/rpzrecurse/tests_sh_rpzrecurse_dnsrps.py diff --git a/bin/tests/system/isctest/mark.py b/bin/tests/system/isctest/mark.py index 769abbbb5d..0caac51af5 100644 --- a/bin/tests/system/isctest/mark.py +++ b/bin/tests/system/isctest/mark.py @@ -12,6 +12,7 @@ # information regarding copyright ownership. import os +from pathlib import Path import subprocess import pytest @@ -33,6 +34,19 @@ def feature_test(feature): return True +DNSRPS_BIN = Path(os.environ["TOP_BUILDDIR"]) / "bin/tests/system/rpz/dnsrps" + + +def is_dnsrps_available(): + if not feature_test("--enable-dnsrps"): + return False + try: + subprocess.run([DNSRPS_BIN, "-a"], check=True) + except subprocess.CalledProcessError: + return False + return True + + have_libxml2 = pytest.mark.skipif( not feature_test("--have-libxml2"), reason="libxml2 support disabled in the build" ) @@ -41,6 +55,10 @@ have_json_c = pytest.mark.skipif( not feature_test("--have-json-c"), reason="json-c support disabled in the build" ) +dnsrps_enabled = pytest.mark.skipif( + not is_dnsrps_available(), reason="dnsrps disabled in the build" +) + try: import flaky as flaky_pkg # type: ignore diff --git a/bin/tests/system/rpz/clean.sh b/bin/tests/system/rpz/clean.sh index 07cd667dda..d6c99c9ac6 100644 --- a/bin/tests/system/rpz/clean.sh +++ b/bin/tests/system/rpz/clean.sh @@ -11,29 +11,6 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -# Clean up after rpz tests. - -USAGE="$0: [-Px]" -DEBUG= -while getopts "Px" c; do - case $c in - x) set -x ;; - P) PARTIAL=set ;; - *) - echo "$USAGE" 1>&2 - exit 1 - ;; - esac -done -shift $((OPTIND - 1)) -if test "$#" -ne 0; then - echo "$USAGE" 1>&2 - exit 1 -fi - -# this might be called from setup.sh to partially clean up the files -# from the first test pass so the second pass can be set up correctly. -# remove those files first, then decide whether to remove the others. rm -f ns*/*.key ns*/*.private rm -f ns2/tld2s.db */bl.tld2.db */bl.tld2s.db rm -f ns3/bl*.db ns3/fast-expire.db ns*/empty.db @@ -43,18 +20,15 @@ rm -f ns5/example.db ns5/bl.db ns5/fast-expire.db ns5/expire.conf rm -f ns8/manual-update-rpz.db rm -f */policy2.db rm -f */*.jnl - -if [ ${PARTIAL:-unset} = unset ]; then - rm -f proto.* dsset-* trusted.conf dig.out* nsupdate.tmp ns*/*tmp - rm -f ns5/requests ns5/*.perf - rm -f */named.memstats */*.run */*.run.prev */named.stats */session.key - rm -f */*.log */*core */*.pid - rm -f ns*/named.lock - rm -f ns*/named.conf - rm -f ns*/*switch - rm -f dnsrps*.conf - rm -f dnsrpzd.conf - rm -f dnsrpzd-license-cur.conf dnsrpzd.rpzf dnsrpzd.sock dnsrpzd.pid - rm -f ns*/managed-keys.bind* - rm -f tmp -fi +rm -f proto.* dsset-* trusted.conf dig.out* nsupdate.tmp ns*/*tmp +rm -f ns5/requests ns5/*.perf +rm -f */named.memstats */*.run */*.run.prev */named.stats */session.key +rm -f */*.log */*core */*.pid +rm -f ns*/named.lock +rm -f ns*/named.conf +rm -f ns*/*switch +rm -f dnsrps*.conf +rm -f dnsrpzd.conf +rm -f dnsrpzd-license-cur.conf dnsrpzd.rpzf dnsrpzd.sock dnsrpzd.pid +rm -f ns*/managed-keys.bind* +rm -f tmp diff --git a/bin/tests/system/rpz/setup.sh b/bin/tests/system/rpz/setup.sh index b263fda1cf..16642be96e 100644 --- a/bin/tests/system/rpz/setup.sh +++ b/bin/tests/system/rpz/setup.sh @@ -19,31 +19,7 @@ set -e QPERF=$($SHELL qperf.sh) -USAGE="$0: [-DNx]" -DEBUG= -while getopts "DNx" c; do - case $c in - x) - set -x - DEBUG=-x - ;; - D) TEST_DNSRPS="-D" ;; - N) PARTIAL=-P ;; - *) - echo "$USAGE" 1>&2 - exit 1 - ;; - esac -done -shift $((OPTIND - 1)) -if test "$#" -ne 0; then - echo "$USAGE" 1>&2 - exit 1 -fi - -if [ ${NOCLEAN:-unset} = unset ]; then - $SHELL clean.sh $PARTIAL $DEBUG -fi +$SHELL clean.sh for dir in ns*; do touch $dir/named.run @@ -63,11 +39,8 @@ copy_setports ns10/named.conf.in ns10/named.conf copy_setports dnsrpzd.conf.in dnsrpzd.conf -# decide whether to test DNSRPS -# Note that dnsrps.conf and dnsrps-secondary.conf are included in named.conf -# and differ from dnsrpz.conf which is used by dnsrpzd. -$SHELL ../ckdnsrps.sh -A $TEST_DNSRPS $DEBUG -test -z "$(grep 'dnsrps-enable yes' dnsrps.conf)" && TEST_DNSRPS= +touch dnsrps.conf +touch dnsrps.cache # set up test policy zones. # bl is the main test zone diff --git a/bin/tests/system/rpz/tests.sh b/bin/tests/system/rpz/tests.sh index 04ac30661a..6d22bb353e 100644 --- a/bin/tests/system/rpz/tests.sh +++ b/bin/tests/system/rpz/tests.sh @@ -37,18 +37,17 @@ HAVE_CORE= status=0 t=0 -DEBUG= SAVE_RESULTS= ARGS= +if grep 'dnsrps-enable yes;' dnsrps.conf >/dev/null; then + MODE=dnsrps +else + MODE=native +fi -USAGE="$0: [-xS]" -while getopts "xS:" c; do +USAGE="$0: [-S]" +while getopts "S:" c; do case $c in - x) - set -x - DEBUG=-x - ARGS="$ARGS -x" - ;; S) SAVE_RESULTS=-S ARGS="$ARGS -S" @@ -144,7 +143,7 @@ get_sn_fast() { # $2=DNS server IP address FZONES=$(sed -n -e 's/^zone "\(.*\)".*\(10.53.0..\).*/Z=\1;M=\2/p' dnsrpzd.conf) dnsrps_loaded() { - test "$mode" = dnsrps || return 0 + test "$MODE" = dnsrps || return 0 n=0 for V in $FZONES; do eval "$V" @@ -173,7 +172,7 @@ dnsrps_loaded() { ck_soa() { n=0 while true; do - if test "$mode" = dnsrps; then + if test "$MODE" = dnsrps; then get_sn_fast "$2" test "$RSN" -eq "$1" && return else @@ -252,11 +251,6 @@ ckalive() { return 0 } -resetstats() { - NSDIR=$1 - eval "${NSDIR}_CNT=''" -} - ckstats() { HOST=$1 LABEL="$2" @@ -481,550 +475,494 @@ make_proto_nodata() { # ensure that the fast-expire zone is populated before we begin testing $RNDCCMD $ns3 retransfer fast-expire -native=0 -dnsrps=0 -for mode in native dnsrps; do - status=0 - case ${mode} in - native) - if [ -e dnsrps-only ]; then - echo_i "'dnsrps-only' found: skipping native RPZ sub-test" - continue - else - echo_i "running native RPZ sub-test" - fi - ;; - dnsrps) - if [ -e dnsrps-off ]; then - echo_i "'dnsrps-off' found: skipping DNSRPS sub-test" - continue - fi - echo_i "attempting to configure servers with DNSRPS..." - stop_server --use-rndc --port ${CONTROLPORT} - $SHELL ./setup.sh -N -D $DEBUG - for server in ns*; do - resetstats $server - done - sed -n 's/^## //p' dnsrps.conf | cat_i - if grep '^#fail' dnsrps.conf >/dev/null; then - echo_i "exit status: 1" - exit 1 - fi - if grep '^#skip' dnsrps.conf >/dev/null; then - echo_i "DNSRPS sub-test skipped" - continue - else - echo_i "running DNSRPS sub-test" - start_server --noclean --restart --port ${PORT} - sleep 3 - fi - ;; - esac +# make prototype files to check against rewritten results +retry_quiet 10 make_proto_nxdomain +retry_quiet 10 make_proto_nodata - # make prototype files to check against rewritten results - retry_quiet 10 make_proto_nxdomain - retry_quiet 10 make_proto_nodata - - start_group "QNAME rewrites" test1 - nochange . # 1 do not crash or rewrite root - nxdomain a0-1.tld2 # 2 - nodata a3-1.tld2 # 3 - nodata a3-2.tld2 # 4 nodata at DNAME itself - nochange sub.a3-2.tld2 # 5 miss where DNAME might work - nxdomain a4-2.tld2 # 6 rewrite based on CNAME target - nxdomain a4-2-cname.tld2 # 7 - nodata a4-3-cname.tld2 # 8 - addr 12.12.12.12 a4-1.sub1.tld2 # 9 A replacement - addr 12.12.12.12 a4-1.sub2.tld2 # 10 A replacement with wildcard - addr 12.12.12.12 nxc1.sub1.tld2 # 11 replace NXDOMAIN with CNAME - addr 12.12.12.12 nxc2.sub1.tld2 # 12 replace NXDOMAIN with CNAME chain - addr 127.4.4.1 a4-4.tld2 # 13 prefer 1st conflicting QNAME zone - nochange a6-1.tld2 # 14 - addr 127.6.2.1 a6-2.tld2 # 15 - addr 56.56.56.56 a3-6.tld2 # 16 wildcard CNAME - addr 57.57.57.57 a3-7.sub1.tld2 # 17 wildcard CNAME - addr 127.0.0.16 a4-5-cname3.tld2 # 18 CNAME chain - addr 127.0.0.17 a4-6-cname3.tld2 # 19 stop short in CNAME chain - nochange a5-2.tld2 +norecurse # 20 check that RD=1 is required - nochange a5-3.tld2 +norecurse # 21 - nochange a5-4.tld2 +norecurse # 22 - nochange sub.a5-4.tld2 +norecurse # 23 - nxdomain c1.crash2.tld3 # 24 assert in rbtdb.c - nxdomain a0-1.tld2 +dnssec # 25 simple DO=1 without signatures - nxdomain a0-1.tld2s +nodnssec # 26 simple DO=0 with signatures - nochange a0-1.tld2s +dnssec # 27 simple DO=1 with signatures - nxdomain a0-1s-cname.tld2s +dnssec # 28 DNSSEC too early in CNAME chain - nochange a0-1-scname.tld2 +dnssec # 29 DNSSEC on target in CNAME chain - nochange a0-1.tld2s srv +auth +dnssec # 30 no write for DNSSEC and no record - nxdomain a0-1.tld2s srv +nodnssec # 31 - drop a3-8.tld2 any # 32 drop - nochange TCP a3-9.tld2 # 33 tcp-only - here x.servfail <<'EOF' # 34 qname-wait-recurse yes - ;; status: SERVFAIL, x +start_group "QNAME rewrites" test1 +nochange . # 1 do not crash or rewrite root +nxdomain a0-1.tld2 # 2 +nodata a3-1.tld2 # 3 +nodata a3-2.tld2 # 4 nodata at DNAME itself +nochange sub.a3-2.tld2 # 5 miss where DNAME might work +nxdomain a4-2.tld2 # 6 rewrite based on CNAME target +nxdomain a4-2-cname.tld2 # 7 +nodata a4-3-cname.tld2 # 8 +addr 12.12.12.12 a4-1.sub1.tld2 # 9 A replacement +addr 12.12.12.12 a4-1.sub2.tld2 # 10 A replacement with wildcard +addr 12.12.12.12 nxc1.sub1.tld2 # 11 replace NXDOMAIN with CNAME +addr 12.12.12.12 nxc2.sub1.tld2 # 12 replace NXDOMAIN with CNAME chain +addr 127.4.4.1 a4-4.tld2 # 13 prefer 1st conflicting QNAME zone +nochange a6-1.tld2 # 14 +addr 127.6.2.1 a6-2.tld2 # 15 +addr 56.56.56.56 a3-6.tld2 # 16 wildcard CNAME +addr 57.57.57.57 a3-7.sub1.tld2 # 17 wildcard CNAME +addr 127.0.0.16 a4-5-cname3.tld2 # 18 CNAME chain +addr 127.0.0.17 a4-6-cname3.tld2 # 19 stop short in CNAME chain +nochange a5-2.tld2 +norecurse # 20 check that RD=1 is required +nochange a5-3.tld2 +norecurse # 21 +nochange a5-4.tld2 +norecurse # 22 +nochange sub.a5-4.tld2 +norecurse # 23 +nxdomain c1.crash2.tld3 # 24 assert in rbtdb.c +nxdomain a0-1.tld2 +dnssec # 25 simple DO=1 without signatures +nxdomain a0-1.tld2s +nodnssec # 26 simple DO=0 with signatures +nochange a0-1.tld2s +dnssec # 27 simple DO=1 with signatures +nxdomain a0-1s-cname.tld2s +dnssec # 28 DNSSEC too early in CNAME chain +nochange a0-1-scname.tld2 +dnssec # 29 DNSSEC on target in CNAME chain +nochange a0-1.tld2s srv +auth +dnssec # 30 no write for DNSSEC and no record +nxdomain a0-1.tld2s srv +nodnssec # 31 +drop a3-8.tld2 any # 32 drop +nochange TCP a3-9.tld2 # 33 tcp-only +here x.servfail <<'EOF' # 34 qname-wait-recurse yes + ;; status: SERVFAIL, x EOF - addr 35.35.35.35 "x.servfail @$ns5" # 35 qname-wait-recurse no - end_group - ckstats $ns3 test1 ns3 22 - ckstats $ns5 test1 ns5 1 - ckstats $ns6 test1 ns6 0 +addr 35.35.35.35 "x.servfail @$ns5" # 35 qname-wait-recurse no +end_group +ckstats $ns3 test1 ns3 22 +ckstats $ns5 test1 ns5 1 +ckstats $ns6 test1 ns6 0 - start_group "NXDOMAIN/NODATA action on QNAME trigger" test1 - nxdomain a0-1.tld2 @$ns6 # 1 - nodata a3-1.tld2 @$ns6 # 2 - nodata a3-2.tld2 @$ns6 # 3 nodata at DNAME itself - nxdomain a4-2.tld2 @$ns6 # 4 rewrite based on CNAME target - nxdomain a4-2-cname.tld2 @$ns6 # 5 - nodata a4-3-cname.tld2 @$ns6 # 6 - addr 12.12.12.12 "a4-1.sub1.tld2 @$ns6" # 7 A replacement - addr 12.12.12.12 "a4-1.sub2.tld2 @$ns6" # 8 A replacement with wildcard - addr 127.4.4.1 "a4-4.tld2 @$ns6" # 9 prefer 1st conflicting QNAME zone - addr 12.12.12.12 "nxc1.sub1.tld2 @$ns6" # 10 replace NXDOMAIN w/ CNAME - addr 12.12.12.12 "nxc2.sub1.tld2 @$ns6" # 11 replace NXDOMAIN w/ CNAME chain - addr 127.6.2.1 "a6-2.tld2 @$ns6" # 12 - addr 56.56.56.56 "a3-6.tld2 @$ns6" # 13 wildcard CNAME - addr 57.57.57.57 "a3-7.sub1.tld2 @$ns6" # 14 wildcard CNAME - addr 127.0.0.16 "a4-5-cname3.tld2 @$ns6" # 15 CNAME chain - addr 127.0.0.17 "a4-6-cname3.tld2 @$ns6" # 16 stop short in CNAME chain - nxdomain c1.crash2.tld3 @$ns6 # 17 assert in rbtdb.c - nxdomain a0-1.tld2 +dnssec @$ns6 # 18 simple DO=1 without sigs - nxdomain a0-1s-cname.tld2s +dnssec @$ns6 # 19 - drop a3-8.tld2 any @$ns6 # 20 drop - end_group - ckstatsrange $ns3 test1 ns3 22 30 - ckstats $ns5 test1 ns5 0 - ckstats $ns6 test1 ns6 0 +start_group "NXDOMAIN/NODATA action on QNAME trigger" test1 +nxdomain a0-1.tld2 @$ns6 # 1 +nodata a3-1.tld2 @$ns6 # 2 +nodata a3-2.tld2 @$ns6 # 3 nodata at DNAME itself +nxdomain a4-2.tld2 @$ns6 # 4 rewrite based on CNAME target +nxdomain a4-2-cname.tld2 @$ns6 # 5 +nodata a4-3-cname.tld2 @$ns6 # 6 +addr 12.12.12.12 "a4-1.sub1.tld2 @$ns6" # 7 A replacement +addr 12.12.12.12 "a4-1.sub2.tld2 @$ns6" # 8 A replacement with wildcard +addr 127.4.4.1 "a4-4.tld2 @$ns6" # 9 prefer 1st conflicting QNAME zone +addr 12.12.12.12 "nxc1.sub1.tld2 @$ns6" # 10 replace NXDOMAIN w/ CNAME +addr 12.12.12.12 "nxc2.sub1.tld2 @$ns6" # 11 replace NXDOMAIN w/ CNAME chain +addr 127.6.2.1 "a6-2.tld2 @$ns6" # 12 +addr 56.56.56.56 "a3-6.tld2 @$ns6" # 13 wildcard CNAME +addr 57.57.57.57 "a3-7.sub1.tld2 @$ns6" # 14 wildcard CNAME +addr 127.0.0.16 "a4-5-cname3.tld2 @$ns6" # 15 CNAME chain +addr 127.0.0.17 "a4-6-cname3.tld2 @$ns6" # 16 stop short in CNAME chain +nxdomain c1.crash2.tld3 @$ns6 # 17 assert in rbtdb.c +nxdomain a0-1.tld2 +dnssec @$ns6 # 18 simple DO=1 without sigs +nxdomain a0-1s-cname.tld2s +dnssec @$ns6 # 19 +drop a3-8.tld2 any @$ns6 # 20 drop +end_group +ckstatsrange $ns3 test1 ns3 22 30 +ckstats $ns5 test1 ns5 0 +ckstats $ns6 test1 ns6 0 - start_group "IP rewrites" test2 - nodata a3-1.tld2 # 1 NODATA - nochange a3-2.tld2 # 2 no policy record so no change - nochange a4-1.tld2 # 3 obsolete PASSTHRU record style - nxdomain a4-2.tld2 # 4 - nochange a4-2.tld2 -taaaa # 5 no A => no policy rewrite - nochange a4-2.tld2 -ttxt # 6 no A => no policy rewrite - nxdomain a4-2.tld2 -tany # 7 no A => no policy rewrite - nodata a4-3.tld2 # 8 - nxdomain a3-1.tld2 -taaaa # 9 IPv6 policy - nochange a4-1-aaaa.tld2 -taaaa # 10 - addr 127.0.0.1 a5-1-2.tld2 # 11 prefer smallest policy address - addr 127.0.0.1 a5-3.tld2 # 12 prefer first conflicting IP zone - nochange a5-4.tld2 +norecurse # 13 check that RD=1 is required for #14 - addr 14.14.14.14 a5-4.tld2 # 14 prefer QNAME to IP - nochange a4-4.tld2 # 15 PASSTHRU - nxdomain c2.crash2.tld3 # 16 assert in rbtdb.c - addr 127.0.0.17 "a4-4.tld2 -b $ns1" # 17 client-IP address trigger - nxdomain a7-1.tld2 # 18 secondary policy zone (RT34450) - # updating an response zone policy - cp ns2/blv2.tld2.db.in ns2/bl.tld2.db - rndc_reload ns2 $ns2 bl.tld2 - ck_soa 2 bl.tld2 $ns3 - nochange a7-1.tld2 # 19 PASSTHRU - # ensure that a clock tick has occurred so that named will do the reload - sleep 1 - cp ns2/blv3.tld2.db.in ns2/bl.tld2.db - rndc_reload ns2 $ns2 bl.tld2 - ck_soa 3 bl.tld2 $ns3 - nxdomain a7-1.tld2 # 20 secondary policy zone (RT34450) - end_group - ckstats $ns3 test2 ns3 12 +start_group "IP rewrites" test2 +nodata a3-1.tld2 # 1 NODATA +nochange a3-2.tld2 # 2 no policy record so no change +nochange a4-1.tld2 # 3 obsolete PASSTHRU record style +nxdomain a4-2.tld2 # 4 +nochange a4-2.tld2 -taaaa # 5 no A => no policy rewrite +nochange a4-2.tld2 -ttxt # 6 no A => no policy rewrite +nxdomain a4-2.tld2 -tany # 7 no A => no policy rewrite +nodata a4-3.tld2 # 8 +nxdomain a3-1.tld2 -taaaa # 9 IPv6 policy +nochange a4-1-aaaa.tld2 -taaaa # 10 +addr 127.0.0.1 a5-1-2.tld2 # 11 prefer smallest policy address +addr 127.0.0.1 a5-3.tld2 # 12 prefer first conflicting IP zone +nochange a5-4.tld2 +norecurse # 13 check that RD=1 is required for #14 +addr 14.14.14.14 a5-4.tld2 # 14 prefer QNAME to IP +nochange a4-4.tld2 # 15 PASSTHRU +nxdomain c2.crash2.tld3 # 16 assert in rbtdb.c +addr 127.0.0.17 "a4-4.tld2 -b $ns1" # 17 client-IP address trigger +nxdomain a7-1.tld2 # 18 secondary policy zone (RT34450) +# updating an response zone policy +cp ns2/blv2.tld2.db.in ns2/bl.tld2.db +rndc_reload ns2 $ns2 bl.tld2 +ck_soa 2 bl.tld2 $ns3 +nochange a7-1.tld2 # 19 PASSTHRU +# ensure that a clock tick has occurred so that named will do the reload +sleep 1 +cp ns2/blv3.tld2.db.in ns2/bl.tld2.db +rndc_reload ns2 $ns2 bl.tld2 +ck_soa 3 bl.tld2 $ns3 +nxdomain a7-1.tld2 # 20 secondary policy zone (RT34450) +end_group +ckstats $ns3 test2 ns3 12 - # check that IP addresses for previous group were deleted from the radix tree - start_group "radix tree deletions" - nochange a3-1.tld2 - nochange a3-2.tld2 - nochange a4-1.tld2 - nochange a4-2.tld2 - nochange a4-2.tld2 -taaaa - nochange a4-2.tld2 -ttxt - nochange a4-2.tld2 -tany - nochange a4-3.tld2 - nochange a3-1.tld2 -tAAAA - nochange a4-1-aaaa.tld2 -tAAAA - nochange a5-1-2.tld2 - end_group - ckstats $ns3 'radix tree deletions' ns3 0 +# check that IP addresses for previous group were deleted from the radix tree +start_group "radix tree deletions" +nochange a3-1.tld2 +nochange a3-2.tld2 +nochange a4-1.tld2 +nochange a4-2.tld2 +nochange a4-2.tld2 -taaaa +nochange a4-2.tld2 -ttxt +nochange a4-2.tld2 -tany +nochange a4-3.tld2 +nochange a3-1.tld2 -tAAAA +nochange a4-1-aaaa.tld2 -tAAAA +nochange a5-1-2.tld2 +end_group +ckstats $ns3 'radix tree deletions' ns3 0 - # these tests assume "min-ns-dots 0" - start_group "NSDNAME rewrites" test3 - nextpart ns3/named.run >/dev/null - nochange a3-1.tld2 # 1 - nochange a3-1.tld2 +dnssec # 2 this once caused problems - nxdomain a3-1.sub1.tld2 # 3 NXDOMAIN *.sub1.tld2 by NSDNAME - nxdomain a3-1.subsub.sub1.tld2 # 4 - nxdomain a3-1.subsub.sub1.tld2 -tany # 5 - addr 12.12.12.12 a4-2.subsub.sub2.tld2 # 6 walled garden for *.sub2.tld2 - nochange a3-2.tld2. # 7 exempt rewrite by name - nochange a0-1.tld2. # 8 exempt rewrite by address block - addr 12.12.12.12 a4-1.tld2 # 9 prefer QNAME policy to NSDNAME - addr 127.0.0.1 a3-1.sub3.tld2 # 10 prefer policy for largest NSDNAME - addr 127.0.0.2 a3-1.subsub.sub3.tld2 # 11 - nxdomain xxx.crash1.tld2 # 12 dns_db_detachnode() crash +# these tests assume "min-ns-dots 0" +start_group "NSDNAME rewrites" test3 +nextpart ns3/named.run >/dev/null +nochange a3-1.tld2 # 1 +nochange a3-1.tld2 +dnssec # 2 this once caused problems +nxdomain a3-1.sub1.tld2 # 3 NXDOMAIN *.sub1.tld2 by NSDNAME +nxdomain a3-1.subsub.sub1.tld2 # 4 +nxdomain a3-1.subsub.sub1.tld2 -tany # 5 +addr 12.12.12.12 a4-2.subsub.sub2.tld2 # 6 walled garden for *.sub2.tld2 +nochange a3-2.tld2. # 7 exempt rewrite by name +nochange a0-1.tld2. # 8 exempt rewrite by address block +addr 12.12.12.12 a4-1.tld2 # 9 prefer QNAME policy to NSDNAME +addr 127.0.0.1 a3-1.sub3.tld2 # 10 prefer policy for largest NSDNAME +addr 127.0.0.2 a3-1.subsub.sub3.tld2 # 11 +nxdomain xxx.crash1.tld2 # 12 dns_db_detachnode() crash - nxdomain a3-1.stub # 13 - nxdomain a3-1.static-stub # 14 - nochange_ns10 a3-1.stub-nomatch # 15 - nochange_ns10 a3-1.static-stub-nomatch # 16 - if [ "$mode" = dnsrps ]; then - addr 12.12.12.12 as-ns.tld5. # 17 qname-as-ns - fi - nextpart ns3/named.run | grep -q "unrecognized NS rpz_rrset_find() failed: glue" \ - && setret "seen: unrecognized NS rpz_rrset_find() failed: glue" - end_group - if [ "$mode" = dnsrps ]; then - ckstats $ns3 test3 ns3 10 - else - ckstats $ns3 test3 ns3 9 - fi +nxdomain a3-1.stub # 13 +nxdomain a3-1.static-stub # 14 +nochange_ns10 a3-1.stub-nomatch # 15 +nochange_ns10 a3-1.static-stub-nomatch # 16 +if [ "$MODE" = dnsrps ]; then + addr 12.12.12.12 as-ns.tld5. # 17 qname-as-ns +fi +nextpart ns3/named.run | grep -q "unrecognized NS rpz_rrset_find() failed: glue" \ + && setret "seen: unrecognized NS rpz_rrset_find() failed: glue" +end_group +if [ "$MODE" = dnsrps ]; then + ckstats $ns3 test3 ns3 10 +else + ckstats $ns3 test3 ns3 9 +fi - # these tests assume "min-ns-dots 0" - start_group "NSIP rewrites" test4 - nextpart ns3/named.run >/dev/null - nxdomain a3-1.tld2 # 1 NXDOMAIN for all of tld2 - nochange a3-2.tld2. # 2 exempt rewrite by name - nochange a0-1.tld2. # 3 exempt rewrite by address block - nochange a3-1.tld4 # 4 different NS IP address - nxdomain a4-1.stub # 5 - nxdomain a4-1.static-stub # 6 - nochange_ns10 a4-1.stub-nomatch # 7 - nochange_ns10 a4-1.static-stub-nomatch # 8 - if [ "$mode" = dnsrps ]; then - addr 12.12.12.12 as-ns.tld5. # 9 ip-as-ns - fi - nextpart ns3/named.run | grep -q "unrecognized NS rpz_rrset_find() failed: glue" \ - && setret "seen: unrecognized NS rpz_rrset_find() failed: glue" - end_group +# these tests assume "min-ns-dots 0" +start_group "NSIP rewrites" test4 +nextpart ns3/named.run >/dev/null +nxdomain a3-1.tld2 # 1 NXDOMAIN for all of tld2 +nochange a3-2.tld2. # 2 exempt rewrite by name +nochange a0-1.tld2. # 3 exempt rewrite by address block +nochange a3-1.tld4 # 4 different NS IP address +nxdomain a4-1.stub # 5 +nxdomain a4-1.static-stub # 6 +nochange_ns10 a4-1.stub-nomatch # 7 +nochange_ns10 a4-1.static-stub-nomatch # 8 +if [ "$MODE" = dnsrps ]; then + addr 12.12.12.12 as-ns.tld5. # 9 ip-as-ns +fi +nextpart ns3/named.run | grep -q "unrecognized NS rpz_rrset_find() failed: glue" \ + && setret "seen: unrecognized NS rpz_rrset_find() failed: glue" +end_group - start_group "walled garden NSIP rewrites" test4a - addr 41.41.41.41 a3-1.tld2 # 1 walled garden for all of tld2 - addr 2041::41 'a3-1.tld2 AAAA' # 2 walled garden for all of tld2 - here a3-1.tld2 TXT <<'EOF' # 3 text message for all of tld2 - ;; status: NOERROR, x - a3-1.tld2. x IN TXT "NSIP walled garden" +start_group "walled garden NSIP rewrites" test4a +addr 41.41.41.41 a3-1.tld2 # 1 walled garden for all of tld2 +addr 2041::41 'a3-1.tld2 AAAA' # 2 walled garden for all of tld2 +here a3-1.tld2 TXT <<'EOF' # 3 text message for all of tld2 + ;; status: NOERROR, x + a3-1.tld2. x IN TXT "NSIP walled garden" EOF - end_group - if [ "$mode" = dnsrps ]; then - ckstats $ns3 test4 ns3 7 - else - ckstats $ns3 test4 ns3 6 - fi +end_group +if [ "$MODE" = dnsrps ]; then + ckstats $ns3 test4 ns3 7 +else + ckstats $ns3 test4 ns3 6 +fi - # policies in ./test5 overridden by response-policy{} in ns3/named.conf - # and in ns5/named.conf - start_group "policy overrides" test5 - addr 127.0.0.1 a3-1.tld2 # 1 bl-given - nochange a3-2.tld2 # 2 bl-passthru - nochange a3-3.tld2 # 3 bl-no-op (obsolete for passthru) - nochange a3-4.tld2 # 4 bl-disabled - nodata a3-5.tld2 # 5 bl-nodata zone recursive-only no - nodata a3-5.tld2 +norecurse # 6 bl-nodata zone recursive-only no - nodata a3-5.tld2 # 7 bl-nodata not needed - nxdomain a3-5.tld2 +norecurse @$ns5 # 8 bl-nodata global recursive-only no - nxdomain a3-5.tld2s @$ns5 # 9 bl-nodata global break-dnssec - nxdomain a3-5.tld2s +dnssec @$ns5 # 10 bl-nodata global break-dnssec - nxdomain a3-6.tld2 # 11 bl-nxdomain - here a3-7.tld2 -tany <<'EOF' # 12 - ;; status: NOERROR, x - a3-7.tld2. x IN CNAME txt-only.tld2. - txt-only.tld2. x IN TXT "txt-only-tld2" +# policies in ./test5 overridden by response-policy{} in ns3/named.conf +# and in ns5/named.conf +start_group "policy overrides" test5 +addr 127.0.0.1 a3-1.tld2 # 1 bl-given +nochange a3-2.tld2 # 2 bl-passthru +nochange a3-3.tld2 # 3 bl-no-op (obsolete for passthru) +nochange a3-4.tld2 # 4 bl-disabled +nodata a3-5.tld2 # 5 bl-nodata zone recursive-only no +nodata a3-5.tld2 +norecurse # 6 bl-nodata zone recursive-only no +nodata a3-5.tld2 # 7 bl-nodata not needed +nxdomain a3-5.tld2 +norecurse @$ns5 # 8 bl-nodata global recursive-only no +nxdomain a3-5.tld2s @$ns5 # 9 bl-nodata global break-dnssec +nxdomain a3-5.tld2s +dnssec @$ns5 # 10 bl-nodata global break-dnssec +nxdomain a3-6.tld2 # 11 bl-nxdomain +here a3-7.tld2 -tany <<'EOF' # 12 + ;; status: NOERROR, x + a3-7.tld2. x IN CNAME txt-only.tld2. + txt-only.tld2. x IN TXT "txt-only-tld2" EOF - addr 58.58.58.58 a3-8.tld2 # 13 bl_wildcname - addr 59.59.59.59 a3-9.sub9.tld2 # 14 bl_wildcname - addr 12.12.12.12 a3-15.tld2 # 15 bl-garden via CNAME to a12.tld2 - addr 127.0.0.16 a3-16.tld2 100 # 16 bl max-policy-ttl 100 - addr 17.17.17.17 "a3-17.tld2 @$ns5" 90 # 17 ns5 bl max-policy-ttl 90 - drop a3-18.tld2 any # 18 bl-drop - nxdomain TCP a3-19.tld2 # 19 bl-tcp-only - end_group - ckstats $ns3 test5 ns3 12 - ckstats $ns5 test5 ns5 4 +addr 58.58.58.58 a3-8.tld2 # 13 bl_wildcname +addr 59.59.59.59 a3-9.sub9.tld2 # 14 bl_wildcname +addr 12.12.12.12 a3-15.tld2 # 15 bl-garden via CNAME to a12.tld2 +addr 127.0.0.16 a3-16.tld2 100 # 16 bl max-policy-ttl 100 +addr 17.17.17.17 "a3-17.tld2 @$ns5" 90 # 17 ns5 bl max-policy-ttl 90 +drop a3-18.tld2 any # 18 bl-drop +nxdomain TCP a3-19.tld2 # 19 bl-tcp-only +end_group +ckstats $ns3 test5 ns3 12 +ckstats $ns5 test5 ns5 4 - # check that miscellaneous bugs are still absent - start_group "crashes" test6 - for Q in RRSIG SIG ANY 'ANY +dnssec'; do - nocrash a3-1.tld2 -t$Q - nocrash a3-2.tld2 -t$Q - nocrash a3-5.tld2 -t$Q - nocrash www.redirect -t$Q - nocrash www.credirect -t$Q - done - - # This is not a bug, because any data leaked by writing 24.4.3.2.10.rpz-ip - # (or whatever) is available by publishing "foo A 10.2.3.4" and then - # resolving foo. - # nxdomain 32.3.2.1.127.rpz-ip - end_group - ckstats $ns3 bugs ns3 8 - - # superficial test for major performance bugs - QPERF=$(sh qperf.sh) - if test -n "$QPERF"; then - perf() { - date "+${TS}checking performance $1" | cat_i - # Dry run to prime everything - comment "before dry run $1" - $RNDCCMD $ns5 notrace - $QPERF -c -1 -l30 -d ns5/requests -s $ns5 -p ${PORT} >/dev/null - comment "before real test $1" - PFILE="ns5/$2.perf" - $QPERF -c -1 -l30 -d ns5/requests -s $ns5 -p ${PORT} >$PFILE - comment "after test $1" - X=$(sed -n -e 's/.*Returned *\([^ ]*:\) *\([0-9]*\) .*/\1\2/p' $PFILE \ - | tr '\n' ' ') - if test "$X" != "$3"; then - setret "wrong results '$X' in $PFILE" - fi - ckalive $ns5 "failed; server #5 crashed" - } - trim() { - sed -n -e 's/.*Queries per second: *\([0-9]*\).*/\1/p' ns5/$1.perf - } - - # get qps with rpz - perf 'with RPZ' rpz 'NOERROR:2900 NXDOMAIN:100 ' - RPZ=$(trim rpz) - # turn off rpz and measure qps again - echo "# RPZ off" >ns5/rpz-switch - RNDCCMD_OUT=$($RNDCCMD $ns5 reload) - perf 'without RPZ' norpz 'NOERROR:3000 ' - NORPZ=$(trim norpz) - - PERCENT=$(((RPZ * 100 + (NORPZ / 2)) / NORPZ)) - echo_i "$RPZ qps with RPZ is $PERCENT% of $NORPZ qps without RPZ" - - MIN_PERCENT=30 - if test "$PERCENT" -lt $MIN_PERCENT; then - echo_i "$RPZ qps with rpz or $PERCENT% is below $MIN_PERCENT% of $NORPZ qps" - fi - - if test "$PERCENT" -ge 100; then - echo_i "$RPZ qps with RPZ or $PERCENT% of $NORPZ qps without RPZ is too high" - fi - - ckstats $ns5 performance ns5 200 - - else - echo_i "performance not checked; queryperf not available" - fi - - if [ "$mode" = dnsrps ]; then - echo_i "checking that dnsrpzd is automatically restarted" - OLD_PID=$(cat dnsrpzd.pid) - kill "$OLD_PID" - n=0 - while true; do - NEW_PID=$(cat dnsrpzd.pid 2>/dev/null) - if test -n "$NEW_PID" -a "0$OLD_PID" -ne "0$NEW_PID"; then - #echo "OLD_PID=$OLD_PID NEW_PID=$NEW_PID" - break - fi - $DIG -p ${PORT} +short +norecurse a0-1.tld2 @$ns3 >/dev/null - n=$((n + 1)) - if test "$n" -gt $TEN_SECS; then - setret "dnsrpzd did not restart" - break - fi - $WAIT_CMD - done - fi - - # Ensure ns3 manages to transfer the fast-expire zone before shutdown. - nextpartreset ns3/named.run - wait_for_log 20 "zone fast-expire/IN: transferred serial 1" ns3/named.run - - # reconfigure the ns5 primary server without the fast-expire zone, so - # it can't be refreshed on ns3, and will expire in 5 seconds. - cat /dev/null >ns5/expire.conf - rndc_reconfig ns5 10.53.0.5 - - # restart the main test RPZ server to see if that creates a core file - if test -z "$HAVE_CORE"; then - stop_server --use-rndc --port ${CONTROLPORT} ns3 - restart 3 "rebuild-bl-rpz" - HAVE_CORE=$(find ns* -name '*core*' -print) - test -z "$HAVE_CORE" || setret "found $HAVE_CORE; memory leak?" - fi - - # look for complaints from lib/dns/rpz.c and bin/name/query.c - for runfile in ns*/named.run; do - EMSGS=$(nextpart $runfile | grep -E -l 'invalid rpz|rpz.*failed' || true) - if test -n "$EMSGS"; then - setret "error messages in $runfile starting with:" - grep -E 'invalid rpz|rpz.*failed' ns*/named.run \ - | sed -e '10,$d' -e 's/^//' | cat_i - fi - done - - if [ native = "$mode" ]; then - # restart the main test RPZ server with a bad zone. - t=$((t + 1)) - echo_i "checking that ns3 with broken rpz does not crash (${t})" - stop_server --use-rndc --port ${CONTROLPORT} ns3 - cp ns3/broken.db.in ns3/bl.db - restart 3 # do not rebuild rpz zones - nocrash a3-1.tld2 -tA - stop_server --use-rndc --port ${CONTROLPORT} ns3 - restart 3 "rebuild-bl-rpz" - - t=$((t + 1)) - echo_i "checking if rpz survives a certain class of failed reconfiguration attempts (${t})" - sed -e "s/^#BAD//" ns3/named.conf.tmp - copy_setports ns3/named.conf.tmp ns3/named.conf - rm ns3/named.conf.tmp - $RNDCCMD $ns3 reconfig >/dev/null 2>&1 && setret "failed" - sleep 1 - copy_setports ns3/named.conf.in ns3/named.conf - $RNDCCMD $ns3 reconfig || setret "failed" - - # reload a RPZ zone that is now deliberately broken. - t=$((t + 1)) - echo_i "checking rpz failed update will keep previous rpz rules (${t})" - $DIG -p ${PORT} @$ns3 walled.tld2 >dig.out.$t.before || setret "failed" - grep "walled\.tld2\..*IN.*A.*10\.0\.0\.1" dig.out.$t.before >/dev/null || setret "failed" - cp ns3/broken.db.in ns3/manual-update-rpz.db - rndc_reload ns3 $ns3 manual-update-rpz - sleep 1 - # ensure previous RPZ rules still apply. - $DIG -p ${PORT} @$ns3 walled.tld2 >dig.out.$t.after || setret "failed" - grep "walled\.tld2\..*IN.*A.*10\.0\.0\.1" dig.out.$t.after >/dev/null || setret "failed" - - t=$((t + 1)) - echo_i "checking reload of a mixed-case RPZ zone (${t})" - # First, a sanity check: the A6-2.TLD2.mixed-case-rpz RPZ record should - # cause a6-2.tld2 NOERROR answers to be rewritten to NXDOMAIN answers. - $DIG -p ${PORT} @$ns3 a6-2.tld2. A >dig.out.$t.before || setret "failed" - grep "status: NXDOMAIN" dig.out.$t.before >/dev/null || setret "failed" - # Add a sibling name (a6-1.tld2.mixed-case-rpz, with "tld2" in lowercase - # rather than uppercase) before A6-2.TLD.mixed-case-rpz. - nextpart ns3/named.run >/dev/null - cp ns3/mixed-case-rpz-2.db.in ns3/mixed-case-rpz.db - rndc_reload ns3 $ns3 mixed-case-rpz - wait_for_log 20 "rpz: mixed-case-rpz: reload done" ns3/named.run - # a6-2.tld2 NOERROR answers should still be rewritten to NXDOMAIN answers. - # (The bug we try to trigger here caused a6-2.tld2.mixed-case-rpz to be - # erroneously removed from the summary RPZ database after reload.) - $DIG -p ${PORT} @$ns3 a6-2.tld2. A >dig.out.$t.after || setret "failed" - grep "status: NXDOMAIN" dig.out.$t.after >/dev/null || setret "failed" - fi - - t=$((t + 1)) - echo_i "checking that ttl values are not zeroed when qtype is '*' (${t})" - $DIG +noall +answer -p ${PORT} @$ns3 any a3-2.tld2 >dig.out.$t || setret "failed" - ttl=$(awk '/a3-2 tld2 text/ {print $2}' dig.out.$t) - if test ${ttl:=0} -eq 0; then setret "failed"; fi - - t=$((t + 1)) - echo_i "checking rpz updates/transfers with parent nodes added after children (${t})" - # regression test for RT #36272: the success condition - # is the secondary server not crashing. - for i in 1 2 3 4 5; do - nsd $ns5 add example.com.policy1. '*.example.com.policy1.' - nsd $ns5 delete example.com.policy1. '*.example.com.policy1.' - done - for i in 1 2 3 4 5; do - nsd $ns5 add '*.example.com.policy1.' example.com.policy1. - nsd $ns5 delete '*.example.com.policy1.' example.com.policy1. - done - - t=$((t + 1)) - echo_i "checking that going from an empty policy zone works (${t})" - nsd $ns5 add '*.x.servfail.policy2.' x.servfail.policy2. - sleep 1 - rndc_reload ns7 $ns7 policy2 - $DIG z.x.servfail -p ${PORT} @$ns7 >dig.out.${t} || setret "failed" - grep NXDOMAIN dig.out.${t} >/dev/null || setret "failed" - - t=$((t + 1)) - echo_i "checking that "add-soa no" at rpz zone level works (${t})" - $DIG z.x.servfail -p ${PORT} @$ns7 >dig.out.${t} || setret "failed" - grep SOA dig.out.${t} >/dev/null && setret "failed" - - if [ native = "$mode" ]; then - t=$((t + 1)) - echo_i "checking that "add-soa yes" at response-policy level works (${t})" - $DIG walled.tld2 -p ${PORT} +noall +add @$ns3 >dig.out.${t} || setret "failed" - grep "^manual-update-rpz\..*SOA" dig.out.${t} >/dev/null || setret "failed" - fi - - if [ native = "$mode" ]; then - t=$((t + 1)) - echo_i "reconfiguring server with 'add-soa no' (${t})" - cp ns3/named.conf ns3/named.conf.tmp - sed -e "s/add-soa yes/add-soa no/g" ns3/named.conf - rndc_reconfig ns3 $ns3 - echo_i "checking that 'add-soa no' at response-policy level works (${t})" - $DIG walled.tld2 -p ${PORT} +noall +add @$ns3 >dig.out.${t} || setret "failed" - grep "^manual-update-rpz\..*SOA" dig.out.${t} >/dev/null && setret "failed" - fi - - if [ native = "$mode" ]; then - t=$((t + 1)) - echo_i "checking that 'add-soa unset' works (${t})" - $DIG walled.tld2 -p ${PORT} +noall +add @$ns8 >dig.out.${t} || setret "failed" - grep "^manual-update-rpz\..*SOA" dig.out.${t} >/dev/null || setret "failed" - fi - - # dnsrps does not allow NS RRs in policy zones, so this check - # with dnsrps results in no rewriting. - if [ native = "$mode" ]; then - t=$((t + 1)) - echo_i "checking rpz with delegation fails correctly (${t})" - $DIG -p ${PORT} @$ns3 ns example.com >dig.out.$t || setret "failed" - grep "status: SERVFAIL" dig.out.$t >/dev/null || setret "failed" - - t=$((t + 1)) - echo_i "checking policies from expired zone are no longer in effect ($t)" - $DIG -p ${PORT} @$ns3 a expired >dig.out.$t || setret "failed" - grep "expired.*10.0.0.10" dig.out.$t >/dev/null && setret "failed" - grep "fast-expire/IN: response-policy zone expired" ns3/named.run >/dev/null || setret "failed" - fi - - # RPZ 'CNAME *.' (NODATA) trumps DNS64. Test against various DNS64 scenarios. - for label in a-only no-a-no-aaaa a-plus-aaaa; do - for type in AAAA A; do - t=$((t + 1)) - case $label in - a-only) - echo_i "checking rpz 'CNAME *.' (NODATA) with dns64, $type lookup with A-only (${t})" - ;; - no-a-no-aaaa) - echo_i "checking rpz 'CNAME *.' (NODATA) with dns64, $type lookup with no A or AAAA (${t})" - ;; - a-plus-aaaa) - echo_i "checking rpz 'CNAME *.' (NODATA) with dns64, $type lookup with A and AAAA (${t})" - ;; - esac - ret=0 - $DIG ${label}.example -p ${PORT} $type @10.53.0.9 >dig.out.${t} || setret "failed" - grep "status: NOERROR" dig.out.$t >/dev/null || ret=1 - grep "ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 2$" dig.out.$t >/dev/null || ret=1 - grep "^rpz" dig.out.$t >/dev/null || ret=1 - [ $ret -eq 0 ] || echo_i "failed" - status=$((status + ret)) - done - done - - if [ native = "$mode" ]; then - t=$((t + 1)) - echo_i "checking that rewriting CD=1 queries handles pending data correctly (${t})" - $RNDCCMD $ns3 flush - $RNDCCMD $ns6 flush - $DIG a7-2.tld2s -p ${PORT} @$ns6 +cd >dig.out.${t} || setret "failed" - grep -w "1.1.1.1" dig.out.${t} >/dev/null || setret "failed" - fi - - [ $status -ne 0 ] && pf=fail || pf=pass - case $mode in - native) - native=$status - echo_i "status (native RPZ sub-test): $status ($pf)" - ;; - - dnsrps) - dnsrps=$status - echo_i "status (DNSRPS sub-test): $status ($pf)" - ;; - *) echo_i "invalid test mode" ;; - esac +# check that miscellaneous bugs are still absent +start_group "crashes" test6 +for Q in RRSIG SIG ANY 'ANY +dnssec'; do + nocrash a3-1.tld2 -t$Q + nocrash a3-2.tld2 -t$Q + nocrash a3-5.tld2 -t$Q + nocrash www.redirect -t$Q + nocrash www.credirect -t$Q done -status=$((native + dnsrps)) + +# This is not a bug, because any data leaked by writing 24.4.3.2.10.rpz-ip +# (or whatever) is available by publishing "foo A 10.2.3.4" and then +# resolving foo. +# nxdomain 32.3.2.1.127.rpz-ip +end_group +ckstats $ns3 bugs ns3 8 + +# superficial test for major performance bugs +QPERF=$(sh qperf.sh) +if test -n "$QPERF"; then + perf() { + date "+${TS}checking performance $1" | cat_i + # Dry run to prime everything + comment "before dry run $1" + $RNDCCMD $ns5 notrace + $QPERF -c -1 -l30 -d ns5/requests -s $ns5 -p ${PORT} >/dev/null + comment "before real test $1" + PFILE="ns5/$2.perf" + $QPERF -c -1 -l30 -d ns5/requests -s $ns5 -p ${PORT} >$PFILE + comment "after test $1" + X=$(sed -n -e 's/.*Returned *\([^ ]*:\) *\([0-9]*\) .*/\1\2/p' $PFILE \ + | tr '\n' ' ') + if test "$X" != "$3"; then + setret "wrong results '$X' in $PFILE" + fi + ckalive $ns5 "failed; server #5 crashed" + } + trim() { + sed -n -e 's/.*Queries per second: *\([0-9]*\).*/\1/p' ns5/$1.perf + } + + # get qps with rpz + perf 'with RPZ' rpz 'NOERROR:2900 NXDOMAIN:100 ' + RPZ=$(trim rpz) + # turn off rpz and measure qps again + echo "# RPZ off" >ns5/rpz-switch + RNDCCMD_OUT=$($RNDCCMD $ns5 reload) + perf 'without RPZ' norpz 'NOERROR:3000 ' + NORPZ=$(trim norpz) + + PERCENT=$(((RPZ * 100 + (NORPZ / 2)) / NORPZ)) + echo_i "$RPZ qps with RPZ is $PERCENT% of $NORPZ qps without RPZ" + + MIN_PERCENT=30 + if test "$PERCENT" -lt $MIN_PERCENT; then + echo_i "$RPZ qps with rpz or $PERCENT% is below $MIN_PERCENT% of $NORPZ qps" + fi + + if test "$PERCENT" -ge 100; then + echo_i "$RPZ qps with RPZ or $PERCENT% of $NORPZ qps without RPZ is too high" + fi + + ckstats $ns5 performance ns5 200 + +else + echo_i "performance not checked; queryperf not available" +fi + +if [ "$MODE" = dnsrps ]; then + echo_i "checking that dnsrpzd is automatically restarted" + OLD_PID=$(cat dnsrpzd.pid) + kill "$OLD_PID" + n=0 + while true; do + NEW_PID=$(cat dnsrpzd.pid 2>/dev/null) + if test -n "$NEW_PID" -a "0$OLD_PID" -ne "0$NEW_PID"; then + #echo "OLD_PID=$OLD_PID NEW_PID=$NEW_PID" + break + fi + $DIG -p ${PORT} +short +norecurse a0-1.tld2 @$ns3 >/dev/null + n=$((n + 1)) + if test "$n" -gt $TEN_SECS; then + setret "dnsrpzd did not restart" + break + fi + $WAIT_CMD + done +fi + +# Ensure ns3 manages to transfer the fast-expire zone before shutdown. +nextpartreset ns3/named.run +wait_for_log 20 "zone fast-expire/IN: transferred serial 1" ns3/named.run + +# reconfigure the ns5 primary server without the fast-expire zone, so +# it can't be refreshed on ns3, and will expire in 5 seconds. +cat /dev/null >ns5/expire.conf +rndc_reconfig ns5 10.53.0.5 + +# restart the main test RPZ server to see if that creates a core file +if test -z "$HAVE_CORE"; then + stop_server --use-rndc --port ${CONTROLPORT} ns3 + restart 3 "rebuild-bl-rpz" + HAVE_CORE=$(find ns* -name '*core*' -print) + test -z "$HAVE_CORE" || setret "found $HAVE_CORE; memory leak?" +fi + +# look for complaints from lib/dns/rpz.c and bin/name/query.c +for runfile in ns*/named.run; do + EMSGS=$(nextpart $runfile | grep -E -l 'invalid rpz|rpz.*failed' || true) + if test -n "$EMSGS"; then + setret "error messages in $runfile starting with:" + grep -E 'invalid rpz|rpz.*failed' ns*/named.run \ + | sed -e '10,$d' -e 's/^//' | cat_i + fi +done + +if [ native = "$MODE" ]; then + # restart the main test RPZ server with a bad zone. + t=$((t + 1)) + echo_i "checking that ns3 with broken rpz does not crash (${t})" + stop_server --use-rndc --port ${CONTROLPORT} ns3 + cp ns3/broken.db.in ns3/bl.db + restart 3 # do not rebuild rpz zones + nocrash a3-1.tld2 -tA + stop_server --use-rndc --port ${CONTROLPORT} ns3 + restart 3 "rebuild-bl-rpz" + + t=$((t + 1)) + echo_i "checking if rpz survives a certain class of failed reconfiguration attempts (${t})" + sed -e "s/^#BAD//" ns3/named.conf.tmp + copy_setports ns3/named.conf.tmp ns3/named.conf + rm ns3/named.conf.tmp + $RNDCCMD $ns3 reconfig >/dev/null 2>&1 && setret "failed" + sleep 1 + copy_setports ns3/named.conf.in ns3/named.conf + $RNDCCMD $ns3 reconfig || setret "failed" + + # reload a RPZ zone that is now deliberately broken. + t=$((t + 1)) + echo_i "checking rpz failed update will keep previous rpz rules (${t})" + $DIG -p ${PORT} @$ns3 walled.tld2 >dig.out.$t.before || setret "failed" + grep "walled\.tld2\..*IN.*A.*10\.0\.0\.1" dig.out.$t.before >/dev/null || setret "failed" + cp ns3/broken.db.in ns3/manual-update-rpz.db + rndc_reload ns3 $ns3 manual-update-rpz + sleep 1 + # ensure previous RPZ rules still apply. + $DIG -p ${PORT} @$ns3 walled.tld2 >dig.out.$t.after || setret "failed" + grep "walled\.tld2\..*IN.*A.*10\.0\.0\.1" dig.out.$t.after >/dev/null || setret "failed" + + t=$((t + 1)) + echo_i "checking reload of a mixed-case RPZ zone (${t})" + # First, a sanity check: the A6-2.TLD2.mixed-case-rpz RPZ record should + # cause a6-2.tld2 NOERROR answers to be rewritten to NXDOMAIN answers. + $DIG -p ${PORT} @$ns3 a6-2.tld2. A >dig.out.$t.before || setret "failed" + grep "status: NXDOMAIN" dig.out.$t.before >/dev/null || setret "failed" + # Add a sibling name (a6-1.tld2.mixed-case-rpz, with "tld2" in lowercase + # rather than uppercase) before A6-2.TLD.mixed-case-rpz. + nextpart ns3/named.run >/dev/null + cp ns3/mixed-case-rpz-2.db.in ns3/mixed-case-rpz.db + rndc_reload ns3 $ns3 mixed-case-rpz + wait_for_log 20 "rpz: mixed-case-rpz: reload done" ns3/named.run + # a6-2.tld2 NOERROR answers should still be rewritten to NXDOMAIN answers. + # (The bug we try to trigger here caused a6-2.tld2.mixed-case-rpz to be + # erroneously removed from the summary RPZ database after reload.) + $DIG -p ${PORT} @$ns3 a6-2.tld2. A >dig.out.$t.after || setret "failed" + grep "status: NXDOMAIN" dig.out.$t.after >/dev/null || setret "failed" +fi + +t=$((t + 1)) +echo_i "checking that ttl values are not zeroed when qtype is '*' (${t})" +$DIG +noall +answer -p ${PORT} @$ns3 any a3-2.tld2 >dig.out.$t || setret "failed" +ttl=$(awk '/a3-2 tld2 text/ {print $2}' dig.out.$t) +if test ${ttl:=0} -eq 0; then setret "failed"; fi + +t=$((t + 1)) +echo_i "checking rpz updates/transfers with parent nodes added after children (${t})" +# regression test for RT #36272: the success condition +# is the secondary server not crashing. +for i in 1 2 3 4 5; do + nsd $ns5 add example.com.policy1. '*.example.com.policy1.' + nsd $ns5 delete example.com.policy1. '*.example.com.policy1.' +done +for i in 1 2 3 4 5; do + nsd $ns5 add '*.example.com.policy1.' example.com.policy1. + nsd $ns5 delete '*.example.com.policy1.' example.com.policy1. +done + +t=$((t + 1)) +echo_i "checking that going from an empty policy zone works (${t})" +nsd $ns5 add '*.x.servfail.policy2.' x.servfail.policy2. +sleep 1 +rndc_reload ns7 $ns7 policy2 +$DIG z.x.servfail -p ${PORT} @$ns7 >dig.out.${t} || setret "failed" +grep NXDOMAIN dig.out.${t} >/dev/null || setret "failed" + +t=$((t + 1)) +echo_i "checking that "add-soa no" at rpz zone level works (${t})" +$DIG z.x.servfail -p ${PORT} @$ns7 >dig.out.${t} || setret "failed" +grep SOA dig.out.${t} >/dev/null && setret "failed" + +if [ native = "$MODE" ]; then + t=$((t + 1)) + echo_i "checking that "add-soa yes" at response-policy level works (${t})" + $DIG walled.tld2 -p ${PORT} +noall +add @$ns3 >dig.out.${t} || setret "failed" + grep "^manual-update-rpz\..*SOA" dig.out.${t} >/dev/null || setret "failed" +fi + +if [ native = "$MODE" ]; then + t=$((t + 1)) + echo_i "reconfiguring server with 'add-soa no' (${t})" + cp ns3/named.conf ns3/named.conf.tmp + sed -e "s/add-soa yes/add-soa no/g" ns3/named.conf + rndc_reconfig ns3 $ns3 + echo_i "checking that 'add-soa no' at response-policy level works (${t})" + $DIG walled.tld2 -p ${PORT} +noall +add @$ns3 >dig.out.${t} || setret "failed" + grep "^manual-update-rpz\..*SOA" dig.out.${t} >/dev/null && setret "failed" +fi + +if [ native = "$MODE" ]; then + t=$((t + 1)) + echo_i "checking that 'add-soa unset' works (${t})" + $DIG walled.tld2 -p ${PORT} +noall +add @$ns8 >dig.out.${t} || setret "failed" + grep "^manual-update-rpz\..*SOA" dig.out.${t} >/dev/null || setret "failed" +fi + +# dnsrps does not allow NS RRs in policy zones, so this check +# with dnsrps results in no rewriting. +if [ native = "$MODE" ]; then + t=$((t + 1)) + echo_i "checking rpz with delegation fails correctly (${t})" + $DIG -p ${PORT} @$ns3 ns example.com >dig.out.$t || setret "failed" + grep "status: SERVFAIL" dig.out.$t >/dev/null || setret "failed" + + t=$((t + 1)) + echo_i "checking policies from expired zone are no longer in effect ($t)" + $DIG -p ${PORT} @$ns3 a expired >dig.out.$t || setret "failed" + grep "expired.*10.0.0.10" dig.out.$t >/dev/null && setret "failed" + grep "fast-expire/IN: response-policy zone expired" ns3/named.run >/dev/null || setret "failed" +fi + +# RPZ 'CNAME *.' (NODATA) trumps DNS64. Test against various DNS64 scenarios. +for label in a-only no-a-no-aaaa a-plus-aaaa; do + for type in AAAA A; do + t=$((t + 1)) + case $label in + a-only) + echo_i "checking rpz 'CNAME *.' (NODATA) with dns64, $type lookup with A-only (${t})" + ;; + no-a-no-aaaa) + echo_i "checking rpz 'CNAME *.' (NODATA) with dns64, $type lookup with no A or AAAA (${t})" + ;; + a-plus-aaaa) + echo_i "checking rpz 'CNAME *.' (NODATA) with dns64, $type lookup with A and AAAA (${t})" + ;; + esac + ret=0 + $DIG ${label}.example -p ${PORT} $type @10.53.0.9 >dig.out.${t} || setret "failed" + grep "status: NOERROR" dig.out.$t >/dev/null || ret=1 + grep "ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 2$" dig.out.$t >/dev/null || ret=1 + grep "^rpz" dig.out.$t >/dev/null || ret=1 + [ $ret -eq 0 ] || echo_i "failed" + status=$((status + ret)) + done +done + +if [ native = "$MODE" ]; then + t=$((t + 1)) + echo_i "checking that rewriting CD=1 queries handles pending data correctly (${t})" + $RNDCCMD $ns3 flush + $RNDCCMD $ns6 flush + $DIG a7-2.tld2s -p ${PORT} @$ns6 +cd >dig.out.${t} || setret "failed" + grep -w "1.1.1.1" dig.out.${t} >/dev/null || setret "failed" +fi [ $status -eq 0 ] || exit 1 diff --git a/bin/tests/system/rpz/tests_sh_rpz_dnsrps.py b/bin/tests/system/rpz/tests_sh_rpz_dnsrps.py new file mode 100644 index 0000000000..d796dfcd17 --- /dev/null +++ b/bin/tests/system/rpz/tests_sh_rpz_dnsrps.py @@ -0,0 +1,20 @@ +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +import isctest.mark + +pytestmark = isctest.mark.dnsrps_enabled + + +def test_rpz_dnsrps(run_tests_sh): + with open("dnsrps.conf", "w", encoding="utf-8") as conf: + conf.writelines(["dnsrps-enable yes;"]) + run_tests_sh() diff --git a/bin/tests/system/rpzrecurse/setup.sh b/bin/tests/system/rpzrecurse/setup.sh index 8a8ebe9af4..8d21434148 100644 --- a/bin/tests/system/rpzrecurse/setup.sh +++ b/bin/tests/system/rpzrecurse/setup.sh @@ -17,29 +17,7 @@ set -e . ../conf.sh -USAGE="$0: [-DNx]" -DEBUG= -while getopts "DNx" c; do - case $c in - x) - set -x - DEBUG=-x - ;; - D) TEST_DNSRPS="-D" ;; - N) NOCLEAN=set ;; - *) - echo "$USAGE" 1>&2 - exit 1 - ;; - esac -done -shift $((OPTIND - 1)) -if test "$#" -ne 0; then - echo "$USAGE" 1>&2 - exit 1 -fi - -[ ${NOCLEAN:-unset} = unset ] && $SHELL clean.sh $DEBUG +$SHELL clean.sh $PERL testgen.pl @@ -52,6 +30,8 @@ copy_setports ns3/named1.conf.in ns3/named.conf copy_setports ns4/named.conf.in ns4/named.conf +touch dnsrps.conf + # setup policy zones for a 64-zone test i=1 while test $i -le 64; do @@ -68,10 +48,6 @@ while test $i -le 64; do i=$((i + 1)) done -# decide whether to test DNSRPS -$SHELL ../ckdnsrps.sh $TEST_DNSRPS $DEBUG -test -z "$(grep 'dnsrps-enable yes' dnsrps.conf)" && TEST_DNSRPS= - CWD=$(pwd) cat <dnsrpzd.conf PID-FILE $CWD/dnsrpzd.pid; diff --git a/bin/tests/system/rpzrecurse/tests.sh b/bin/tests/system/rpzrecurse/tests.sh index afc1a2b928..34b3720796 100644 --- a/bin/tests/system/rpzrecurse/tests.sh +++ b/bin/tests/system/rpzrecurse/tests.sh @@ -22,17 +22,16 @@ status=0 t=0 -DEBUG= ARGS= +if grep 'dnsrps-enable yes;' dnsrps.conf >/dev/null; then + MODE=dnsrps +else + MODE=native +fi -USAGE="$0: [-xS]" -while getopts "xS:" c; do +USAGE="$0: [-S]" +while getopts "S:" c; do case $c in - x) - set -x - DEBUG=-x - ARGS="$ARGS -x" - ;; S) SAVE_RESULTS=-S ARGS="$ARGS -S" @@ -118,452 +117,397 @@ add_test_marker() { done } -native=0 -dnsrps=0 -for mode in native dnsrps; do - status=0 - case $mode in - native) - if [ -e dnsrps-only ]; then - echo_i "'dnsrps-only' found: skipping native RPZ sub-test" - continue - else - echo_i "running native RPZ sub-test" - fi - ;; - dnsrps) - if [ -e dnsrps-off ]; then - echo_i "'dnsrps-off' found: skipping DNSRPS sub-test" - continue - fi - echo_i "attempting to configure servers with DNSRPS..." - stop_server --use-rndc --port ${CONTROLPORT} - $SHELL ./setup.sh -N -D $DEBUG - sed -n 's/^## //p' dnsrps.conf | cat_i - if grep '^#fail' dnsrps.conf >/dev/null; then - echo_i "exit status: 1" - exit 1 - fi - if grep '^#skip' dnsrps.conf >/dev/null; then - echo_i "DNSRPS sub-test skipped" - continue - else - echo_i "running DNSRPS sub-test" - start_server --noclean --restart --port ${PORT} - sleep 3 - fi - ;; - esac +t=$((t + 1)) +echo_i "testing that l1.l0 exists without RPZ (${t})" +add_test_marker 10.53.0.2 +$DIG $DIGOPTS l1.l0 ns @10.53.0.2 -p ${PORT} >dig.out.${t} +grep "status: NOERROR" dig.out.${t} >/dev/null 2>&1 || { + echo_i "test ${t} failed" + status=1 +} - # show whether and why DNSRPS is enabled or disabled - sed -n 's/^## //p' dnsrps.conf | cat_i +t=$((t + 1)) +echo_i "testing that l2.l1.l0 returns SERVFAIL without RPZ (${t})" +add_test_marker 10.53.0.2 +$DIG $DIGOPTS l2.l1.l0 ns @10.53.0.2 -p ${PORT} >dig.out.${t} +grep "status: SERVFAIL" dig.out.${t} >/dev/null 2>&1 || { + echo_i "test ${t} failed" + status=1 +} - t=$((t + 1)) - echo_i "testing that l1.l0 exists without RPZ (${t})" - add_test_marker 10.53.0.2 - $DIG $DIGOPTS l1.l0 ns @10.53.0.2 -p ${PORT} >dig.out.${t} - grep "status: NOERROR" dig.out.${t} >/dev/null 2>&1 || { - echo_i "test ${t} failed" - status=1 - } +# Group 1 +run_server 1a +expect_norecurse 1a 1 +run_server 1b +expect_norecurse 1b 1 +expect_recurse 1b 2 +run_server 1c +expect_norecurse 1c 1 - t=$((t + 1)) - echo_i "testing that l2.l1.l0 returns SERVFAIL without RPZ (${t})" - add_test_marker 10.53.0.2 - $DIG $DIGOPTS l2.l1.l0 ns @10.53.0.2 -p ${PORT} >dig.out.${t} - grep "status: SERVFAIL" dig.out.${t} >/dev/null 2>&1 || { - echo_i "test ${t} failed" - status=1 - } - - # Group 1 - run_server 1a - expect_norecurse 1a 1 - run_server 1b - expect_norecurse 1b 1 - expect_recurse 1b 2 - run_server 1c - expect_norecurse 1c 1 - - # Group 2 - run_server 2a - for n in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \ - 21 22 23 24 25 26 27 28 29 30 31 32; do - expect_norecurse 2a $n - done - expect_recurse 2a 33 - - # Group 3 - run_server 3a - expect_recurse 3a 1 - run_server 3b - expect_recurse 3b 1 - run_server 3c - expect_recurse 3c 1 - run_server 3d - expect_norecurse 3d 1 - expect_recurse 3d 2 - run_server 3e - expect_norecurse 3e 1 - expect_recurse 3e 2 - run_server 3f - expect_norecurse 3f 1 - expect_recurse 3f 2 - - # Group 4 - testlist="aa ap bf" - values="1 16 32" - # Uncomment the following to test every skip value instead of - # only a sample of values - # - #testlist="aa ab ac ad ae af ag ah ai aj ak al am an ao ap \ - # aq ar as at au av aw ax ay az ba bb bc bd be bf" - #values="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \ - # 21 22 23 24 25 26 27 28 29 30 31 32" - set -- $values - for n in $testlist; do - run_server 4$n - ni=$1 - t=$((t + 1)) - echo_i "testing that ${ni} of 33 queries skip recursion (${t})" - add_test_marker 10.53.0.2 - c=0 - for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \ - 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33; do - run_query 4$n $i || c=$((c + 1)) - done - skipped=$((33 - c)) - if [ $skipped != $ni ]; then - echo_i "test $t failed (actual=$skipped, expected=$ni)" - status=1 - fi - shift - done - - # Group 5 - run_server 5a - expect_norecurse 5a 1 - expect_norecurse 5a 2 - expect_recurse 5a 3 - expect_recurse 5a 4 - expect_recurse 5a 5 - expect_recurse 5a 6 - - # Group 6 - echo_i "check recursive behavior consistency during policy update races" - run_server 6a - sleep 1 - t=$((t + 1)) - echo_i "running dig to cache CNAME record (${t})" - add_test_marker 10.53.0.1 10.53.0.2 - $DIG $DIGOPTS @10.53.0.2 -p ${PORT} www.test.example.org CNAME >dig.out.${t} - sleep 1 - echo_i "suspending authority server" - PID=$(cat ns1/named.pid) - kill -STOP $PID - echo_i "adding an NSDNAME policy" - cp ns2/db.6a.00.policy.local ns2/saved.policy.local - cp ns2/db.6b.00.policy.local ns2/db.6a.00.policy.local - $RNDC -c ../_common/rndc.conf -s 10.53.0.2 -p ${CONTROLPORT} reload 6a.00.policy.local 2>&1 | sed 's/^/ns2 /' | cat_i - test -f dnsrpzd.pid && kill -USR1 $(cat dnsrpzd.pid) || true - sleep 1 - t=$((t + 1)) - echo_i "running dig to follow CNAME (blocks, so runs in the background) (${t})" - add_test_marker 10.53.0.2 - $DIG $DIGOPTS @10.53.0.2 -p ${PORT} www.test.example.org A +time=5 >dig.out.${t} & - sleep 1 - echo_i "removing the NSDNAME policy" - cp ns2/db.6c.00.policy.local ns2/db.6a.00.policy.local - $RNDC -c ../_common/rndc.conf -s 10.53.0.2 -p ${CONTROLPORT} reload 6a.00.policy.local 2>&1 | sed 's/^/ns2 /' | cat_i - test -f dnsrpzd.pid && kill -USR1 $(cat dnsrpzd.pid) || true - sleep 1 - echo_i "resuming authority server" - PID=$(cat ns1/named.pid) - kill -CONT $PID - add_test_marker 10.53.0.1 - for n in 1 2 3 4 5 6 7 8 9; do - sleep 1 - [ -s dig.out.${t} ] || continue - grep "status: .*," dig.out.${t} >/dev/null 2>&1 && break - done - grep "status: NOERROR" dig.out.${t} >/dev/null 2>&1 || { - echo_i "test ${t} failed" - status=1 - } - - echo_i "check recursive behavior consistency during policy removal races" - cp ns2/saved.policy.local ns2/db.6a.00.policy.local - run_server 6a - sleep 1 - t=$((t + 1)) - echo_i "running dig to cache CNAME record (${t})" - add_test_marker 10.53.0.1 10.53.0.2 - $DIG $DIGOPTS @10.53.0.2 -p ${PORT} www.test.example.org CNAME >dig.out.${t} - sleep 1 - echo_i "suspending authority server" - PID=$(cat ns1/named.pid) - kill -STOP $PID - echo_i "adding an NSDNAME policy" - cp ns2/db.6b.00.policy.local ns2/db.6a.00.policy.local - $RNDC -c ../_common/rndc.conf -s 10.53.0.2 -p ${CONTROLPORT} reload 6a.00.policy.local 2>&1 | sed 's/^/ns2 /' | cat_i - test -f dnsrpzd.pid && kill -USR1 $(cat dnsrpzd.pid) || true - sleep 1 - t=$((t + 1)) - echo_i "running dig to follow CNAME (blocks, so runs in the background) (${t})" - add_test_marker 10.53.0.2 - $DIG $DIGOPTS @10.53.0.2 -p ${PORT} www.test.example.org A +time=5 >dig.out.${t} & - sleep 1 - echo_i "removing the policy zone" - cp ns2/named.default.conf ns2/named.conf - rndc_reconfig ns2 10.53.0.2 - test -f dnsrpzd.pid && kill -USR1 $(cat dnsrpzd.pid) || true - sleep 1 - echo_i "resuming authority server" - PID=$(cat ns1/named.pid) - kill -CONT $PID - add_test_marker 10.53.0.1 - for n in 1 2 3 4 5 6 7 8 9; do - sleep 1 - [ -s dig.out.${t} ] || continue - grep "status: .*," dig.out.${t} >/dev/null 2>&1 && break - done - grep "status: NOERROR" dig.out.${t} >/dev/null 2>&1 || { - echo_i "test ${t} failed" - status=1 - } - - # Check maximum number of RPZ zones (64) - t=$((t + 1)) - echo_i "testing maximum number of RPZ zones (${t})" - add_test_marker 10.53.0.2 - run_server max - i=1 - while test $i -le 64; do - $DIG $DIGOPTS name$i a @10.53.0.2 -p ${PORT} -b 10.53.0.1 >dig.out.${t}.${i} - grep "^name$i.[ ]*[0-9]*[ ]*IN[ ]*A[ ]*10.53.0.$i" dig.out.${t}.${i} >/dev/null 2>&1 || { - echo_i "test $t failed: didn't get expected answer from policy zone $i" - status=1 - } - i=$((i + 1)) - done - - # Check CLIENT-IP behavior - t=$((t + 1)) - echo_i "testing CLIENT-IP behavior (${t})" - add_test_marker 10.53.0.2 - run_server clientip - $DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.4 >dig.out.${t} - grep "status: NOERROR" dig.out.${t} >/dev/null 2>&1 || { - echo_i "test $t failed: query failed" - status=1 - } - grep "^l2.l1.l0.[ ]*[0-9]*[ ]*IN[ ]*A[ ]*10.53.0.2" dig.out.${t} >/dev/null 2>&1 || { - echo_i "test $t failed: didn't get expected answer" - status=1 - } - - # Check CLIENT-IP behavior #2 - t=$((t + 1)) - echo_i "testing CLIENT-IP behavior #2 (${t})" - add_test_marker 10.53.0.2 - run_server clientip2 - $DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.1 >dig.out.${t}.1 - grep "status: SERVFAIL" dig.out.${t}.1 >/dev/null 2>&1 || { - echo_i "test $t failed: query failed" - status=1 - } - $DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.2 >dig.out.${t}.2 - grep "status: NXDOMAIN" dig.out.${t}.2 >/dev/null 2>&1 || { - echo_i "test $t failed: query failed" - status=1 - } - $DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.3 >dig.out.${t}.3 - grep "status: NOERROR" dig.out.${t}.3 >/dev/null 2>&1 || { - echo_i "test $t failed: query failed" - status=1 - } - grep "^l2.l1.l0.[ ]*[0-9]*[ ]*IN[ ]*A[ ]*10.53.0.1" dig.out.${t}.3 >/dev/null 2>&1 || { - echo_i "test $t failed: didn't get expected answer" - status=1 - } - $DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.4 >dig.out.${t}.4 - grep "status: SERVFAIL" dig.out.${t}.4 >/dev/null 2>&1 || { - echo_i "test $t failed: query failed" - status=1 - } - - # Check RPZ log clause - t=$((t + 1)) - echo_i "testing RPZ log clause (${t})" - add_test_marker 10.53.0.2 - run_server log - cur=$(awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run) - $DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.4 >dig.out.${t} - $DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.3 >>dig.out.${t} - $DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.2 >>dig.out.${t} - sed -n "$cur,"'$p' /dev/null && { - echo_ic "failed: unexpected rewrite message for policy zone log1 was logged" - status=1 - } - sed -n "$cur,"'$p' /dev/null || { - echo_ic "failed: expected rewrite message for policy zone log2 was not logged" - status=1 - } - sed -n "$cur,"'$p' /dev/null || { - echo_ic "failed: expected rewrite message for policy zone log3 was not logged" - status=1 - } - - # Check wildcard behavior - - t=$((t + 1)) - echo_i "testing wildcard behavior with 1 RPZ zone (${t})" - add_test_marker 10.53.0.2 - run_server wildcard1 - $DIG $DIGOPTS www.test1.example.net a @10.53.0.2 -p ${PORT} >dig.out.${t}.1 - grep "status: NXDOMAIN" dig.out.${t}.1 >/dev/null || { - echo_i "test ${t} failed" - status=1 - } - $DIG $DIGOPTS test1.example.net a @10.53.0.2 -p ${PORT} >dig.out.${t}.2 - grep "status: NXDOMAIN" dig.out.${t}.2 >/dev/null || { - echo_i "test ${t} failed" - status=1 - } - - t=$((t + 1)) - echo_i "testing wildcard behavior with 2 RPZ zones (${t})" - add_test_marker 10.53.0.2 - run_server wildcard2 - $DIG $DIGOPTS www.test1.example.net a @10.53.0.2 -p ${PORT} >dig.out.${t}.1 - grep "status: NXDOMAIN" dig.out.${t}.1 >/dev/null || { - echo_i "test ${t} failed" - status=1 - } - $DIG $DIGOPTS test1.example.net a @10.53.0.2 -p ${PORT} >dig.out.${t}.2 - grep "status: NXDOMAIN" dig.out.${t}.2 >/dev/null || { - echo_i "test ${t} failed" - status=1 - } - - t=$((t + 1)) - echo_i "testing wildcard behavior with 1 RPZ zone and no non-wildcard triggers (${t})" - add_test_marker 10.53.0.2 - run_server wildcard3 - $DIG $DIGOPTS www.test1.example.net a @10.53.0.2 -p ${PORT} >dig.out.${t}.1 - grep "status: NXDOMAIN" dig.out.${t}.1 >/dev/null || { - echo_i "test ${t} failed" - status=1 - } - $DIG $DIGOPTS test1.example.net a @10.53.0.2 -p ${PORT} >dig.out.${t}.2 - grep "status: NOERROR" dig.out.${t}.2 >/dev/null || { - echo_i "test ${t} failed" - status=1 - } - - t=$((t + 1)) - echo_i "testing wildcard passthru before explicit drop (${t})" - add_test_marker 10.53.0.2 - run_server wildcard4 - $DIG $DIGOPTS example.com a @10.53.0.2 -p ${PORT} >dig.out.${t}.1 - grep "status: NOERROR" dig.out.${t}.1 >/dev/null || { - echo_i "test ${t} failed" - status=1 - } - $DIG $DIGOPTS www.example.com a @10.53.0.2 -p ${PORT} >dig.out.${t}.2 - grep "status: NOERROR" dig.out.${t}.2 >/dev/null || { - echo_i "test ${t} failed" - status=1 - } - - if [ "$mode" = "native" ]; then - # Check for invalid prefix length error - t=$((t + 1)) - echo_i "testing for invalid prefix length error (${t})" - add_test_marker 10.53.0.2 - run_server invalidprefixlength - grep "invalid rpz IP address \"1000.4.0.53.10.rpz-client-ip.invalidprefixlength\"; invalid prefix length of 1000$" ns2/named.run >/dev/null || { - echo_ic "failed: expected that invalid prefix length error would be logged" - status=1 - } - fi - - t=$((t + 1)) - echo_i "checking 'nsip-wait-recurse no' is faster than 'nsip-wait-recurse yes' ($t)" - add_test_marker 10.53.0.2 10.53.0.3 - echo_i "timing 'nsip-wait-recurse yes' (default)" - ret=0 - t1=$($PERL -e 'print time()."\n";') - $DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a >dig.out.yes.$t - t2=$($PERL -e 'print time()."\n";') - p1=$((t2 - t1)) - echo_i "elapsed time $p1 seconds" - - $RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush - copy_setports ns3/named2.conf.in ns3/named.conf - nextpart ns3/named.run >/dev/null - $RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} reload >/dev/null - wait_for_log 20 "rpz: policy: reload done" ns3/named.run || ret=1 - - echo_i "timing 'nsip-wait-recurse no'" - t3=$($PERL -e 'print time()."\n";') - $DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a >dig.out.no.$t - t4=$($PERL -e 'print time()."\n";') - p2=$((t4 - t3)) - echo_i "elapsed time $p2 seconds" - - if test $p1 -le $p2; then ret=1; fi - if test $ret != 0; then echo_i "failed"; fi - status=$((status + ret)) - - $RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush - # restore original named.conf - copy_setports ns3/named1.conf.in ns3/named.conf - nextpart ns3/named.run >/dev/null - $RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} reload >/dev/null - wait_for_log 20 "rpz: policy: reload done" ns3/named.run || ret=1 - - t=$((t + 1)) - echo_i "checking 'nsdname-wait-recurse no' is faster than 'nsdname-wait-recurse yes' ($t)" - add_test_marker 10.53.0.2 10.53.0.3 - echo_i "timing 'nsdname-wait-recurse yes' (default)" - ret=0 - t1=$($PERL -e 'print time()."\n";') - $DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a >dig.out.yes.$t - t2=$($PERL -e 'print time()."\n";') - p1=$((t2 - t1)) - echo_i "elapsed time $p1 seconds" - - $RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush - copy_setports ns3/named3.conf.in ns3/named.conf - nextpart ns3/named.run >/dev/null - $RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} reload >/dev/null - wait_for_log 20 "rpz: policy: reload done" ns3/named.run || ret=1 - - echo_i "timing 'nsdname-wait-recurse no'" - t3=$($PERL -e 'print time()."\n";') - $DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a >dig.out.no.$t - t4=$($PERL -e 'print time()."\n";') - p2=$((t4 - t3)) - echo_i "elapsed time $p2 seconds" - - if test $p1 -le $p2; then ret=1; fi - if test $ret != 0; then echo_i "failed"; fi - status=$((status + ret)) - - [ $status -ne 0 ] && pf=fail || pf=pass - case $mode in - native) - native=$status - echo_i "status (native RPZ sub-test): $status ($pf)" - ;; - dnsrps) - dnsrps=$status - echo_i "status (DNSRPS sub-test): $status ($pf)" - ;; - *) echo_i "invalid test mode" ;; - esac +# Group 2 +run_server 2a +for n in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \ + 21 22 23 24 25 26 27 28 29 30 31 32; do + expect_norecurse 2a $n done -status=$((native + dnsrps)) +expect_recurse 2a 33 + +# Group 3 +run_server 3a +expect_recurse 3a 1 +run_server 3b +expect_recurse 3b 1 +run_server 3c +expect_recurse 3c 1 +run_server 3d +expect_norecurse 3d 1 +expect_recurse 3d 2 +run_server 3e +expect_norecurse 3e 1 +expect_recurse 3e 2 +run_server 3f +expect_norecurse 3f 1 +expect_recurse 3f 2 + +# Group 4 +testlist="aa ap bf" +values="1 16 32" +# Uncomment the following to test every skip value instead of +# only a sample of values +# +#testlist="aa ab ac ad ae af ag ah ai aj ak al am an ao ap \ +# aq ar as at au av aw ax ay az ba bb bc bd be bf" +#values="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \ +# 21 22 23 24 25 26 27 28 29 30 31 32" +set -- $values +for n in $testlist; do + run_server 4$n + ni=$1 + t=$((t + 1)) + echo_i "testing that ${ni} of 33 queries skip recursion (${t})" + add_test_marker 10.53.0.2 + c=0 + for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 \ + 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33; do + run_query 4$n $i || c=$((c + 1)) + done + skipped=$((33 - c)) + if [ $skipped != $ni ]; then + echo_i "test $t failed (actual=$skipped, expected=$ni)" + status=1 + fi + shift +done + +# Group 5 +run_server 5a +expect_norecurse 5a 1 +expect_norecurse 5a 2 +expect_recurse 5a 3 +expect_recurse 5a 4 +expect_recurse 5a 5 +expect_recurse 5a 6 + +# Group 6 +echo_i "check recursive behavior consistency during policy update races" +run_server 6a +sleep 1 +t=$((t + 1)) +echo_i "running dig to cache CNAME record (${t})" +add_test_marker 10.53.0.1 10.53.0.2 +$DIG $DIGOPTS @10.53.0.2 -p ${PORT} www.test.example.org CNAME >dig.out.${t} +sleep 1 +echo_i "suspending authority server" +PID=$(cat ns1/named.pid) +kill -STOP $PID +echo_i "adding an NSDNAME policy" +cp ns2/db.6a.00.policy.local ns2/saved.policy.local +cp ns2/db.6b.00.policy.local ns2/db.6a.00.policy.local +$RNDC -c ../_common/rndc.conf -s 10.53.0.2 -p ${CONTROLPORT} reload 6a.00.policy.local 2>&1 | sed 's/^/ns2 /' | cat_i +test -f dnsrpzd.pid && kill -USR1 $(cat dnsrpzd.pid) || true +sleep 1 +t=$((t + 1)) +echo_i "running dig to follow CNAME (blocks, so runs in the background) (${t})" +add_test_marker 10.53.0.2 +$DIG $DIGOPTS @10.53.0.2 -p ${PORT} www.test.example.org A +time=5 >dig.out.${t} & +sleep 1 +echo_i "removing the NSDNAME policy" +cp ns2/db.6c.00.policy.local ns2/db.6a.00.policy.local +$RNDC -c ../_common/rndc.conf -s 10.53.0.2 -p ${CONTROLPORT} reload 6a.00.policy.local 2>&1 | sed 's/^/ns2 /' | cat_i +test -f dnsrpzd.pid && kill -USR1 $(cat dnsrpzd.pid) || true +sleep 1 +echo_i "resuming authority server" +PID=$(cat ns1/named.pid) +kill -CONT $PID +add_test_marker 10.53.0.1 +for n in 1 2 3 4 5 6 7 8 9; do + sleep 1 + [ -s dig.out.${t} ] || continue + grep "status: .*," dig.out.${t} >/dev/null 2>&1 && break +done +grep "status: NOERROR" dig.out.${t} >/dev/null 2>&1 || { + echo_i "test ${t} failed" + status=1 +} + +echo_i "check recursive behavior consistency during policy removal races" +cp ns2/saved.policy.local ns2/db.6a.00.policy.local +run_server 6a +sleep 1 +t=$((t + 1)) +echo_i "running dig to cache CNAME record (${t})" +add_test_marker 10.53.0.1 10.53.0.2 +$DIG $DIGOPTS @10.53.0.2 -p ${PORT} www.test.example.org CNAME >dig.out.${t} +sleep 1 +echo_i "suspending authority server" +PID=$(cat ns1/named.pid) +kill -STOP $PID +echo_i "adding an NSDNAME policy" +cp ns2/db.6b.00.policy.local ns2/db.6a.00.policy.local +$RNDC -c ../_common/rndc.conf -s 10.53.0.2 -p ${CONTROLPORT} reload 6a.00.policy.local 2>&1 | sed 's/^/ns2 /' | cat_i +test -f dnsrpzd.pid && kill -USR1 $(cat dnsrpzd.pid) || true +sleep 1 +t=$((t + 1)) +echo_i "running dig to follow CNAME (blocks, so runs in the background) (${t})" +add_test_marker 10.53.0.2 +$DIG $DIGOPTS @10.53.0.2 -p ${PORT} www.test.example.org A +time=5 >dig.out.${t} & +sleep 1 +echo_i "removing the policy zone" +cp ns2/named.default.conf ns2/named.conf +rndc_reconfig ns2 10.53.0.2 +test -f dnsrpzd.pid && kill -USR1 $(cat dnsrpzd.pid) || true +sleep 1 +echo_i "resuming authority server" +PID=$(cat ns1/named.pid) +kill -CONT $PID +add_test_marker 10.53.0.1 +for n in 1 2 3 4 5 6 7 8 9; do + sleep 1 + [ -s dig.out.${t} ] || continue + grep "status: .*," dig.out.${t} >/dev/null 2>&1 && break +done +grep "status: NOERROR" dig.out.${t} >/dev/null 2>&1 || { + echo_i "test ${t} failed" + status=1 +} + +# Check maximum number of RPZ zones (64) +t=$((t + 1)) +echo_i "testing maximum number of RPZ zones (${t})" +add_test_marker 10.53.0.2 +run_server max +i=1 +while test $i -le 64; do + $DIG $DIGOPTS name$i a @10.53.0.2 -p ${PORT} -b 10.53.0.1 >dig.out.${t}.${i} + grep "^name$i.[ ]*[0-9]*[ ]*IN[ ]*A[ ]*10.53.0.$i" dig.out.${t}.${i} >/dev/null 2>&1 || { + echo_i "test $t failed: didn't get expected answer from policy zone $i" + status=1 + } + i=$((i + 1)) +done + +# Check CLIENT-IP behavior +t=$((t + 1)) +echo_i "testing CLIENT-IP behavior (${t})" +add_test_marker 10.53.0.2 +run_server clientip +$DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.4 >dig.out.${t} +grep "status: NOERROR" dig.out.${t} >/dev/null 2>&1 || { + echo_i "test $t failed: query failed" + status=1 +} +grep "^l2.l1.l0.[ ]*[0-9]*[ ]*IN[ ]*A[ ]*10.53.0.2" dig.out.${t} >/dev/null 2>&1 || { + echo_i "test $t failed: didn't get expected answer" + status=1 +} + +# Check CLIENT-IP behavior #2 +t=$((t + 1)) +echo_i "testing CLIENT-IP behavior #2 (${t})" +add_test_marker 10.53.0.2 +run_server clientip2 +$DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.1 >dig.out.${t}.1 +grep "status: SERVFAIL" dig.out.${t}.1 >/dev/null 2>&1 || { + echo_i "test $t failed: query failed" + status=1 +} +$DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.2 >dig.out.${t}.2 +grep "status: NXDOMAIN" dig.out.${t}.2 >/dev/null 2>&1 || { + echo_i "test $t failed: query failed" + status=1 +} +$DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.3 >dig.out.${t}.3 +grep "status: NOERROR" dig.out.${t}.3 >/dev/null 2>&1 || { + echo_i "test $t failed: query failed" + status=1 +} +grep "^l2.l1.l0.[ ]*[0-9]*[ ]*IN[ ]*A[ ]*10.53.0.1" dig.out.${t}.3 >/dev/null 2>&1 || { + echo_i "test $t failed: didn't get expected answer" + status=1 +} +$DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.4 >dig.out.${t}.4 +grep "status: SERVFAIL" dig.out.${t}.4 >/dev/null 2>&1 || { + echo_i "test $t failed: query failed" + status=1 +} + +# Check RPZ log clause +t=$((t + 1)) +echo_i "testing RPZ log clause (${t})" +add_test_marker 10.53.0.2 +run_server log +cur=$(awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run) +$DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.4 >dig.out.${t} +$DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.3 >>dig.out.${t} +$DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p ${PORT} -b 10.53.0.2 >>dig.out.${t} +sed -n "$cur,"'$p' /dev/null && { + echo_ic "failed: unexpected rewrite message for policy zone log1 was logged" + status=1 +} +sed -n "$cur,"'$p' /dev/null || { + echo_ic "failed: expected rewrite message for policy zone log2 was not logged" + status=1 +} +sed -n "$cur,"'$p' /dev/null || { + echo_ic "failed: expected rewrite message for policy zone log3 was not logged" + status=1 +} + +# Check wildcard behavior + +t=$((t + 1)) +echo_i "testing wildcard behavior with 1 RPZ zone (${t})" +add_test_marker 10.53.0.2 +run_server wildcard1 +$DIG $DIGOPTS www.test1.example.net a @10.53.0.2 -p ${PORT} >dig.out.${t}.1 +grep "status: NXDOMAIN" dig.out.${t}.1 >/dev/null || { + echo_i "test ${t} failed" + status=1 +} +$DIG $DIGOPTS test1.example.net a @10.53.0.2 -p ${PORT} >dig.out.${t}.2 +grep "status: NXDOMAIN" dig.out.${t}.2 >/dev/null || { + echo_i "test ${t} failed" + status=1 +} + +t=$((t + 1)) +echo_i "testing wildcard behavior with 2 RPZ zones (${t})" +add_test_marker 10.53.0.2 +run_server wildcard2 +$DIG $DIGOPTS www.test1.example.net a @10.53.0.2 -p ${PORT} >dig.out.${t}.1 +grep "status: NXDOMAIN" dig.out.${t}.1 >/dev/null || { + echo_i "test ${t} failed" + status=1 +} +$DIG $DIGOPTS test1.example.net a @10.53.0.2 -p ${PORT} >dig.out.${t}.2 +grep "status: NXDOMAIN" dig.out.${t}.2 >/dev/null || { + echo_i "test ${t} failed" + status=1 +} + +t=$((t + 1)) +echo_i "testing wildcard behavior with 1 RPZ zone and no non-wildcard triggers (${t})" +add_test_marker 10.53.0.2 +run_server wildcard3 +$DIG $DIGOPTS www.test1.example.net a @10.53.0.2 -p ${PORT} >dig.out.${t}.1 +grep "status: NXDOMAIN" dig.out.${t}.1 >/dev/null || { + echo_i "test ${t} failed" + status=1 +} +$DIG $DIGOPTS test1.example.net a @10.53.0.2 -p ${PORT} >dig.out.${t}.2 +grep "status: NOERROR" dig.out.${t}.2 >/dev/null || { + echo_i "test ${t} failed" + status=1 +} + +t=$((t + 1)) +echo_i "testing wildcard passthru before explicit drop (${t})" +add_test_marker 10.53.0.2 +run_server wildcard4 +$DIG $DIGOPTS example.com a @10.53.0.2 -p ${PORT} >dig.out.${t}.1 +grep "status: NOERROR" dig.out.${t}.1 >/dev/null || { + echo_i "test ${t} failed" + status=1 +} +$DIG $DIGOPTS www.example.com a @10.53.0.2 -p ${PORT} >dig.out.${t}.2 +grep "status: NOERROR" dig.out.${t}.2 >/dev/null || { + echo_i "test ${t} failed" + status=1 +} + +if [ "$MODE" = "native" ]; then + # Check for invalid prefix length error + t=$((t + 1)) + echo_i "testing for invalid prefix length error (${t})" + add_test_marker 10.53.0.2 + run_server invalidprefixlength + grep "invalid rpz IP address \"1000.4.0.53.10.rpz-client-ip.invalidprefixlength\"; invalid prefix length of 1000$" ns2/named.run >/dev/null || { + echo_ic "failed: expected that invalid prefix length error would be logged" + status=1 + } +fi + +t=$((t + 1)) +echo_i "checking 'nsip-wait-recurse no' is faster than 'nsip-wait-recurse yes' ($t)" +add_test_marker 10.53.0.2 10.53.0.3 +echo_i "timing 'nsip-wait-recurse yes' (default)" +ret=0 +t1=$($PERL -e 'print time()."\n";') +$DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a >dig.out.yes.$t +t2=$($PERL -e 'print time()."\n";') +p1=$((t2 - t1)) +echo_i "elapsed time $p1 seconds" + +$RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush +copy_setports ns3/named2.conf.in ns3/named.conf +nextpart ns3/named.run >/dev/null +$RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} reload >/dev/null +wait_for_log 20 "rpz: policy: reload done" ns3/named.run || ret=1 + +echo_i "timing 'nsip-wait-recurse no'" +t3=$($PERL -e 'print time()."\n";') +$DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a >dig.out.no.$t +t4=$($PERL -e 'print time()."\n";') +p2=$((t4 - t3)) +echo_i "elapsed time $p2 seconds" + +if test $p1 -le $p2; then ret=1; fi +if test $ret != 0; then echo_i "failed"; fi +status=$((status + ret)) + +$RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush +# restore original named.conf +copy_setports ns3/named1.conf.in ns3/named.conf +nextpart ns3/named.run >/dev/null +$RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} reload >/dev/null +wait_for_log 20 "rpz: policy: reload done" ns3/named.run || ret=1 + +t=$((t + 1)) +echo_i "checking 'nsdname-wait-recurse no' is faster than 'nsdname-wait-recurse yes' ($t)" +add_test_marker 10.53.0.2 10.53.0.3 +echo_i "timing 'nsdname-wait-recurse yes' (default)" +ret=0 +t1=$($PERL -e 'print time()."\n";') +$DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a >dig.out.yes.$t +t2=$($PERL -e 'print time()."\n";') +p1=$((t2 - t1)) +echo_i "elapsed time $p1 seconds" + +$RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush +copy_setports ns3/named3.conf.in ns3/named.conf +nextpart ns3/named.run >/dev/null +$RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} reload >/dev/null +wait_for_log 20 "rpz: policy: reload done" ns3/named.run || ret=1 + +echo_i "timing 'nsdname-wait-recurse no'" +t3=$($PERL -e 'print time()."\n";') +$DIG -p ${PORT} @10.53.0.3 foo.child.example.tld a >dig.out.no.$t +t4=$($PERL -e 'print time()."\n";') +p2=$((t4 - t3)) +echo_i "elapsed time $p2 seconds" + +if test $p1 -le $p2; then ret=1; fi +if test $ret != 0; then echo_i "failed"; fi +status=$((status + ret)) [ $status -eq 0 ] || exit 1 diff --git a/bin/tests/system/rpzrecurse/tests_sh_rpzrecurse_dnsrps.py b/bin/tests/system/rpzrecurse/tests_sh_rpzrecurse_dnsrps.py new file mode 100644 index 0000000000..0d897ebce9 --- /dev/null +++ b/bin/tests/system/rpzrecurse/tests_sh_rpzrecurse_dnsrps.py @@ -0,0 +1,20 @@ +# Copyright (C) Internet Systems Consortium, Inc. ("ISC") +# +# SPDX-License-Identifier: MPL-2.0 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, you can obtain one at https://mozilla.org/MPL/2.0/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +import isctest.mark + +pytestmark = isctest.mark.dnsrps_enabled + + +def test_rpzrecurse_dnsrps(run_tests_sh): + with open("dnsrps.conf", "w", encoding="utf-8") as conf: + conf.writelines(["dnsrps-enable yes;"]) + run_tests_sh() From cd6c9590f1081fd8bcb277ac246b07d4b8988341 Mon Sep 17 00:00:00 2001 From: Tom Krizek Date: Wed, 25 Oct 2023 14:10:18 +0200 Subject: [PATCH 2/3] Remove obsolete ckdnsrps.sh script As dnsrps and native test cases have been properly split up, the ckdnsrps.sh script is no longer used anywhere, as the logic for selecting these test cases is handled by pytest. (cherry picked from commit b1d71c4d263ee2756ae05d1c1f11fd9cd4919e30) --- bin/tests/system/ckdnsrps.sh | 172 ------------------------------ bin/tests/system/legacy.run.sh.in | 2 +- 2 files changed, 1 insertion(+), 173 deletions(-) delete mode 100644 bin/tests/system/ckdnsrps.sh diff --git a/bin/tests/system/ckdnsrps.sh b/bin/tests/system/ckdnsrps.sh deleted file mode 100644 index 19eb0546f1..0000000000 --- a/bin/tests/system/ckdnsrps.sh +++ /dev/null @@ -1,172 +0,0 @@ -#!/bin/sh - -# Copyright (C) Internet Systems Consortium, Inc. ("ISC") -# -# SPDX-License-Identifier: MPL-2.0 -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, you can obtain one at https://mozilla.org/MPL/2.0/. -# -# See the COPYRIGHT file distributed with this work for additional -# information regarding copyright ownership. - -set -e - -# Say on stdout whether to test DNSRPS -# and create dnsrps.conf and dnsrps-secondary.conf -# Note that dnsrps.conf and dnsrps-secondary.conf are included in named.conf -# and differ from dnsrpz.conf which is used by dnsrpzd. - -. ../conf.sh - -DNSRPS_CMD=../rpz/dnsrps - -AS_NS= -TEST_DNSRPS= -MCONF=dnsrps.conf -SCONF=dnsrps-secondary.conf -USAGE="$0: [-xAD] [-M dnsrps.conf] [-S dnsrps-secondary.conf]" -while getopts "xADM:S:" c; do - case $c in - x) - set -x - DEBUG=-x - ;; - A) AS_NS=yes ;; - D) TEST_DNSRPS=yes ;; - M) MCONF="$OPTARG" ;; - S) SCONF="$OPTARG" ;; - *) - echo "$USAGE" 1>&2 - exit 1 - ;; - esac -done -shift $(expr $OPTIND - 1 || true) -if [ "$#" -ne 0 ]; then - echo "$USAGE" 1>&2 - exit 1 -fi - -# erase any existing conf files -cat /dev/null >$MCONF -cat /dev/null >$SCONF - -add_conf() { - echo "$*" >>$MCONF - echo "$*" >>$SCONF -} - -if ! $FEATURETEST --enable-dnsrps; then - if [ -n "$TEST_DNSRPS" ]; then - add_conf "## DNSRPS disabled at compile time" - fi - add_conf "#skip" - exit 0 -fi - -if [ -z "$TEST_DNSRPS" ]; then - add_conf "## testing with native RPZ" - add_conf '#skip' - exit 0 -else - add_conf "## testing with DNSRPS" -fi - -if [ ! -x "$DNSRPS_CMD" ]; then - add_conf "## make $DNSRPS_CMD to test DNSRPS" - add_conf '#skip' - exit 0 -fi - -if $DNSRPS_CMD -a >/dev/null; then - : -else - add_conf "## DNSRPS provider library is not available" - add_conf '#skip' - exit 0 -fi - -CMN=" dnsrps-options { dnsrpzd-conf ../dnsrpzd.conf - dnsrpzd-sock ../dnsrpzd.sock - dnsrpzd-rpzf ../dnsrpzd.rpzf - dnsrpzd-args '-dddd -L stdout' - log-level 3" - -PRIMARY="$CMN" -if [ -n "$AS_NS" ]; then - PRIMARY="$PRIMARY - qname-as-ns yes - ip-as-ns yes" -fi - -# write dnsrps settings for primary resolver -cat <>$MCONF -$PRIMARY }; -EOF - -# write dnsrps settings for resolvers that should not start dnsrpzd -cat <>$SCONF -$CMN - dnsrpzd '' }; # do not start dnsrpzd -EOF - -# DNSRPS is available. -# The test should fail if the license is bad. -add_conf "dnsrps-enable yes;" - -# Use alt-dnsrpzd-license.conf if it exists -CUR_L=dnsrpzd-license-cur.conf -ALT_L=alt-dnsrpzd-license.conf -# try ../rpz/alt-dnsrpzd-license.conf if alt-dnsrpzd-license.conf does not exist -[ -s $ALT_L ] || ALT_L=../rpz/alt-dnsrpzd-license.conf -if [ -s $ALT_L ]; then - SRC_L=$ALT_L - USE_ALT= -else - SRC_L=../rpz/dnsrpzd-license.conf - USE_ALT="## consider installing alt-dnsrpzd-license.conf" -fi -cp $SRC_L $CUR_L - -# parse $CUR_L for the license zone name, primary IP addresses, and optional -# transfer-source IP addresses -eval $(sed -n -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/' \ - -e 's/.*zone *\([-a-z0-9]*.license.fastrpz.com\).*/NAME=\1/p' \ - -e 's/.*farsight_fastrpz_license *\([0-9.]*\);.*/IPV4=\1/p' \ - -e 's/.*farsight_fastrpz_license *\([0-9a-f:]*\);.*/IPV6=\1/p' \ - -e 's/.*transfer-source *\([0-9.]*\);.*/TS4=-b\1/p' \ - -e 's/.*transfer-source *\([0-9a-f:]*\);.*/TS6=-b\1/p' \ - -e 's/.*transfer-source-v6 *\([0-9a-f:]*\);.*/TS6=-b\1/p' \ - $CUR_L) -if [ -z "$NAME" ]; then - add_conf "## no DNSRPS tests; no license domain name in $SRC_L" - add_conf '#fail' - exit 0 -fi -if [ -z "$IPV4" ]; then - IPV4=license1.fastrpz.com - TS4= -fi -if [ -z "$IPV6" ]; then - IPV6=license1.fastrpz.com - TS6= -fi - -# This TSIG key is common and NOT a secret -KEY='hmac-sha256:farsight_fastrpz_license:f405d02b4c8af54855fcebc1' - -# Try IPv4 and then IPv6 to deal with IPv6 tunnel and connectivity problems -if $($DIG -4 -t axfr -y$KEY $TS4 $NAME @$IPV4 \ - | grep -i "^$NAME.*TXT" >/dev/null); then - exit 0 -fi -if $($DIG -6 -t axfr -y$KEY $TS6 $NAME @$IPV6 \ - | grep -i "^$NAME.*TXT" >/dev/null); then - exit 0 -fi - -add_conf "## DNSRPS lacks a valid license via $SRC_L" -[ -z "$USE_ALT" ] || add_conf "$USE_ALT" -add_conf '#fail' diff --git a/bin/tests/system/legacy.run.sh.in b/bin/tests/system/legacy.run.sh.in index 2004615c5f..8bab66f3b8 100644 --- a/bin/tests/system/legacy.run.sh.in +++ b/bin/tests/system/legacy.run.sh.in @@ -87,7 +87,7 @@ if [ "${srcdir}" != "${builddir}" ]; then cp -a "${srcdir}/_common" "${builddir}" fi # Some tests require additional files to work for out-of-tree test runs. - for file in ckdnsrps.sh conftest.py digcomp.pl ditch.pl fromhex.pl get_core_dumps.sh kasp.sh packet.pl start.pl stop.pl testcrypto.sh; do + for file in conftest.py digcomp.pl ditch.pl fromhex.pl get_core_dumps.sh kasp.sh packet.pl start.pl stop.pl testcrypto.sh; do if [ ! -r "${file}" ]; then cp -a "${srcdir}/${file}" "${builddir}" fi From 575728dee873eed22af886ea13979c7b6aeba1dc Mon Sep 17 00:00:00 2001 From: Tom Krizek Date: Thu, 18 Jan 2024 16:47:08 +0100 Subject: [PATCH 3/3] Remove extraneous dnsrps-secondary.conf from rpz tests The contents of the dnsrps-secondary.conf file are identical to the contents of dnsrps.conf. Remove it since it's redundant. --- bin/tests/system/rpz/ns5/named.conf.in | 2 +- bin/tests/system/rpz/ns6/named.conf.in | 2 +- bin/tests/system/rpz/ns7/named.conf.in | 2 +- bin/tests/system/rpzrecurse/.gitignore | 1 - bin/tests/system/rpzrecurse/ns2/named.conf.header.in | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/bin/tests/system/rpz/ns5/named.conf.in b/bin/tests/system/rpz/ns5/named.conf.in index e1f8fb6056..58b591b70d 100644 --- a/bin/tests/system/rpz/ns5/named.conf.in +++ b/bin/tests/system/rpz/ns5/named.conf.in @@ -35,7 +35,7 @@ options { # turn rpz on or off include "rpz-switch"; - include "../dnsrps-secondary.conf"; + include "../dnsrps.conf"; }; key rndc_key { diff --git a/bin/tests/system/rpz/ns6/named.conf.in b/bin/tests/system/rpz/ns6/named.conf.in index c0ad5c4237..66832eed48 100644 --- a/bin/tests/system/rpz/ns6/named.conf.in +++ b/bin/tests/system/rpz/ns6/named.conf.in @@ -36,7 +36,7 @@ options { nsip-enable yes nsdname-enable yes; - include "../dnsrps-secondary.conf"; + include "../dnsrps.conf"; }; logging { category rpz { default_debug; }; }; diff --git a/bin/tests/system/rpz/ns7/named.conf.in b/bin/tests/system/rpz/ns7/named.conf.in index 7effd3db41..3f5265751a 100644 --- a/bin/tests/system/rpz/ns7/named.conf.in +++ b/bin/tests/system/rpz/ns7/named.conf.in @@ -32,7 +32,7 @@ options { nsdname-enable yes min-update-interval 0; - include "../dnsrps-secondary.conf"; + include "../dnsrps.conf"; }; logging { category rpz { default_debug; }; }; diff --git a/bin/tests/system/rpzrecurse/.gitignore b/bin/tests/system/rpzrecurse/.gitignore index 5d4371d852..b58ca75d82 100644 --- a/bin/tests/system/rpzrecurse/.gitignore +++ b/bin/tests/system/rpzrecurse/.gitignore @@ -5,7 +5,6 @@ /ns3/named2.conf /ns4/named.conf /ans5/ans.pid -/dnsrps-secondary.conf /dnsrps.conf /dnsrpzd.conf session.key diff --git a/bin/tests/system/rpzrecurse/ns2/named.conf.header.in b/bin/tests/system/rpzrecurse/ns2/named.conf.header.in index 2fb16788aa..90a17b7a37 100644 --- a/bin/tests/system/rpzrecurse/ns2/named.conf.header.in +++ b/bin/tests/system/rpzrecurse/ns2/named.conf.header.in @@ -27,7 +27,7 @@ options { querylog yes; # let ns3 start dnsrpzd - include "../dnsrps-secondary.conf"; + include "../dnsrps.conf"; }; key rndc_key {