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