t_ipsec_tunnel.sh revision 1.3
1#	$NetBSD: t_ipsec_tunnel.sh,v 1.3 2017/04/16 10:34:49 ozaki-r Exp $
2#
3# Copyright (c) 2017 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
28SOCK_LOCAL=unix://ipsec_local
29SOCK_TUNNEL_LOCAL=unix://ipsec_tunel_local
30SOCK_TUNNEL_REMOTE=unix://ipsec_tunnel_remote
31SOCK_REMOTE=unix://ipsec_remote
32BUS_LOCAL=./bus_ipsec_local
33BUS_TUNNEL=./bus_ipsec_tunnel
34BUS_REMOTE=./bus_ipsec_remote
35
36DEBUG=${DEBUG:-false}
37
38test_ipsec4_tunnel()
39{
40	local proto=$1
41	local algo=$2
42	local ip_local=10.0.1.2
43	local ip_gw_local=10.0.1.1
44	local ip_gw_local_tunnel=20.0.0.1
45	local ip_gw_remote_tunnel=20.0.0.2
46	local ip_gw_remote=10.0.2.1
47	local ip_remote=10.0.2.2
48	local subnet_local=10.0.1.0
49	local subnet_remote=10.0.2.0
50	local keylen=$(get_one_valid_keylen $algo)
51	local key=$(generate_key $keylen)
52	local tmpfile=./tmp
53	local outfile=./out
54	local opt= proto_cap=
55
56	if [ $proto = esp ]; then
57		opt=-E
58		proto_cap=ESP
59	else
60		opt=-A
61		proto_cap=AH
62	fi
63
64	# See https://www.netbsd.org/docs/network/ipsec/#sample_vpn
65	rump_server_crypto_start $SOCK_LOCAL
66	rump_server_crypto_start $SOCK_TUNNEL_LOCAL netipsec
67	rump_server_crypto_start $SOCK_TUNNEL_REMOTE netipsec
68	rump_server_crypto_start $SOCK_REMOTE
69	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS_LOCAL
70	rump_server_add_iface $SOCK_TUNNEL_LOCAL shmif0 $BUS_LOCAL
71	rump_server_add_iface $SOCK_TUNNEL_LOCAL shmif1 $BUS_TUNNEL
72	rump_server_add_iface $SOCK_TUNNEL_REMOTE shmif0 $BUS_REMOTE
73	rump_server_add_iface $SOCK_TUNNEL_REMOTE shmif1 $BUS_TUNNEL
74	rump_server_add_iface $SOCK_REMOTE shmif0 $BUS_REMOTE
75
76	export RUMP_SERVER=$SOCK_LOCAL
77	atf_check -s exit:0 rump.ifconfig shmif0 $ip_local/24
78	atf_check -s exit:0 -o ignore \
79	    rump.route -n add -net $subnet_remote $ip_gw_local
80
81	export RUMP_SERVER=$SOCK_TUNNEL_LOCAL
82	atf_check -s exit:0 rump.ifconfig shmif0 $ip_gw_local/24
83	atf_check -s exit:0 rump.ifconfig shmif1 $ip_gw_local_tunnel/24
84	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=1
85	atf_check -s exit:0 -o ignore \
86	    rump.route -n add -net $subnet_remote $ip_gw_remote_tunnel
87
88	export RUMP_SERVER=$SOCK_TUNNEL_REMOTE
89	atf_check -s exit:0 rump.ifconfig shmif0 $ip_gw_remote/24
90	atf_check -s exit:0 rump.ifconfig shmif1 $ip_gw_remote_tunnel/24
91	atf_check -s exit:0 rump.sysctl -q -w net.inet.ip.forwarding=1
92	atf_check -s exit:0 -o ignore \
93	    rump.route -n add -net $subnet_local $ip_gw_local_tunnel
94
95	export RUMP_SERVER=$SOCK_REMOTE
96	atf_check -s exit:0 rump.ifconfig shmif0 $ip_remote/24
97	# Run ifconfig -w 10 just once for optimization
98	atf_check -s exit:0 rump.ifconfig -w 10
99	atf_check -s exit:0 -o ignore \
100	    rump.route -n add -net $subnet_local $ip_gw_remote
101
102	extract_new_packets $BUS_TUNNEL > $outfile
103
104	export RUMP_SERVER=$SOCK_LOCAL
105	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_remote
106
107	extract_new_packets $BUS_TUNNEL > $outfile
108	atf_check -s exit:0 \
109	    -o match:"$ip_local > $ip_remote: ICMP echo request" \
110	    cat $outfile
111	atf_check -s exit:0 \
112	    -o match:"$ip_remote > $ip_local: ICMP echo reply" \
113	    cat $outfile
114
115	export RUMP_SERVER=$SOCK_TUNNEL_LOCAL
116	# from https://www.netbsd.org/docs/network/ipsec/
117	cat > $tmpfile <<-EOF
118	add $ip_gw_local_tunnel $ip_gw_remote_tunnel $proto 10000 $opt $algo $key;
119	add $ip_gw_remote_tunnel $ip_gw_local_tunnel $proto 10001 $opt $algo $key;
120	spdadd $subnet_local/24 $subnet_remote/24 any -P out ipsec
121	    $proto/tunnel/$ip_gw_local_tunnel-$ip_gw_remote_tunnel/require;
122	spdadd $subnet_remote/24 $subnet_local/24 any -P in ipsec
123	    $proto/tunnel/$ip_gw_remote_tunnel-$ip_gw_local_tunnel/require;
124	EOF
125	$DEBUG && cat $tmpfile
126	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
127	$DEBUG && $HIJACKING setkey -D
128	atf_check -s exit:0 \
129	    -o match:"$ip_gw_local_tunnel $ip_gw_remote_tunnel" \
130	    $HIJACKING setkey -D
131	atf_check -s exit:0 \
132	    -o match:"$ip_gw_remote_tunnel $ip_gw_local_tunnel" \
133	    $HIJACKING setkey -D
134	# TODO: more detail checks
135
136	export RUMP_SERVER=$SOCK_TUNNEL_REMOTE
137	cat > $tmpfile <<-EOF
138	add $ip_gw_local_tunnel $ip_gw_remote_tunnel $proto 10000 $opt $algo $key;
139	add $ip_gw_remote_tunnel $ip_gw_local_tunnel $proto 10001 $opt $algo $key;
140	spdadd $subnet_remote/24 $subnet_local/24 any -P out ipsec
141	    $proto/tunnel/$ip_gw_remote_tunnel-$ip_gw_local_tunnel/require;
142	spdadd $subnet_local/24 $subnet_remote/24 any -P in ipsec
143	    $proto/tunnel/$ip_gw_local_tunnel-$ip_gw_remote_tunnel/require;
144	EOF
145	$DEBUG && cat $tmpfile
146	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
147	$DEBUG && $HIJACKING setkey -D
148	atf_check -s exit:0 \
149	    -o match:"$ip_gw_local_tunnel $ip_gw_remote_tunnel" \
150	    $HIJACKING setkey -D
151	atf_check -s exit:0 \
152	    -o match:"$ip_gw_remote_tunnel $ip_gw_local_tunnel" \
153	    $HIJACKING setkey -D
154	# TODO: more detail checks
155
156	export RUMP_SERVER=$SOCK_LOCAL
157	atf_check -s exit:0 -o ignore rump.ping -c 1 -n -w 3 $ip_remote
158
159	extract_new_packets $BUS_TUNNEL > $outfile
160	atf_check -s exit:0 \
161	    -o match:"$ip_gw_local_tunnel > $ip_gw_remote_tunnel: $proto_cap" \
162	    cat $outfile
163	atf_check -s exit:0 \
164	    -o match:"$ip_gw_remote_tunnel > $ip_gw_local_tunnel: $proto_cap" \
165	    cat $outfile
166}
167
168test_ipsec6_tunnel()
169{
170	local proto=$1
171	local algo=$2
172	local ip_local=fd00:1::2
173	local ip_gw_local=fd00:1::1
174	local ip_gw_local_tunnel=fc00::1
175	local ip_gw_remote_tunnel=fc00::2
176	local ip_gw_remote=fd00:2::1
177	local ip_remote=fd00:2::2
178	local subnet_local=fd00:1::
179	local subnet_remote=fd00:2::
180	local keylen=$(get_one_valid_keylen $algo)
181	local key=$(generate_key $keylen)
182	local tmpfile=./tmp
183	local outfile=./out
184	local opt= proto_cap=
185
186	if [ $proto = esp ]; then
187		opt=-E
188		proto_cap=ESP
189	else
190		opt=-A
191		proto_cap=AH
192	fi
193
194	rump_server_crypto_start $SOCK_LOCAL netinet6
195	rump_server_crypto_start $SOCK_TUNNEL_LOCAL netipsec netinet6
196	rump_server_crypto_start $SOCK_TUNNEL_REMOTE netipsec netinet6
197	rump_server_crypto_start $SOCK_REMOTE netinet6
198	rump_server_add_iface $SOCK_LOCAL shmif0 $BUS_LOCAL
199	rump_server_add_iface $SOCK_TUNNEL_LOCAL shmif0 $BUS_LOCAL
200	rump_server_add_iface $SOCK_TUNNEL_LOCAL shmif1 $BUS_TUNNEL
201	rump_server_add_iface $SOCK_TUNNEL_REMOTE shmif0 $BUS_REMOTE
202	rump_server_add_iface $SOCK_TUNNEL_REMOTE shmif1 $BUS_TUNNEL
203	rump_server_add_iface $SOCK_REMOTE shmif0 $BUS_REMOTE
204
205	export RUMP_SERVER=$SOCK_LOCAL
206	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_local/64
207	atf_check -s exit:0 -o ignore \
208	    rump.route -n add -inet6 -net $subnet_remote/64 $ip_gw_local
209
210	export RUMP_SERVER=$SOCK_TUNNEL_LOCAL
211	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_gw_local/64
212	atf_check -s exit:0 rump.ifconfig shmif1 inet6 $ip_gw_local_tunnel/64
213	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=1
214	atf_check -s exit:0 -o ignore \
215	    rump.route -n add -inet6 -net $subnet_remote/64 $ip_gw_remote_tunnel
216
217	export RUMP_SERVER=$SOCK_TUNNEL_REMOTE
218	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_gw_remote/64
219	atf_check -s exit:0 rump.ifconfig shmif1 inet6 $ip_gw_remote_tunnel/64
220	atf_check -s exit:0 rump.sysctl -q -w net.inet6.ip6.forwarding=1
221	atf_check -s exit:0 -o ignore \
222	    rump.route -n add -inet6 -net $subnet_local/64 $ip_gw_local_tunnel
223
224	export RUMP_SERVER=$SOCK_REMOTE
225	atf_check -s exit:0 rump.ifconfig shmif0 inet6 $ip_remote
226	# Run ifconfig -w 10 just once for optimization
227	atf_check -s exit:0 rump.ifconfig -w 10
228	atf_check -s exit:0 -o ignore \
229	    rump.route -n add -inet6 -net $subnet_local/64 $ip_gw_remote
230
231	extract_new_packets $BUS_TUNNEL > $outfile
232
233	export RUMP_SERVER=$SOCK_LOCAL
234	atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n -X 3 $ip_remote
235
236	extract_new_packets $BUS_TUNNEL > $outfile
237	atf_check -s exit:0 \
238	    -o match:"$ip_local > $ip_remote: ICMP6, echo request" \
239	    cat $outfile
240	atf_check -s exit:0 \
241	    -o match:"$ip_remote > $ip_local: ICMP6, echo reply" \
242	    cat $outfile
243
244	export RUMP_SERVER=$SOCK_TUNNEL_LOCAL
245	# from https://www.netbsd.org/docs/network/ipsec/
246	cat > $tmpfile <<-EOF
247	add $ip_gw_local_tunnel $ip_gw_remote_tunnel $proto 10000 $opt $algo $key;
248	add $ip_gw_remote_tunnel $ip_gw_local_tunnel $proto 10001 $opt $algo $key;
249	spdadd $subnet_local/64 $subnet_remote/64 any -P out ipsec
250	    $proto/tunnel/$ip_gw_local_tunnel-$ip_gw_remote_tunnel/require;
251	spdadd $subnet_remote/64 $subnet_local/64 any -P in ipsec
252	    $proto/tunnel/$ip_gw_remote_tunnel-$ip_gw_local_tunnel/require;
253	EOF
254	$DEBUG && cat $tmpfile
255	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
256	$DEBUG && $HIJACKING setkey -D
257	atf_check -s exit:0 \
258	    -o match:"$ip_gw_local_tunnel $ip_gw_remote_tunnel" \
259	    $HIJACKING setkey -D
260	atf_check -s exit:0 \
261	    -o match:"$ip_gw_remote_tunnel $ip_gw_local_tunnel" \
262	    $HIJACKING setkey -D
263	# TODO: more detail checks
264
265	export RUMP_SERVER=$SOCK_TUNNEL_REMOTE
266	cat > $tmpfile <<-EOF
267	add $ip_gw_local_tunnel $ip_gw_remote_tunnel $proto 10000 $opt $algo $key;
268	add $ip_gw_remote_tunnel $ip_gw_local_tunnel $proto 10001 $opt $algo $key;
269	spdadd $subnet_remote/64 $subnet_local/64 any -P out ipsec
270	    $proto/tunnel/$ip_gw_remote_tunnel-$ip_gw_local_tunnel/require;
271	spdadd $subnet_local/64 $subnet_remote/64 any -P in ipsec
272	    $proto/tunnel/$ip_gw_local_tunnel-$ip_gw_remote_tunnel/require;
273	EOF
274	$DEBUG && cat $tmpfile
275	atf_check -s exit:0 -o empty $HIJACKING setkey -c < $tmpfile
276	$DEBUG && $HIJACKING setkey -D
277	atf_check -s exit:0 \
278	    -o match:"$ip_gw_local_tunnel $ip_gw_remote_tunnel" \
279	    $HIJACKING setkey -D
280	atf_check -s exit:0 \
281	    -o match:"$ip_gw_remote_tunnel $ip_gw_local_tunnel" \
282	    $HIJACKING setkey -D
283	# TODO: more detail checks
284
285	export RUMP_SERVER=$SOCK_LOCAL
286	atf_check -s exit:0 -o ignore rump.ping6 -c 1 -n -X 3 $ip_remote
287
288	extract_new_packets $BUS_TUNNEL > $outfile
289	atf_check -s exit:0 \
290	    -o match:"$ip_gw_local_tunnel > $ip_gw_remote_tunnel: $proto_cap" \
291	    cat $outfile
292	atf_check -s exit:0 \
293	    -o match:"$ip_gw_remote_tunnel > $ip_gw_local_tunnel: $proto_cap" \
294	    cat $outfile
295}
296
297test_tunnel_common()
298{
299	local ipproto=$1
300	local proto=$2
301	local algo=$3
302
303	if [ $ipproto = ipv4 ]; then
304		test_ipsec4_tunnel $proto $algo
305	else
306		test_ipsec6_tunnel $proto $algo
307	fi
308}
309
310add_test_tunnel_mode()
311{
312	local ipproto=$1
313	local proto=$2
314	local algo=$3
315	local _algo=$(echo $algo | sed 's/-//g')
316	local name= desc=
317
318	name="ipsec_tunnel_${ipproto}_${proto}_${_algo}"
319	desc="Tests of IPsec ($ipproto) tunnel mode with $proto ($algo)"
320
321	atf_test_case ${name} cleanup
322	eval "								\
323	    ${name}_head() {						\
324	        atf_set \"descr\" \"$desc\";				\
325	        atf_set \"require.progs\" \"rump_server\" \"setkey\";	\
326	    };								\
327	    ${name}_body() {						\
328	        test_tunnel_common $ipproto $proto $algo;		\
329	        rump_server_destroy_ifaces;				\
330	    };								\
331	    ${name}_cleanup() {						\
332	        $DEBUG && dump;						\
333	        cleanup;						\
334	    }								\
335	"
336	atf_add_test_case ${name}
337}
338
339atf_init_test_cases()
340{
341	local algo=
342
343	for algo in $ESP_ENCRYPTION_ALGORITHMS; do
344		add_test_tunnel_mode ipv4 esp $algo
345		add_test_tunnel_mode ipv6 esp $algo
346	done
347
348	for algo in $AH_AUTHENTICATION_ALGORITHMS; do
349		add_test_tunnel_mode ipv4 ah $algo
350		add_test_tunnel_mode ipv6 ah $algo
351	done
352}
353