2022-08-02 15:01:01 +02:00
|
|
|
#!/bin/sh
|
|
|
|
|
2018-02-22 15:10:37 -08:00
|
|
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
2013-02-25 10:49:30 -08:00
|
|
|
#
|
|
|
|
# SPDX-License-Identifier: MPL-2.0
|
2021-06-03 08:37:05 +02:00
|
|
|
#
|
2013-02-25 10:49:30 -08:00
|
|
|
# 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/.
|
2018-02-23 09:53:12 +01:00
|
|
|
#
|
2013-02-25 10:49:30 -08:00
|
|
|
# See the COPYRIGHT file distributed with this work for additional
|
2013-06-08 13:17:33 -07:00
|
|
|
# information regarding copyright ownership.
|
2013-02-25 10:49:30 -08:00
|
|
|
|
|
|
|
# test response rate limiting
|
|
|
|
|
2020-07-21 12:12:59 +02:00
|
|
|
. ../conf.sh
|
2013-02-25 10:49:30 -08:00
|
|
|
|
2020-07-21 12:12:59 +02:00
|
|
|
RNDCCMD="$RNDC -c ../common/rndc.conf -p ${CONTROLPORT} -s"
|
2018-02-20 15:43:27 -08:00
|
|
|
|
2013-02-25 10:49:30 -08:00
|
|
|
#set -x
|
|
|
|
|
|
|
|
ns1=10.53.0.1 # root, defining the others
|
|
|
|
ns2=10.53.0.2 # test server
|
|
|
|
ns3=10.53.0.3 # secondary test server
|
2016-01-11 19:37:17 -08:00
|
|
|
ns4=10.53.0.4 # log-only test server
|
2013-02-25 10:49:30 -08:00
|
|
|
ns7=10.53.0.7 # whitelisted client
|
|
|
|
|
|
|
|
USAGE="$0: [-x]"
|
|
|
|
while getopts "x" c; do
|
|
|
|
case $c in
|
|
|
|
x) set -x;;
|
|
|
|
*) echo "$USAGE" 1>&2; exit 1;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
shift `expr $OPTIND - 1 || true`
|
|
|
|
if test "$#" -ne 0; then
|
|
|
|
echo "$USAGE" 1>&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
# really quit on control-C
|
|
|
|
trap 'exit 1' 1 2 15
|
|
|
|
|
|
|
|
|
|
|
|
ret=0
|
|
|
|
setret () {
|
|
|
|
ret=1
|
2018-02-20 15:43:27 -08:00
|
|
|
echo_i "$*"
|
2013-02-25 10:49:30 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Wait until soon after the start of a second to make results consistent.
|
|
|
|
# The start of a second credits a rate limit.
|
|
|
|
# This would be far easier in C or by assuming a modern version of perl.
|
|
|
|
sec_start () {
|
|
|
|
START=`date`
|
|
|
|
while true; do
|
|
|
|
NOW=`date`
|
|
|
|
if test "$START" != "$NOW"; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
$PERL -e 'select(undef, undef, undef, 0.05)' || true
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-25 14:40:32 -07:00
|
|
|
# turn off ${HOME}/.digrc
|
|
|
|
HOME=/dev/null; export HOME
|
|
|
|
|
2013-02-25 10:49:30 -08:00
|
|
|
# $1=number of tests $2=target domain $3=dig options
|
2013-06-08 13:17:33 -07:00
|
|
|
QNUM=1
|
2013-02-25 10:49:30 -08:00
|
|
|
burst () {
|
|
|
|
BURST_LIMIT=$1; shift
|
|
|
|
BURST_DOM_BASE="$1"; shift
|
2016-11-02 20:56:02 -07:00
|
|
|
|
|
|
|
XCNT=$CNT
|
|
|
|
CNT='XXX'
|
|
|
|
eval FILENAME="mdig.out-$BURST_DOM_BASE"
|
|
|
|
CNT=$XCNT
|
|
|
|
|
|
|
|
DOMS=""
|
2015-12-14 21:27:49 -08:00
|
|
|
CNTS=`$PERL -e 'for ( $i = 0; $i < '$BURST_LIMIT'; $i++) { printf "%03d\n", '$QNUM' + $i; }'`
|
|
|
|
for CNT in $CNTS
|
|
|
|
do
|
2016-01-11 19:37:17 -08:00
|
|
|
eval BURST_DOM="$BURST_DOM_BASE"
|
2016-11-02 20:56:02 -07:00
|
|
|
DOMS="$DOMS $BURST_DOM"
|
2013-02-25 10:49:30 -08:00
|
|
|
done
|
2020-09-16 12:40:52 +10:00
|
|
|
ARGS="+burst +nocookie +continue +time=1 +tries=1 -p ${PORT} $* @$ns2 $DOMS"
|
2019-01-24 10:11:25 -08:00
|
|
|
$MDIG $ARGS 2>&1 | \
|
|
|
|
tee -a full-$FILENAME | \
|
|
|
|
sed -n -e '/^;; AUTHORITY/,/^$/d' \
|
2016-11-02 20:56:02 -07:00
|
|
|
-e '/^;; ADDITIONAL/,/^$/d' \
|
|
|
|
-e 's/^[^;].* \([^ ]\{1,\}\)$/\1/p' \
|
|
|
|
-e 's/;; flags.* tc .*/TC/p' \
|
|
|
|
-e 's/;; .* status: NXDOMAIN.*/NXDOMAIN/p' \
|
|
|
|
-e 's/;; .* status: NOERROR.*/NOERROR/p' \
|
|
|
|
-e 's/;; .* status: SERVFAIL.*/SERVFAIL/p' \
|
|
|
|
-e 's/response failed with timed out.*/drop/p' \
|
2020-09-16 12:40:52 +10:00
|
|
|
-e 's/;; communications error to.*/drop/p' >> $FILENAME &
|
2015-12-14 21:27:49 -08:00
|
|
|
QNUM=`expr $QNUM + $BURST_LIMIT`
|
2013-02-25 10:49:30 -08:00
|
|
|
}
|
|
|
|
|
2016-01-11 19:37:17 -08:00
|
|
|
# compare integers $1 and $2; ensure the difference is no more than $3
|
|
|
|
range () {
|
2016-01-15 14:35:12 -08:00
|
|
|
$PERL -e 'if (abs(int($ARGV[0]) - int($ARGV[1])) > int($ARGV[2])) { exit(1) }' $1 $2 $3
|
2016-01-11 19:37:17 -08:00
|
|
|
}
|
2013-02-25 10:49:30 -08:00
|
|
|
|
|
|
|
# $1=domain $2=IP address $3=# of IP addresses $4=TC $5=drop
|
|
|
|
# $6=NXDOMAIN $7=SERVFAIL or other errors
|
|
|
|
ck_result() {
|
2020-09-16 12:40:52 +10:00
|
|
|
# wait to the background mdig calls to complete.
|
|
|
|
wait
|
2016-11-02 20:56:02 -07:00
|
|
|
BAD=no
|
2022-09-16 12:13:52 +02:00
|
|
|
ADDRS=`grep -E "^$2$" mdig.out-$1 2>/dev/null | wc -l`
|
2013-06-08 13:17:33 -07:00
|
|
|
# count simple truncated and truncated NXDOMAIN as TC
|
2022-09-16 12:13:52 +02:00
|
|
|
TC=`grep -E "^TC|NXDOMAINTC$" mdig.out-$1 2>/dev/null | wc -l`
|
|
|
|
DROP=`grep -E "^drop$" mdig.out-$1 2>/dev/null | wc -l`
|
2013-06-08 13:17:33 -07:00
|
|
|
# count NXDOMAIN and truncated NXDOMAIN as NXDOMAIN
|
2022-09-16 12:13:52 +02:00
|
|
|
NXDOMAIN=`grep -E "^NXDOMAIN|NXDOMAINTC$" mdig.out-$1 2>/dev/null | wc -l`
|
|
|
|
SERVFAIL=`grep -E "^SERVFAIL$" mdig.out-$1 2>/dev/null | wc -l`
|
|
|
|
NOERROR=`grep -E "^NOERROR$" mdig.out-$1 2>/dev/null | wc -l`
|
2023-06-07 16:00:00 +02:00
|
|
|
|
2016-01-11 19:37:17 -08:00
|
|
|
range $ADDRS "$3" 1 ||
|
2018-02-20 15:43:27 -08:00
|
|
|
setret "$ADDRS instead of $3 '$2' responses for $1" &&
|
2016-01-11 19:37:17 -08:00
|
|
|
BAD=yes
|
2023-06-07 16:00:00 +02:00
|
|
|
|
2016-01-11 19:37:17 -08:00
|
|
|
range $TC "$4" 1 ||
|
2018-02-20 15:43:27 -08:00
|
|
|
setret "$TC instead of $4 truncation responses for $1" &&
|
2016-01-11 19:37:17 -08:00
|
|
|
BAD=yes
|
2023-06-07 16:00:00 +02:00
|
|
|
|
2016-01-11 19:37:17 -08:00
|
|
|
range $DROP "$5" 1 ||
|
2018-02-20 15:43:27 -08:00
|
|
|
setret "$DROP instead of $5 dropped responses for $1" &&
|
2016-01-11 19:37:17 -08:00
|
|
|
BAD=yes
|
2023-06-07 16:00:00 +02:00
|
|
|
|
2016-01-11 19:37:17 -08:00
|
|
|
range $NXDOMAIN "$6" 1 ||
|
2018-02-20 15:43:27 -08:00
|
|
|
setret "$NXDOMAIN instead of $6 NXDOMAIN responses for $1" &&
|
2016-01-11 19:37:17 -08:00
|
|
|
BAD=yes
|
2023-06-07 16:00:00 +02:00
|
|
|
|
2016-01-11 19:37:17 -08:00
|
|
|
range $SERVFAIL "$7" 1 ||
|
2018-02-20 15:43:27 -08:00
|
|
|
setret "$SERVFAIL instead of $7 error responses for $1" &&
|
2016-01-11 19:37:17 -08:00
|
|
|
BAD=yes
|
2016-11-02 20:56:02 -07:00
|
|
|
|
|
|
|
range $NOERROR "$8" 1 ||
|
2018-02-20 15:43:27 -08:00
|
|
|
setret "$NOERROR instead of $8 NOERROR responses for $1" &&
|
2016-11-02 20:56:02 -07:00
|
|
|
BAD=yes
|
2023-06-07 16:00:00 +02:00
|
|
|
|
2013-02-25 10:49:30 -08:00
|
|
|
if test -z "$BAD"; then
|
2016-11-02 20:56:02 -07:00
|
|
|
rm -f mdig.out-$1
|
2013-02-25 10:49:30 -08:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-04-25 14:40:32 -07:00
|
|
|
ckstats () {
|
|
|
|
LABEL="$1"; shift
|
|
|
|
TYPE="$1"; shift
|
|
|
|
EXPECTED="$1"; shift
|
2021-10-15 00:05:36 -07:00
|
|
|
C=`cat ns2/named.stats |
|
2019-01-24 10:11:25 -08:00
|
|
|
sed -n -e "s/[ ]*\([0-9]*\).responses $TYPE for rate limits.*/\1/p" |
|
|
|
|
tail -1`
|
2013-06-08 13:17:33 -07:00
|
|
|
C=`expr 0$C + 0`
|
2023-06-07 16:00:00 +02:00
|
|
|
|
2016-01-11 19:37:17 -08:00
|
|
|
range "$C" $EXPECTED 1 ||
|
2018-02-20 15:43:27 -08:00
|
|
|
setret "wrong $LABEL $TYPE statistics of $C instead of $EXPECTED"
|
2013-04-25 14:40:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-02-25 10:49:30 -08:00
|
|
|
#########
|
|
|
|
sec_start
|
|
|
|
|
Remove a lot of obsoleted options
These options were ancient or made obsolete a long time ago, it is
safe to remove them.
Also stop printing ancient options, they should be treated the same as
unknown options.
Removed options: lwres, geoip-use-ecs, sit-secret, use-ixfr,
acache-cleaning-interval, acache-enable, additional-from-auth,
additional-from-cache, allow-v6-synthesis, dnssec-enable,
max-acache-size, nosit-udp-size, queryport-pool-ports,
queryport-pool-updateinterval, request-sit, use-queryport-pool, and
support-ixfr.
2020-12-08 15:08:32 +01:00
|
|
|
# Tests of referrals to "." must be done before the hints are loaded.
|
2013-04-25 14:40:32 -07:00
|
|
|
burst 5 a1.tld3 +norec
|
2013-02-25 10:49:30 -08:00
|
|
|
# basic rate limiting
|
|
|
|
burst 3 a1.tld2
|
2016-11-02 20:56:02 -07:00
|
|
|
# delay allows an additional response.
|
2013-02-25 10:49:30 -08:00
|
|
|
sleep 1
|
2013-06-08 13:17:33 -07:00
|
|
|
burst 10 a1.tld2
|
2013-04-25 14:40:32 -07:00
|
|
|
# Request 30 different qnames to try a wildcard.
|
2022-07-25 13:55:03 +00:00
|
|
|
burst 30 'y.x$CNT.a2.tld2'
|
2013-02-25 10:49:30 -08:00
|
|
|
|
2016-11-02 20:56:02 -07:00
|
|
|
# IP TC drop NXDOMAIN SERVFAIL NOERROR
|
2013-04-25 14:40:32 -07:00
|
|
|
# referrals to "."
|
2016-11-02 20:56:02 -07:00
|
|
|
ck_result a1.tld3 x 0 1 2 0 0 2
|
2013-06-08 13:17:33 -07:00
|
|
|
# check 13 results including 1 second delay that allows an additional response
|
2016-11-02 20:56:02 -07:00
|
|
|
ck_result a1.tld2 192.0.2.1 3 4 6 0 0 8
|
2013-02-25 10:49:30 -08:00
|
|
|
|
2022-07-25 13:55:03 +00:00
|
|
|
# Check the wildcard answers.
|
|
|
|
# The zone origin name of the 30 requests is counted.
|
|
|
|
ck_result 'y.x*.a2.tld2' 192.0.2.2 2 10 18 0 0 12
|
2013-02-25 10:49:30 -08:00
|
|
|
|
|
|
|
#########
|
|
|
|
sec_start
|
|
|
|
|
2013-06-08 13:17:33 -07:00
|
|
|
burst 10 'x.a3.tld3'
|
|
|
|
burst 10 'y$CNT.a3.tld3'
|
|
|
|
burst 10 'z$CNT.a4.tld2'
|
|
|
|
|
|
|
|
# 10 identical recursive responses are limited
|
2016-11-02 20:56:02 -07:00
|
|
|
ck_result 'x.a3.tld3' 192.0.3.3 2 3 5 0 0 5
|
2013-02-25 10:49:30 -08:00
|
|
|
|
2013-06-08 13:17:33 -07:00
|
|
|
# 10 different recursive responses are not limited
|
2016-11-02 20:56:02 -07:00
|
|
|
ck_result 'y*.a3.tld3' 192.0.3.3 10 0 0 0 0 10
|
2013-02-25 10:49:30 -08:00
|
|
|
|
2013-06-08 13:17:33 -07:00
|
|
|
# 10 different NXDOMAIN responses are limited based on the parent name.
|
|
|
|
# We count 13 responses because we count truncated NXDOMAIN responses
|
|
|
|
# as both truncated and NXDOMAIN.
|
2016-11-02 20:56:02 -07:00
|
|
|
ck_result 'z*.a4.tld2' x 0 3 5 5 0 0
|
2013-02-25 10:49:30 -08:00
|
|
|
|
2018-02-20 15:43:27 -08:00
|
|
|
$RNDCCMD $ns2 stats
|
2013-06-08 13:17:33 -07:00
|
|
|
ckstats first dropped 36
|
|
|
|
ckstats first truncated 21
|
2013-04-25 14:40:32 -07:00
|
|
|
|
2013-02-25 10:49:30 -08:00
|
|
|
|
|
|
|
#########
|
|
|
|
sec_start
|
|
|
|
|
2013-06-08 13:17:33 -07:00
|
|
|
burst 10 a5.tld2 +tcp
|
|
|
|
burst 10 a6.tld2 -b $ns7
|
|
|
|
burst 10 a7.tld4
|
2016-11-02 20:56:02 -07:00
|
|
|
burst 2 a8.tld2 -t AAAA
|
|
|
|
burst 2 a8.tld2 -t TXT
|
|
|
|
burst 2 a8.tld2 -t SPF
|
2013-02-25 10:49:30 -08:00
|
|
|
|
2016-11-02 20:56:02 -07:00
|
|
|
# IP TC drop NXDOMAIN SERVFAIL NOERROR
|
2013-02-25 10:49:30 -08:00
|
|
|
# TCP responses are not rate limited
|
2016-11-02 20:56:02 -07:00
|
|
|
ck_result a5.tld2 192.0.2.5 10 0 0 0 0 10
|
2013-02-25 10:49:30 -08:00
|
|
|
|
|
|
|
# whitelisted client is not rate limited
|
2016-11-02 20:56:02 -07:00
|
|
|
ck_result a6.tld2 192.0.2.6 10 0 0 0 0 10
|
2013-02-25 10:49:30 -08:00
|
|
|
|
2013-06-08 13:17:33 -07:00
|
|
|
# Errors such as SERVFAIL are rate limited.
|
2016-11-02 20:56:02 -07:00
|
|
|
ck_result a7.tld4 x 0 0 8 0 2 0
|
2013-02-25 10:49:30 -08:00
|
|
|
|
2013-04-25 14:40:32 -07:00
|
|
|
# NODATA responses are counted as the same regardless of qtype.
|
2016-11-02 20:56:02 -07:00
|
|
|
ck_result a8.tld2 x 0 2 2 0 0 4
|
2013-04-25 14:40:32 -07:00
|
|
|
|
2018-02-20 15:43:27 -08:00
|
|
|
$RNDCCMD $ns2 stats
|
2013-06-08 13:17:33 -07:00
|
|
|
ckstats second dropped 46
|
|
|
|
ckstats second truncated 23
|
2013-04-25 14:40:32 -07:00
|
|
|
|
2013-02-25 10:49:30 -08:00
|
|
|
|
|
|
|
#########
|
|
|
|
sec_start
|
|
|
|
|
2016-11-02 20:56:02 -07:00
|
|
|
# IP TC drop NXDOMAIN SERVFAIL NOERROR
|
2013-02-25 10:49:30 -08:00
|
|
|
# all-per-second
|
|
|
|
# The qnames are all unique but the client IP address is constant.
|
2013-06-08 13:17:33 -07:00
|
|
|
QNUM=101
|
|
|
|
burst 60 'all$CNT.a9.tld2'
|
2013-02-25 10:49:30 -08:00
|
|
|
|
2016-11-02 20:56:02 -07:00
|
|
|
ck_result 'a*.a9.tld2' 192.0.2.8 50 0 10 0 0 50
|
2013-02-25 10:49:30 -08:00
|
|
|
|
2018-02-20 15:43:27 -08:00
|
|
|
$RNDCCMD $ns2 stats
|
2013-06-08 13:17:33 -07:00
|
|
|
ckstats final dropped 56
|
|
|
|
ckstats final truncated 23
|
2013-04-25 14:40:32 -07:00
|
|
|
|
2023-05-24 13:58:01 +02:00
|
|
|
|
2016-01-11 19:37:17 -08:00
|
|
|
#########
|
|
|
|
sec_start
|
|
|
|
|
2023-05-24 13:58:01 +02:00
|
|
|
# check that "would limit" is emitted for "log-only yes;"
|
2018-02-20 15:43:27 -08:00
|
|
|
DIGOPTS="+nocookie +nosearch +time=1 +tries=1 +ignore -p ${PORT}"
|
2023-05-24 13:58:01 +02:00
|
|
|
$DIG $DIGOPTS @$ns4 A a7.tld4 > dig.out.a7.tld 2> /dev/null
|
|
|
|
# skip this check if query takes over 500ms
|
|
|
|
if grep -E ';; Query time: [1-4]?[0-9]?[0-9] msec' dig.out.a7.tld > /dev/null 2>&1; then
|
|
|
|
for i in 1 2 3 4 5; do
|
|
|
|
$DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1 &
|
|
|
|
done
|
|
|
|
wait
|
|
|
|
grep "would limit" ns4/named.run > /dev/null 2>&1 || setret "\"would limit\" not found in log file."
|
|
|
|
fi
|
|
|
|
|
2016-01-11 19:37:17 -08:00
|
|
|
|
2021-07-27 17:55:08 -07:00
|
|
|
# regression test for GL #2839
|
|
|
|
DIGOPTS="+bufsize=4096 +ignore -p ${PORT}"
|
|
|
|
$DIG $DIGOPTS @$ns4 TXT big.tld4 > /dev/null 2>&1
|
|
|
|
|
2016-01-11 19:37:17 -08:00
|
|
|
|
2023-05-24 13:58:01 +02:00
|
|
|
# check named doesn't start with a broken config
|
2019-01-28 18:11:57 -08:00
|
|
|
$NAMED -D rrl-ns5 -gc broken.conf > broken.out 2>&1 &
|
2016-01-11 19:37:17 -08:00
|
|
|
sleep 2
|
2018-02-20 15:43:27 -08:00
|
|
|
grep "min-table-size 1" broken.out > /dev/null || setret "min-table-size 0 was not changed to 1"
|
2016-01-11 19:37:17 -08:00
|
|
|
|
|
|
|
if [ -f named.pid ]; then
|
2021-10-15 00:05:36 -07:00
|
|
|
kill `cat named.pid`
|
2018-02-20 15:43:27 -08:00
|
|
|
setret "named should not have started, but did"
|
2016-01-11 19:37:17 -08:00
|
|
|
fi
|
2013-02-25 10:49:30 -08:00
|
|
|
|
2023-05-24 13:58:01 +02:00
|
|
|
|
2018-02-20 15:43:27 -08:00
|
|
|
echo_i "exit status: $ret"
|
2016-06-14 13:48:39 +10:00
|
|
|
[ $ret -eq 0 ] || exit 1
|