t_ipsec_pfil.sh revision 1.1.6.1 1 # $NetBSD: t_ipsec_pfil.sh,v 1.1.6.1 2020/11/10 11:44:22 martin Exp $
2 #
3 # Copyright (c) 2019 Internet Initiative Japan Inc.
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 # 1. Redistributions of source code must retain the above copyright
10 # notice, this list of conditions and the following disclaimer.
11 # 2. Redistributions in binary form must reproduce the above copyright
12 # notice, this list of conditions and the following disclaimer in the
13 # documentation and/or other materials provided with the distribution.
14 #
15 # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 # POSSIBILITY OF SUCH DAMAGE.
26 #
27
28 SOCK_ROUTER1=unix://router1
29 SOCK_ROUTER2=unix://router2
30 ROUTER1_LANIP=192.168.1.1
31 ROUTER1_LANNET=192.168.1.0/24
32 ROUTER1_WANIP=10.0.0.1
33 ROUTER1_IPSECIP=172.16.1.1
34 ROUTER2_LANIP=192.168.2.1
35 ROUTER2_LANNET=192.168.2.0/24
36 ROUTER2_WANIP=10.0.0.2
37 ROUTER2_IPSECIP=172.16.2.1
38
39 DEBUG=${DEBUG:-false}
40 TIMEOUT=7
41 HIJACKING_NPF="${HIJACKING},blanket=/dev/npf"
42
43 setup_router()
44 {
45 local sock=$1
46 local lan=$2
47 local wan=$3
48
49 rump_server_add_iface $sock shmif0 bus0
50 rump_server_add_iface $sock shmif1 bus1
51
52 export RUMP_SERVER=${sock}
53 atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.dad_count=0
54
55 atf_check -s exit:0 rump.ifconfig shmif0 inet ${lan} netmask 0xffffff00
56 atf_check -s exit:0 rump.ifconfig shmif0 up
57 # Ensure shmif0 is running
58 atf_check -s exit:0 -o ignore rump.ping -n -c 1 -w $TIMEOUT ${lan}
59 $DEBUG && rump.ifconfig shmif0
60
61 atf_check -s exit:0 rump.ifconfig shmif1 inet ${wan} netmask 0xff000000
62 atf_check -s exit:0 rump.ifconfig shmif1 up
63 # Ensure shmif1 is running
64 atf_check -s exit:0 -o ignore rump.ping -n -c 1 -w $TIMEOUT ${wan}
65 $DEBUG && rump.ifconfig shmif1
66
67 unset RUMP_SERVER
68 }
69
70 setup_if_ipsec()
71 {
72 local addr=$1
73 local remote=$2
74 local src=$3
75 local dst=$4
76 local peernet=$5
77
78 atf_check -s exit:0 rump.ifconfig ipsec0 create
79 atf_check -s exit:0 rump.ifconfig ipsec0 tunnel $src $dst
80 atf_check -s exit:0 rump.ifconfig ipsec0 inet ${addr}/32 $remote
81 atf_check -s exit:0 -o ignore rump.route add -inet $peernet $addr
82
83 $DEBUG && rump.ifconfig ipsec0
84 $DEBUG && rump.route -nL show -inet
85 }
86
87 get_if_ipsec_unique()
88 {
89 local src=$1
90 local proto=$2
91 local unique=""
92
93 unique=`$HIJACKING setkey -DP | grep -A2 "^${src}.*(${proto})$" | grep unique | sed 's/.*unique#//'`
94
95 echo $unique
96 }
97
98 setup_if_ipsec_sa()
99 {
100 local src=$1
101 local dst=$2
102 local inid=$3
103 local outid=$4
104 local proto=$5
105 local algo=$6
106
107 local tmpfile=./tmp
108 local inunique=""
109 local outunique=""
110 local algo_args="$(generate_algo_args $proto $algo)"
111
112 inunique=`get_if_ipsec_unique $dst "ipv4"`
113 atf_check -s exit:0 test "X$inunique" != "X"
114 outunique=`get_if_ipsec_unique $src "ipv4"`
115 atf_check -s exit:0 test "X$outunique" != "X"
116
117 cat > $tmpfile <<-EOF
118 add $dst $src $proto $inid -u $inunique -m transport $algo_args;
119 add $src $dst $proto $outid -u $outunique -m transport $algo_args;
120 EOF
121 $DEBUG && cat $tmpfile
122 atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
123 $DEBUG && $HIJACKING setkey -D
124 $DEBUG && $HIJACKING setkey -DP
125 }
126
127 setup_tunnel()
128 {
129 local proto=$1
130 local algo=$2
131
132 local addr= remote= src= dst= peernet=
133
134 export RUMP_SERVER=$SOCK_ROUTER1
135 addr=$ROUTER1_IPSECIP
136 remote=$ROUTER2_IPSECIP
137 src=$ROUTER1_WANIP
138 dst=$ROUTER2_WANIP
139 peernet=$ROUTER2_LANNET
140 setup_if_ipsec $addr $remote $src $dst $peernet
141 setup_if_ipsec_sa $src $dst "10000" "10001" $proto $algo
142
143 export RUMP_SERVER=$SOCK_ROUTER2
144 addr=$ROUTER2_IPSECIP
145 remote=$ROUTER1_IPSECIP
146 src=$ROUTER2_WANIP
147 dst=$ROUTER1_WANIP
148 peernet=$ROUTER1_LANNET
149 setup_if_ipsec $addr $remote $src $dst $peernet
150 setup_if_ipsec_sa $src $dst "10001" "10000" $proto $algo
151
152 # Ensure ipsecif(4) settings have completed.
153 export RUMP_SERVER=$SOCK_ROUTER1
154 atf_check -s exit:0 -o ignore \
155 rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER1_LANIP \
156 $ROUTER2_LANIP
157
158 export RUMP_SERVER=$SOCK_ROUTER2
159 atf_check -s exit:0 -o ignore \
160 rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER2_LANIP \
161 $ROUTER1_LANIP
162
163 unset RUMP_SERVER
164 }
165
166 ipsecif_pfil_setup()
167 {
168 local proto=$1
169 local algo=$2
170
171 rump_server_crypto_npf_start $SOCK_ROUTER1 netipsec ipsec
172 rump_server_crypto_npf_start $SOCK_ROUTER2 netipsec ipsec
173
174 setup_router $SOCK_ROUTER1 $ROUTER1_LANIP $ROUTER1_WANIP
175 setup_router $SOCK_ROUTER2 $ROUTER2_LANIP $ROUTER2_WANIP
176
177 setup_tunnel $proto $algo
178 }
179
180 prepare_file()
181 {
182 local file=$1
183 local data="0123456789"
184
185 touch $file
186 for i in `seq 1 512`
187 do
188 echo $data >> $file
189 done
190 }
191
192 build_npf_conf()
193 {
194 local outfile=$1
195 local subnet=$2
196 local direction=$3
197
198 local reverse=
199 if [ "X${direction}" = "Xin" ] ; then
200 reverse="out"
201 else
202 reverse="in"
203 fi
204
205 cat > $outfile <<-EOF
206 set bpf.jit off
207 \$if = inet4(ipsec0)
208 \$subnet = { $subnet }
209
210 procedure "log0" {
211 log: npflog0
212 }
213
214 group default {
215 block $direction on \$if proto tcp from \$subnet apply "log0"
216 pass $reverse on \$if proto tcp from \$subnet
217 pass in on \$if proto icmp from 0.0.0.0/0
218 pass out on \$if proto icmp from 0.0.0.0/0
219 pass final on shmif0 all
220 pass final on shmif1 all
221 }
222 EOF
223 }
224
225 ipsecif_pfil_test()
226 {
227 local outfile=./out
228 local npffile=./npf.conf
229 local file_send=./file.send
230 local file_recv=./file.recv
231
232 local subnet="172.16.0.0/16"
233
234 # Try TCP communications just in case.
235 start_nc_server $SOCK_ROUTER2 8888 $file_recv ipv4
236 prepare_file $file_send
237 export RUMP_SERVER=$SOCK_ROUTER1
238 atf_check -s exit:0 $HIJACKING nc -w 3 $ROUTER2_IPSECIP 8888 < $file_send
239 atf_check -s exit:0 diff -q $file_send $file_recv
240 stop_nc_server
241
242 # Setup npf to block *out* direction for ipsecif(4).
243 build_npf_conf $npffile $subnet "out"
244 $DEBUG && cat $npffile
245
246 export RUMP_SERVER=$SOCK_ROUTER1
247 atf_check -s exit:0 $HIJACKING_NPF npfctl reload $npffile
248 atf_check -s exit:0 $HIJACKING_NPF npfctl start
249 $DEBUG && ${HIJACKING},"blanket=/dev/npf" npfctl show
250
251 # ping should still work
252 export RUMP_SERVER=$SOCK_ROUTER1
253 atf_check -s exit:0 -o ignore \
254 rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER1_LANIP \
255 $ROUTER2_LANIP
256
257 export RUMP_SERVER=$SOCK_ROUTER2
258 atf_check -s exit:0 -o ignore \
259 rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER2_LANIP \
260 $ROUTER1_LANIP
261
262 # TCP communications should be blocked.
263 start_nc_server $SOCK_ROUTER2 8888 $file_recv ipv4
264 prepare_file $file_send
265 export RUMP_SERVER=$SOCK_ROUTER1
266 atf_check -s exit:1 -o ignore $HIJACKING nc -w 3 $ROUTER2_IPSECIP 8888 < $file_send
267 stop_nc_server
268
269 atf_check -s exit:0 $HIJACKING_NPF npfctl stop
270 $DEBUG && ${HIJACKING},"blanket=/dev/npf" npfctl show
271
272 # Setup npf to block *in* direction for ipsecif(4).
273 build_npf_conf $npffile $subnet "in"
274 $DEBUG && cat $npffile
275
276 export RUMP_SERVER=$SOCK_ROUTER2
277 atf_check -s exit:0 $HIJACKING_NPF npfctl reload $npffile
278 atf_check -s exit:0 $HIJACKING_NPF npfctl start
279 $DEBUG && ${HIJACKING},"blanket=/dev/npf" npfctl show
280
281 # ping should still work.
282 export RUMP_SERVER=$SOCK_ROUTER1
283 atf_check -s exit:0 -o ignore \
284 rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER1_LANIP \
285 $ROUTER2_LANIP
286
287 export RUMP_SERVER=$SOCK_ROUTER2
288 atf_check -s exit:0 -o ignore \
289 rump.ping -n -w $TIMEOUT -c 1 -I $ROUTER2_LANIP \
290 $ROUTER1_LANIP
291
292 # TCP communications should be blocked.
293 start_nc_server $SOCK_ROUTER2 8888 $file_recv ipv4
294 prepare_file $file_send
295 export RUMP_SERVER=$SOCK_ROUTER1
296 atf_check -s exit:1 -o ignore $HIJACKING nc -w 3 $ROUTER2_IPSECIP 8888 < $file_send
297 stop_nc_server
298
299 atf_check -s exit:0 $HIJACKING_NPF npfctl stop
300 $DEBUG && ${HIJACKING},"blanket=/dev/npf" npfctl show
301
302
303 unset RUMP_SERVER
304 }
305
306 ipsecif_pfil_teardown()
307 {
308
309 export RUMP_SERVER=$SOCK_ROUTER1
310 atf_check -s exit:0 rump.ifconfig ipsec0 deletetunnel
311 atf_check -s exit:0 rump.ifconfig ipsec0 destroy
312 $HIJACKING setkey -F
313
314 export RUMP_SERVER=$SOCK_ROUTER2
315 atf_check -s exit:0 rump.ifconfig ipsec0 deletetunnel
316 atf_check -s exit:0 rump.ifconfig ipsec0 destroy
317 $HIJACKING setkey -F
318
319 unset RUMP_SERVER
320 }
321
322 add_test()
323 {
324 local proto=$1
325 local algo=$2
326 local _algo=$(echo $algo | sed 's/-//g')
327
328 name="ipsecif_pfil_${proto}_${_algo}"
329 desc="Does ipsecif filter tests"
330
331 atf_test_case ${name} cleanup
332 eval "${name}_head() {
333 atf_set descr \"${desc}\"
334 atf_set require.progs rump_server setkey
335 }
336 ${name}_body() {
337 ipsecif_pfil_setup ${proto} ${algo}
338 ipsecif_pfil_test
339 ipsecif_pfil_teardown
340 rump_server_destroy_ifaces
341 }
342 ${name}_cleanup() {
343 \$DEBUG && dump
344 cleanup
345 }"
346 atf_add_test_case ${name}
347 }
348
349 add_test_allalgo()
350 {
351 local desc=$1
352
353 for algo in $ESP_ENCRYPTION_ALGORITHMS_MINIMUM; do
354 add_test esp $algo
355 done
356
357 # ah does not support yet
358 }
359
360 atf_init_test_cases()
361 {
362
363 add_test_allalgo ipsecif_pfil
364 }
365