[master] rpz work

3620.	[func]		Added "rpz-client-ip" policy triggers, enabling
			RPZ responses to be configured on the basis of
			the client IP address; this can be used, for
			example, to blacklist misbehaving recursive
			or stub resolvers. [RT #33605]

3619.	[bug]		Fixed a bug in RPZ with "recursive-only no;"
			[RT #33776]
This commit is contained in:
Evan Hunt
2013-07-12 14:46:47 -07:00
parent 0b4ed61d20
commit 421d4a0647
17 changed files with 992 additions and 496 deletions

View File

@@ -22,15 +22,14 @@ SYSTEMTESTTOP=..
ns=10.53.0
ns1=$ns.1 # root, defining the others
ns2=$ns.2 # authoritative server whose answers are rewritten
ns3=$ns.3 # resolver that does the rewriting
ns2=$ns.2 # authoritative server whose records are rewritten
ns3=$ns.3 # main rewriting resolver
ns4=$ns.4 # another authoritative server that is rewritten
ns5=$ns.5 # resolver to check performance and give un-rewritten
# responses for comparisons
ns5=$ns.5 # another rewriting resolver
HAVE_CORE=
SAVE_RESULTS=
NS3_STATS=47
USAGE="$0: [-x]"
while getopts "x" c; do
@@ -58,11 +57,16 @@ comment () {
RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s"
digcmd () {
digcmd_args="+noadd +time=1 +tries=1 -p 5300 $*"
expr "$digcmd_args" : '.*@' >/dev/null || \
digcmd_args="$digcmd_args @$ns3"
expr "$digcmd_args" : '.*+[no]*auth' >/dev/null || \
digcmd_args="+noauth $digcmd_args"
if test "$1" = TCP; then
shift
fi
# Default to +noauth and @$ns3
# Also default to -bX where X is the @value so that OS X will choose
# the right IP source address.
digcmd_args=`echo "+noadd +time=1 +tries=1 -p 5300 $*" | \
sed -e "/@/!s/.*/& @$ns3/" \
-e '/-b/!s/@\([^ ]*\)/@\1 -b\1/' \
-e '/+n?o?auth/!s/.*/+noauth &/'`
#echo I:dig $digcmd_args 1>&2
$DIG $digcmd_args
}
@@ -88,10 +92,13 @@ setret () {
# (re)load the reponse policy zones with the rules in the file $TEST_FILE
load_db () {
if test -n "$TEST_FILE"; then
$NSUPDATE -v $TEST_FILE || {
if $NSUPDATE -v $TEST_FILE; then :
$RNDCCMD $ns3 sync
else
echo "I:failed to update policy zone with $TEST_FILE"
$RNDCCMD $ns3 sync
exit 1
}
fi
fi
}
@@ -134,15 +141,20 @@ ckalive () {
return 1
}
# check that statistics for $1 in $2 = $3
ckstats () {
$RNDCCMD $1 stats
CNT=`sed -n -e 's/[ ]*\([0-9]*\).response policy.*/\1/p' \
$2/named.stats`
CNT=`expr 0$CNT + 0`
if test "$CNT" -ne $3; then
setret "I:wrong $2 statistics of $CNT instead of $3"
HOST=$1
LABEL="$2"
NSDIR="$3"
EXPECTED="$4"
$RNDCCMD $HOST stats
NEW_CNT=0`sed -n -e 's/[ ]*\([0-9]*\).response policy.*/\1/p' \
$NSDIR/named.stats | tail -1`
eval "OLD_CNT=0\$${NSDIR}_CNT"
GOT=`expr $NEW_CNT - $OLD_CNT`
if test "$GOT" -ne "$EXPECTED"; then
setret "I:wrong $LABEL $NSDIR statistics of $GOT instead of $EXPECTED"
fi
eval "${NSDIR}_CNT=$NEW_CNT"
}
# $1=message $2=optional test file name
@@ -179,6 +191,12 @@ clean_result () {
ckresult () {
#ckalive "$1" "I:server crashed by 'dig $1'" || return 1
if $PERL $SYSTEMTESTTOP/digcomp.pl $DIGNM $2 >/dev/null; then
NEED_TCP=`echo "$1" | sed -n -e 's/[Tt][Cc][Pp].*/TCP/p'`
RESULT_TCP=`sed -n -e 's/.*Truncated, retrying in TCP.*/TCP/p' $DIGNM`
if test "$NEED_TCP" != "$RESULT_TCP"; then
setret "I:'dig $1' wrong; no or unexpected truncation in $DIGNM"
return 1
fi
clean_result ${DIGNM}*
return 0
fi
@@ -235,12 +253,14 @@ addr () {
clean_result ${DIGNM}*
}
# check that a response is not rewritten
# $1=target domain $2=optional query type
# Check that a response is not rewritten
# Use $ns1 instead of the authority for most test domains, $ns2 to prevent
# spurious differences for `dig +norecurse`
# $1=optional "TCP" remaining args for dig
nochange () {
make_dignm
digcmd $* >$DIGNM
digcmd $* @$ns5 >${DIGNM}_OK
digcmd $* @$ns1 >${DIGNM}_OK
ckresult "$*" ${DIGNM}_OK && clean_result ${DIGNM}_OK
}
@@ -252,6 +272,20 @@ here () {
ckresult "$*" ${DIGNM}_OK
}
# check dropped response
DROPPED='^;; connection timed out; no servers could be reached'
drop () {
make_dignm
digcmd $* >$DIGNM
if grep "$DROPPED" $DIGNM >/dev/null; then
clean_result ${DIGNM}*
return 0
fi
setret "I:'dig $1' wrong; response in $DIGNM"
return 1
}
# make prototype files to check against rewritten results
digcmd nonexistent @$ns2 >proto.nxdomain
digcmd txt-only.tld2 @$ns2 >proto.nodata
@@ -291,7 +325,15 @@ 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 # 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
start_group "IP rewrites" test2
nodata a3-1.tld2 # 1 NODATA
@@ -310,7 +352,9 @@ 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
end_group
ckstats $ns3 test2 ns3 10
# check that IP addresses for previous group were deleted from the radix tree
start_group "radix tree deletions"
@@ -326,6 +370,7 @@ 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
if ./rpz nsdname; then
# these tests assume "min-ns-dots 0"
@@ -343,7 +388,7 @@ if ./rpz nsdname; then
addr 127.0.0.2 a3-1.subsub.sub3.tld2
nxdomain xxx.crash1.tld2 # 12 dns_db_detachnode() crash
end_group
NS3_STATS=`expr $NS3_STATS + 7`
ckstats $ns3 test3 ns3 7
else
echo "I:NSDNAME not checked; named configured with --disable-rpz-nsdname"
fi
@@ -365,7 +410,7 @@ if ./rpz nsip; then
a3-1.tld2. x IN TXT "NSIP walled garden"
EOF
end_group
NS3_STATS=`expr $NS3_STATS + 4`
ckstats $ns3 test4 ns3 4
else
echo "I:NSIP not checked; named configured with --disable-rpz-nsip"
fi
@@ -377,12 +422,12 @@ 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
nodata a3-5.tld2 +norecurse # 6 bl-nodata recursive-only no
nodata a3-5.tld2 # 7 bl-nodata
nodata a3-5.tld2 +norecurse @$ns5 # 8 bl-nodata recursive-only no
nodata a3-5.tld2s @$ns5 # 9 bl-nodata
nodata a3-5.tld2s +dnssec @$ns5 # 10 bl-nodata break-dnssec
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'
;; status: NOERROR, x
@@ -394,10 +439,15 @@ 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 # 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"
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
@@ -411,6 +461,8 @@ done
# resolving foo.
# nxdomain 32.3.2.1.127.rpz-ip
end_group
ckstats $ns3 bugs ns3 8
# superficial test for major performance bugs
@@ -423,6 +475,7 @@ if test -n "$QPERF"; then
$QPERF -c -1 -l30 -d ns5/requests -s $ns5 -p 5300 >/dev/null
comment "before real test $1"
PFILE="ns5/$2.perf"
$RNDCCMD $ns5 notrace
$QPERF -c -1 -l30 -d ns5/requests -s $ns5 -p 5300 >$PFILE
comment "after test $1"
X=`sed -n -e 's/.*Returned *\([^ ]*:\) *\([0-9]*\) .*/\1\2/p' $PFILE \
@@ -437,17 +490,17 @@ if test -n "$QPERF"; then
}
# get qps with rpz
perf 'with rpz' rpz 'NOERROR:2900 NXDOMAIN:100 '
perf 'with RPZ' rpz 'NOERROR:2900 NXDOMAIN:100 '
RPZ=`trim rpz`
# turn off rpz and measure qps again
echo "# rpz off" >ns5/rpz-switch
echo "# RPZ off" >ns5/rpz-switch
RNDCCMD_OUT=`$RNDCCMD $ns5 reload`
perf 'without rpz' norpz 'NOERROR:3000 '
perf 'without RPZ' norpz 'NOERROR:3000 '
NORPZ=`trim norpz`
PERCENT=`expr \( "$RPZ" \* 100 + \( $NORPZ / 2 \) \) / $NORPZ`
echo "I:$RPZ qps with rpz is $PERCENT% of $NORPZ qps without rpz"
echo "I:$RPZ qps with RPZ is $PERCENT% of $NORPZ qps without RPZ"
MIN_PERCENT=30
if test "$PERCENT" -lt $MIN_PERCENT; then
@@ -458,15 +511,13 @@ if test -n "$QPERF"; then
setret "I:$RPZ qps with RPZ or $PERCENT% of $NORPZ qps without RPZ is too high"
fi
ckstats $ns5 ns5 203
ckstats $ns5 performance ns5 200
else
echo "I:performance not checked; queryperf not available"
fi
ckstats $ns3 ns3 $NS3_STATS
# restart the main test RPZ server to see if that creates a core file
if test -z "$HAVE_CORE"; then
$PERL $SYSTEMTESTTOP/stop.pl . ns3