tests.sh 13.7 KB
Newer Older
1
2
#!/bin/sh
#
3
# Copyright (C) 2015-2018  Internet Systems Consortium, Inc. ("ISC")
4
#
5
6
7
# 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 http://mozilla.org/MPL/2.0/.
8

9
10
11
# touch dnsrps-off to not test with DNSRPS
# touch dnsrps-only to not test with classic RPZ

12
13
14
15
SYSTEMTESTTOP=..
. $SYSTEMTESTTOP/conf.sh

status=0
16

17
18
t=0

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
DEBUG=
DNSRPS_TEST_MODE=	# "" to test with and then without DNSRPS
ARGS=

USAGE="$0: [-xS] [-D {1,2}]"
while getopts "xSD:" c; do
    case $c in
	x) set -x; DEBUG=-x; ARGS="$ARGS -x";;
	D) DNSRPS_TEST_MODE="$OPTARG";;		# with or without DNSRPS
	*) 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


DNSRPSCMD=../rpz/dnsrps
RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s"

# Run the tests twice, first without DNSRPS and then with if it is available
if [ -z "$DNSRPS_TEST_MODE" ]; then
    if [ -e dnsrps-only ]; then
        echo "I:'dnsrps-only' found: skipping native RPZ sub-test"
    else
        echo "I:running native RPZ sub-test"
	$SHELL ./$0 -D1 $ARGS || status=1
    fi

    if [ -e dnsrps-off ]; then
	echo "I:'dnsrps-off' found: skipping DNSRPS sub-test"
    else
	echo "I:attempting to configure servers with DNSRPS..."
	$SHELL ./setup.sh -D $DEBUG
	sed -n 's/^## /I:/p' dnsrps.conf
	if grep '^#fail' dnsrps.conf >/dev/null; then
	    echo "I:exit status: 1"
	    exit 1
	fi
	if test -z "`grep '^#skip' dnsrps.conf`"; then
	    $RNDCCMD 10.53.0.2 reload
	    $RNDCCMD 10.53.0.3 reload
	    $RNDCCMD 10.53.0.2 flush
	    $RNDCCMD 10.53.0.3 flush
	    echo "I:running DNSRPS sub-test"
	    $SHELL ./$0 -D2 $ARGS || status=1
        else
            echo "I:DNSRPS sub-test skipped"
	fi
    fi

    echo "I:exit status: $status"
    exit $status
fi

78
79
80
81
82
83
84
85
86
87
88
89
# $1 = test name (such as 1a, 1b, etc. for which named.$1.conf exists)
run_server() {
    TESTNAME=$1

    echo "I:stopping resolver"
    $PERL $SYSTEMTESTTOP/stop.pl . ns2

    sleep 1

    echo "I:starting resolver using named.$TESTNAME.conf"
    cp -f ns2/named.$TESTNAME.conf ns2/named.conf
    $PERL $SYSTEMTESTTOP/start.pl --noclean --restart . ns2
90
    sleep 3
91
92
93
94
95
96
}

run_query() {
    TESTNAME=$1
    LINE=$2

97
    NAME=`sed -n -e "$LINE,"'$p' ns2/$TESTNAME.queries | head -n 1`
98
99
100
101
102
103
104
105
106
107
108
    $DIG $DIGOPTS $NAME a @10.53.0.2 -p 5300 -b 127.0.0.1 > dig.out.${t}
    grep "status: SERVFAIL" dig.out.${t} > /dev/null 2>&1 && return 1
    return 0
}

# $1 = test name (such as 1a, 1b, etc. for which $1.queries exists)
# $2 = line number in query file to test (the name to query is taken from this line)
expect_norecurse() {
    TESTNAME=$1
    LINE=$2

109
    NAME=`sed -n -e "$LINE,"'$p' ns2/$TESTNAME.queries | head -n 1`
110
111
112
    t=`expr $t + 1`
    echo "I:testing $NAME doesn't recurse (${t})"
    run_query $TESTNAME $LINE || {
113
114
	echo "I:test ${t} failed"
	status=1
115
116
117
118
119
120
121
122
123
    }
}

# $1 = test name (such as 1a, 1b, etc. for which $1.queries exists)
# $2 = line number in query file to test (the name to query is taken from this line)
expect_recurse() {
    TESTNAME=$1
    LINE=$2

124
    NAME=`sed -n -e "$LINE,"'$p' ns2/$TESTNAME.queries | head -n 1`
125
126
127
    t=`expr $t + 1`
    echo "I:testing $NAME recurses (${t})"
    run_query $TESTNAME $LINE && {
128
129
	echo "I:test ${t} failed"
	status=1
130
131
132
    }
}

133
134
135
# show whether and why DNSRPS is enabled or disabled
sed -n 's/^## /I:/p' dnsrps.conf

136
137
138
139
t=`expr $t + 1`
echo "I:testing that l1.l0 exists without RPZ (${t})"
$DIG $DIGOPTS l1.l0 ns @10.53.0.2 -p 5300 > dig.out.${t}
grep "status: NOERROR" dig.out.${t} > /dev/null 2>&1 || {
140
    echo "I:test ${t} failed"
141
142
143
144
145
146
147
    status=1
}

t=`expr $t + 1`
echo "I:testing that l2.l1.l0 returns SERVFAIL without RPZ (${t})"
$DIG $DIGOPTS l2.l1.l0 ns @10.53.0.2 -p 5300 > dig.out.${t}
grep "status: SERVFAIL" dig.out.${t} > /dev/null 2>&1 || {
148
    echo "I:test ${t} failed"
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
    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=`expr $t + 1`
    echo "I:testing that ${ni} of 33 queries skip recursion (${t})"
    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=`expr $c + $?`
    done
    skipped=`expr 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

226
227
228
229
230
231
232
233
234
# Group 6
echo "I:check recursive behavior consistency during policy update races"
run_server 6a
sleep 1
t=`expr $t + 1`
echo "I:running dig to cache CNAME record (${t})"
$DIG $DIGOPTS @10.53.0.2 -p 5300 www.test.example.org CNAME > dig.out.${t}
sleep 1
echo "I:suspending authority server"
235
236
237
238
239
240
241
if [ "$CYGWIN" ]; then
    WINPID=`cat ns1/named.pid`
    PID=`ps | sed 's/^..//' | awk '$4 == '$WINPID | awk '{print $1}'`
else
    PID=`cat ns1/named.pid`
fi
kill -TSTP $PID
242
243
244
245
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 9953 reload 6a.00.policy.local 2>&1 | sed 's/^/I:ns2 /'
246
test -f dnsrpzd.pid && kill -USR1 `cat dnsrpzd.pid`
247
248
249
250
251
252
253
254
sleep 1
t=`expr $t + 1`
echo "I:running dig to follow CNAME (blocks, so runs in the background) (${t})"
$DIG $DIGOPTS @10.53.0.2 -p 5300 www.test.example.org A > 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 9953 reload 6a.00.policy.local 2>&1 | sed 's/^/I:ns2 /'
255
test -f dnsrpzd.pid && kill -USR1 `cat dnsrpzd.pid`
256
257
sleep 1
echo "I:resuming authority server"
258
259
260
261
262
263
264
if [ "$CYGWIN" ]; then
    WINPID=`cat ns1/named.pid`
    PID=`ps | sed 's/^..//' | awk '$4 == '$WINPID | awk '{print $1}'`
else
    PID=`cat ns1/named.pid`
fi
kill -CONT $PID
265
266
267
for n in 1 2 3 4 5 6 7 8 9; do
    sleep 1
    [ -s dig.out.${t} ] || continue
268
    grep "status: .*," dig.out.${t} > /dev/null 2>&1 && break
269
done
270
271
272
273
grep "status: NOERROR" dig.out.${t} > /dev/null 2>&1 || {
    echo "I:test ${t} failed"
    status=1
}
274
275
276
277
278
279
280
281
282
283

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=`expr $t + 1`
echo "I:running dig to cache CNAME record (${t})"
$DIG $DIGOPTS @10.53.0.2 -p 5300 www.test.example.org CNAME > dig.out.${t}
sleep 1
echo "I:suspending authority server"
284
285
286
287
288
289
290
if [ "$CYGWIN" ]; then
    WINPID=`cat ns1/named.pid`
    PID=`ps | sed 's/^..//' | awk '$4 == '$WINPID | awk '{print $1}'`
else
    PID=`cat ns1/named.pid`
fi
kill -TSTP $PID
291
292
293
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 9953 reload 6a.00.policy.local 2>&1 | sed 's/^/I:ns2 /'
294
test -f dnsrpzd.pid && kill -USR1 `cat dnsrpzd.pid`
295
296
297
298
299
300
sleep 1
t=`expr $t + 1`
echo "I:running dig to follow CNAME (blocks, so runs in the background) (${t})"
$DIG $DIGOPTS @10.53.0.2 -p 5300 www.test.example.org A > dig.out.${t} &
sleep 1
echo "I:removing the policy zone"
301
302
cp ns2/named.default.conf ns2/named.conf
$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 reconfig 2>&1 | sed 's/^/I:ns2 /'
303
test -f dnsrpzd.pid && kill -USR1 `cat dnsrpzd.pid`
304
305
sleep 1
echo "I:resuming authority server"
306
307
308
309
310
311
312
if [ "$CYGWIN" ]; then
    WINPID=`cat ns1/named.pid`
    PID=`ps | sed 's/^..//' | awk '$4 == '$WINPID | awk '{print $1}'`
else
    PID=`cat ns1/named.pid`
fi
kill -CONT $PID
313
314
315
for n in 1 2 3 4 5 6 7 8 9; do
    sleep 1
    [ -s dig.out.${t} ] || continue
316
    grep "status: .*," dig.out.${t} > /dev/null 2>&1 && break
317
done
318
319
320
321
grep "status: NOERROR" dig.out.${t} > /dev/null 2>&1 || {
     echo "I:test ${t} failed"
     status=1
}
322

323
324
325
326
327
328
329
330
331
# Check CLIENT-IP behavior
t=`expr $t + 1`
echo "I:testing CLIENT-IP behavior (${t})"
run_server clientip
$DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p 5300 -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
}
332
grep "^l2.l1.l0.[ 	]*[0-9]*[ 	]*IN[ 	]*A[ 	]*10.53.0.2" dig.out.${t} > /dev/null 2>&1 || {
333
334
335
336
    echo "I:test $t failed: didn't get expected answer"
    status=1
}

337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
# Check CLIENT-IP behavior #2
t=`expr $t + 1`
echo "I:testing CLIENT-IP behavior #2 (${t})"
run_server clientip2
$DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p 5300 -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 5300 -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 5300 -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 5300 -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
}

366
367
368
369
# Check RPZ log clause
t=`expr $t + 1`
echo "I:testing RPZ log clause (${t})"
run_server log
370
cur=`awk 'BEGIN {l=0} /^/ {l++} END { print l }' ns2/named.run`
371
372
373
$DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p 5300 -b 10.53.0.4 > dig.out.${t}
$DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p 5300 -b 10.53.0.3 >> dig.out.${t}
$DIG $DIGOPTS l2.l1.l0 a @10.53.0.2 -p 5300 -b 10.53.0.2 >> dig.out.${t}
Mark Andrews's avatar
Mark Andrews committed
374
sed -n "$cur,"'$p' < ns2/named.run | grep "view recursive: rpz CLIENT-IP Local-Data rewrite l2.l1.l0 via 32.4.0.53.10.rpz-client-ip.log1" > /dev/null && {
375
376
377
    echo "I: failed: unexpected rewrite message for policy zone log1 was logged"
    status=1
}
Mark Andrews's avatar
Mark Andrews committed
378
sed -n "$cur,"'$p' < ns2/named.run | grep "view recursive: rpz CLIENT-IP Local-Data rewrite l2.l1.l0 via 32.3.0.53.10.rpz-client-ip.log2" > /dev/null || {
379
380
381
    echo "I: failed: expected rewrite message for policy zone log2 was not logged"
    status=1
}
Mark Andrews's avatar
Mark Andrews committed
382
sed -n "$cur,"'$p' < ns2/named.run | grep "view recursive: rpz CLIENT-IP Local-Data rewrite l2.l1.l0 via 32.2.0.53.10.rpz-client-ip.log3" > /dev/null || {
383
384
385
386
    echo "I: failed: expected rewrite message for policy zone log3 was not logged"
    status=1
}

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
# Check wildcard behavior

t=`expr $t + 1`
echo "I:testing wildcard behavior with 1 RPZ zone (${t})"
run_server wildcard1
$DIG $DIGOPTS www.test1.example.net a @10.53.0.2 -p 5300 > 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 5300 > dig.out.${t}.2
grep "status: NXDOMAIN" dig.out.${t}.2 > /dev/null || {
    echo "I:test ${t} failed"
    status=1
}

t=`expr $t + 1`
echo "I:testing wildcard behavior with 2 RPZ zones (${t})"
run_server wildcard2
$DIG $DIGOPTS www.test1.example.net a @10.53.0.2 -p 5300 > 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 5300 > dig.out.${t}.2
grep "status: NXDOMAIN" dig.out.${t}.2 > /dev/null || {
    echo "I:test ${t} failed"
    status=1
}

t=`expr $t + 1`
echo "I:testing wildcard behavior with 1 RPZ zone and no non-wildcard triggers (${t})"
run_server wildcard3
$DIG $DIGOPTS www.test1.example.net a @10.53.0.2 -p 5300 > 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 5300 > dig.out.${t}.2
grep "status: NOERROR" dig.out.${t}.2 > /dev/null || {
    echo "I:test ${t} failed"
    status=1
}

431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
t=`expr $t + 1`
echo "I:checking 'nsip-wait-recurse no' is faster than 'nsip-wait-recurse yes' ($t)"
echo "I:timing 'nsip-wait-recurse yes' (default)"
ret=0
t1=`$PERL -e 'print time()."\n";'`
$DIG -p 5300 @10.53.0.3 foo.child.example.tld a > dig.out.yes.$t
t2=`$PERL -e 'print time()."\n";'`
p1=`expr $t2 - $t1`
echo "I:elasped time $p1 seconds"

$RNDC  -c ../common/rndc.conf -s 10.53.0.3 -p 9953 flush
cp -f ns3/named2.conf ns3/named.conf
$RNDC  -c ../common/rndc.conf -s 10.53.0.3 -p 9953 reload > /dev/null

echo "I:timing 'nsip-wait-recurse no'"
t3=`$PERL -e 'print time()."\n";'`
$DIG -p 5300 @10.53.0.3 foo.child.example.tld a > dig.out.no.$t
t4=`$PERL -e 'print time()."\n";'`
p2=`expr $t4 - $t3`
echo "I:elasped time $p2 seconds"

if test $p1 -le $p2; then ret=1; fi
if test $ret != 0; then echo "I:failed"; fi
status=`expr $status + $ret`

456
457
458
459
460
461
[ $status -ne 0 ] && pf=fail || pf=pass
case $DNSRPS_TEST_MODE in
        1) echo "I:status (native RPZ sub-test): $status ($pf)";;
        2) echo "I:status (DNSRPS sub-test): $status ($pf)";;
    *) echo "I:invalid test mode";;
esac
462
[ $status -eq 0 ] || exit 1