xref: /src/tests/sys/net/if_ovpn/if_ovpn.sh (revision 77f453e9f9cafaf5e787c5bfd29966066d6b9dc3)
1##
2# SPDX-License-Identifier: BSD-2-Clause
3#
4# Copyright (c) 2022 Rubicon Communications, LLC ("Netgate")
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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25# SUCH DAMAGE.
26
27. $(atf_get_srcdir)/utils.subr
28. $(atf_get_srcdir)/../../netpfil/pf/utils.subr
29
30atf_test_case "4in4" "cleanup"
314in4_head()
32{
33	atf_set descr 'IPv4 in IPv4 tunnel'
34	atf_set require.user root
35	atf_set require.progs openvpn
36}
37
384in4_body()
39{
40	ovpn_init
41
42	l=$(vnet_mkepair)
43
44	vnet_mkjail a ${l}a
45	jexec a ifconfig ${l}a 192.0.2.1/24 up
46	vnet_mkjail b ${l}b
47	jexec b ifconfig ${l}b 192.0.2.2/24 up
48
49	# Sanity check
50	atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2
51
52	ovpn_start a "
53		dev ovpn0
54		dev-type tun
55		proto udp4
56
57		cipher AES-256-GCM
58		auth SHA256
59
60		local 192.0.2.1
61		server 198.51.100.0 255.255.255.0
62		ca $(atf_get_srcdir)/ca.crt
63		cert $(atf_get_srcdir)/server.crt
64		key $(atf_get_srcdir)/server.key
65		dh $(atf_get_srcdir)/dh.pem
66
67		mode server
68		script-security 2
69		auth-user-pass-verify /usr/bin/true via-env
70		topology subnet
71
72		keepalive 100 600
73	"
74	ovpn_start b "
75		dev tun0
76		dev-type tun
77
78		client
79
80		remote 192.0.2.1
81		auth-user-pass $(atf_get_srcdir)/user.pass
82
83		ca $(atf_get_srcdir)/ca.crt
84		cert $(atf_get_srcdir)/client.crt
85		key $(atf_get_srcdir)/client.key
86		dh $(atf_get_srcdir)/dh.pem
87
88		keepalive 100 600
89	"
90
91	# Give the tunnel time to come up
92	sleep 10
93
94	atf_check -s exit:0 -o ignore jexec b ping -c 1 198.51.100.1
95
96	echo 'foo' | jexec b nc -u -w 2 192.0.2.1 1194
97	atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1
98
99	# Test routing loop protection
100	jexec b route add 192.0.2.1 198.51.100.1
101	atf_check -s exit:2 -o ignore jexec b ping -t 1 -c 1 198.51.100.1
102
103	jexec a netstat -I ovpn0 -n -b
104	ipkts=$(jexec a netstat -I ovpn0 -n -b | awk 'NR == 2 { print($5); }')
105	echo "$ipkts input packets"
106	if [ $ipkts -eq 0 ]; then
107		atf_fail "Input packets were not counted"
108	fi
109
110	ibytes=$(jexec a netstat -I ovpn0 -n -b | awk 'NR == 2 { print($8); }')
111	echo "$ibytes input bytes"
112	if [ $ibytes -eq 0 ]; then
113		atf_fail "Input bytes were not counted"
114	fi
115
116	opkts=$(jexec a netstat -I ovpn0 -n -b | awk 'NR == 2 { print($9); }')
117	echo "$opkts output packets"
118	if [ $obytes -eq 0 ]; then
119		atf_fail "Output packets were not counted"
120	fi
121
122	obytes=$(jexec a netstat -I ovpn0 -n -b | awk 'NR == 2 { print($11); }')
123	echo "$obytes output bytes"
124	if [ $obytes -eq 0 ]; then
125		atf_fail "Output bytes were not counted"
126	fi
127}
128
1294in4_cleanup()
130{
131	ovpn_cleanup
132}
133
134atf_test_case "bz283426" "cleanup"
135bz283426_head()
136{
137	atf_set descr 'FreeBSD Bugzilla 283426'
138	atf_set require.user root
139	atf_set require.progs openvpn python3
140}
141
142bz283426_body()
143{
144	ovpn_init
145
146	l=$(vnet_mkepair)
147
148	vnet_mkjail a ${l}a
149	jexec a ifconfig ${l}a 192.0.2.1/24 up
150	vnet_mkjail b ${l}b
151	jexec b ifconfig ${l}b 192.0.2.2/24 up
152
153	# Sanity check
154	atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2
155
156	ovpn_start a "
157		dev ovpn0
158		dev-type tun
159		proto udp4
160
161		cipher AES-256-GCM
162		auth SHA256
163
164		bind 0.0.0.0:1194
165		server 198.51.100.0 255.255.255.0
166		ca $(atf_get_srcdir)/ca.crt
167		cert $(atf_get_srcdir)/server.crt
168		key $(atf_get_srcdir)/server.key
169		dh $(atf_get_srcdir)/dh.pem
170
171		mode server
172		script-security 2
173		auth-user-pass-verify /usr/bin/true via-env
174		topology subnet
175
176		keepalive 100 600
177	"
178	ovpn_start b "
179		dev tun0
180		dev-type tun
181
182		client
183
184		remote 192.0.2.1
185		auth-user-pass $(atf_get_srcdir)/user.pass
186
187		ca $(atf_get_srcdir)/ca.crt
188		cert $(atf_get_srcdir)/client.crt
189		key $(atf_get_srcdir)/client.key
190		dh $(atf_get_srcdir)/dh.pem
191
192		keepalive 100 600
193	"
194
195	# Give the tunnel time to come up
196	sleep 10
197
198	atf_check -s exit:0 -o ignore jexec b ping -c 1 198.51.100.1
199
200	# Send a broadcast packet in the outer link.
201	echo "import socket as sk
202s = sk.socket(sk.AF_INET, sk.SOCK_DGRAM)
203s.setsockopt(sk.SOL_SOCKET, sk.SO_BROADCAST, 1)
204s.sendto(b'x' * 1000, ('192.0.2.255', 1194))" | jexec b python3
205
206	atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1
207}
208
209bz283426_cleanup()
210{
211	ovpn_cleanup
212}
213
214atf_test_case "4mapped" "cleanup"
2154mapped_head()
216{
217	atf_set descr 'IPv4 mapped addresses'
218	atf_set require.user root
219	atf_set require.progs openvpn
220}
221
2224mapped_body()
223{
224	ovpn_init
225
226	l=$(vnet_mkepair)
227
228	vnet_mkjail a ${l}a
229	jexec a ifconfig ${l}a 192.0.2.1/24 up
230	vnet_mkjail b ${l}b
231	jexec b ifconfig ${l}b 192.0.2.2/24 up
232
233	# Sanity check
234	atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2
235
236	#jexec a ifconfig ${l}a
237
238	ovpn_start a "
239		dev ovpn0
240		dev-type tun
241
242		cipher AES-256-GCM
243		auth SHA256
244
245		server 198.51.100.0 255.255.255.0
246		ca $(atf_get_srcdir)/ca.crt
247		cert $(atf_get_srcdir)/server.crt
248		key $(atf_get_srcdir)/server.key
249		dh $(atf_get_srcdir)/dh.pem
250
251		mode server
252		script-security 2
253		auth-user-pass-verify /usr/bin/true via-env
254		topology subnet
255
256		keepalive 100 600
257	"
258	ovpn_start b "
259		dev tun0
260		dev-type tun
261
262		client
263
264		remote 192.0.2.1
265		auth-user-pass $(atf_get_srcdir)/user.pass
266
267		ca $(atf_get_srcdir)/ca.crt
268		cert $(atf_get_srcdir)/client.crt
269		key $(atf_get_srcdir)/client.key
270		dh $(atf_get_srcdir)/dh.pem
271
272		keepalive 100 600
273	"
274
275	# Give the tunnel time to come up
276	sleep 10
277
278	atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1
279}
280
2814mapped_cleanup()
282{
283	ovpn_cleanup
284}
285
286atf_test_case "6in4" "cleanup"
2876in4_head()
288{
289	atf_set descr 'IPv6 in IPv4 tunnel'
290	atf_set require.user root
291	atf_set require.progs openvpn
292}
293
2946in4_body()
295{
296	ovpn_init
297
298	l=$(vnet_mkepair)
299
300	vnet_mkjail a ${l}a
301	jexec a ifconfig ${l}a 192.0.2.1/24 up
302	vnet_mkjail b ${l}b
303	jexec b ifconfig ${l}b 192.0.2.2/24 up
304
305	# Sanity check
306	atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2
307
308	ovpn_start a "
309		dev ovpn0
310		dev-type tun
311		proto udp
312
313		cipher AES-256-GCM
314		auth SHA256
315
316		local 192.0.2.1
317		server-ipv6 2001:db8:1::/64
318
319		ca $(atf_get_srcdir)/ca.crt
320		cert $(atf_get_srcdir)/server.crt
321		key $(atf_get_srcdir)/server.key
322		dh $(atf_get_srcdir)/dh.pem
323
324		mode server
325		script-security 2
326		auth-user-pass-verify /usr/bin/true via-env
327		topology subnet
328
329		keepalive 100 600
330	"
331	ovpn_start b "
332		dev tun0
333		dev-type tun
334
335		client
336
337		remote 192.0.2.1
338		auth-user-pass $(atf_get_srcdir)/user.pass
339
340		ca $(atf_get_srcdir)/ca.crt
341		cert $(atf_get_srcdir)/client.crt
342		key $(atf_get_srcdir)/client.key
343		dh $(atf_get_srcdir)/dh.pem
344
345		keepalive 100 600
346	"
347
348	# Give the tunnel time to come up
349	sleep 10
350
351	atf_check -s exit:0 -o ignore jexec b ping6 -c 3 2001:db8:1::1
352}
353
3546in4_cleanup()
355{
356	ovpn_cleanup
357}
358
359atf_test_case "4in6" "cleanup"
3604in6_head()
361{
362	atf_set descr 'IPv4 in IPv6 tunnel'
363	atf_set require.user root
364	atf_set require.progs openvpn
365}
366
3674in6_body()
368{
369	ovpn_init
370
371	l=$(vnet_mkepair)
372
373	vnet_mkjail a ${l}a
374	jexec a ifconfig ${l}a inet6 2001:db8::1/64 up no_dad
375	vnet_mkjail b ${l}b
376	jexec b ifconfig ${l}b inet6 2001:db8::2/64 up no_dad
377
378	# Sanity check
379	atf_check -s exit:0 -o ignore jexec a ping6 -c 1 2001:db8::2
380
381	ovpn_start a "
382		dev ovpn0
383		dev-type tun
384		proto udp6
385
386		cipher AES-256-GCM
387		auth SHA256
388
389		local 2001:db8::1
390		server 198.51.100.0 255.255.255.0
391		ca $(atf_get_srcdir)/ca.crt
392		cert $(atf_get_srcdir)/server.crt
393		key $(atf_get_srcdir)/server.key
394		dh $(atf_get_srcdir)/dh.pem
395
396		mode server
397		script-security 2
398		auth-user-pass-verify /usr/bin/true via-env
399		topology subnet
400
401		keepalive 100 600
402	"
403	ovpn_start b "
404		dev tun0
405		dev-type tun
406
407		client
408
409		remote 2001:db8::1
410		auth-user-pass $(atf_get_srcdir)/user.pass
411
412		ca $(atf_get_srcdir)/ca.crt
413		cert $(atf_get_srcdir)/client.crt
414		key $(atf_get_srcdir)/client.key
415		dh $(atf_get_srcdir)/dh.pem
416
417		keepalive 100 600
418	"
419
420	dd if=/dev/random of=test.img bs=1024 count=1024
421	cat test.img | jexec a nc -N -l 1234 &
422
423	# Give the tunnel time to come up
424	sleep 10
425
426	atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1
427
428	# MTU sweep
429	for i in `seq 1000 1500`
430	do
431		atf_check -s exit:0 -o ignore jexec b \
432		    ping -c 1 -s $i 198.51.100.1
433	done
434
435	rcvmd5=$(jexec b nc -N -w 3 198.51.100.1 1234 | md5)
436	md5=$(md5 test.img)
437
438	if [ $md5  != $rcvmd5 ];
439	then
440		atf_fail "Transmit corruption!"
441	fi
442}
443
4444in6_cleanup()
445{
446	ovpn_cleanup
447}
448
449atf_test_case "6in6" "cleanup"
4506in6_head()
451{
452	atf_set descr 'IPv6 in IPv6 tunnel'
453	atf_set require.user root
454	atf_set require.progs openvpn
455}
456
4576in6_body()
458{
459	ovpn_init
460
461	l=$(vnet_mkepair)
462
463	vnet_mkjail a ${l}a
464	jexec a ifconfig ${l}a inet6 2001:db8::1/64 up no_dad
465	vnet_mkjail b ${l}b
466	jexec b ifconfig ${l}b inet6 2001:db8::2/64 up no_dad
467
468	# Sanity check
469	atf_check -s exit:0 -o ignore jexec a ping6 -c 1 2001:db8::2
470
471	ovpn_start a "
472		dev ovpn0
473		dev-type tun
474		proto udp6
475
476		cipher AES-256-GCM
477		auth SHA256
478
479		local 2001:db8::1
480		server-ipv6 2001:db8:1::/64
481
482		ca $(atf_get_srcdir)/ca.crt
483		cert $(atf_get_srcdir)/server.crt
484		key $(atf_get_srcdir)/server.key
485		dh $(atf_get_srcdir)/dh.pem
486
487		mode server
488		script-security 2
489		auth-user-pass-verify /usr/bin/true via-env
490		topology subnet
491
492		keepalive 100 600
493	"
494	ovpn_start b "
495		dev tun0
496		dev-type tun
497
498		client
499
500		remote 2001:db8::1
501		auth-user-pass $(atf_get_srcdir)/user.pass
502
503		ca $(atf_get_srcdir)/ca.crt
504		cert $(atf_get_srcdir)/client.crt
505		key $(atf_get_srcdir)/client.key
506		dh $(atf_get_srcdir)/dh.pem
507
508		keepalive 100 600
509	"
510
511	# Give the tunnel time to come up
512	sleep 10
513
514	atf_check -s exit:0 -o ignore jexec b ping6 -c 3 2001:db8:1::1
515	atf_check -s exit:0 -o ignore jexec b ping6 -c 3 -z 16 2001:db8:1::1
516
517	# Test routing loop protection
518	jexec b route add -6 2001:db8::1 2001:db8:1::1
519	atf_check -s exit:2 -o ignore jexec b ping6 -t 1 -c 3 2001:db8:1::1
520}
521
5226in6_cleanup()
523{
524	ovpn_cleanup
525}
526
527atf_test_case "linklocal" "cleanup"
528linklocal_head()
529{
530	atf_set descr 'Use IPv6 link-local addresses'
531	atf_set require.user root
532	atf_set require.progs openvpn
533}
534
535linklocal_body()
536{
537	ovpn_init
538	ovpn_check_version 2.7.0
539
540	l=$(vnet_mkepair)
541
542	vnet_mkjail a ${l}a
543	jexec a ifconfig ${l}a inet6 fe80::a/64 up no_dad
544	vnet_mkjail b ${l}b
545	jexec b ifconfig ${l}b inet6 fe80::b/64 up no_dad
546
547	# Sanity check
548	atf_check -s exit:0 -o ignore jexec a ping6 -c 1 fe80::b%${l}a
549
550	ovpn_start a "
551		dev ovpn0
552		dev-type tun
553		proto udp6
554
555		cipher AES-256-GCM
556		auth SHA256
557
558		local fe80::a%${l}a
559		server-ipv6 2001:db8:1::/64
560
561		ca $(atf_get_srcdir)/ca.crt
562		cert $(atf_get_srcdir)/server.crt
563		key $(atf_get_srcdir)/server.key
564		dh $(atf_get_srcdir)/dh.pem
565
566		mode server
567		script-security 2
568		auth-user-pass-verify /usr/bin/true via-env
569		topology subnet
570
571		keepalive 100 600
572	"
573	ovpn_start b "
574		dev tun0
575		dev-type tun
576
577		client
578
579		remote fe80::a%${l}b
580		auth-user-pass $(atf_get_srcdir)/user.pass
581
582		ca $(atf_get_srcdir)/ca.crt
583		cert $(atf_get_srcdir)/client.crt
584		key $(atf_get_srcdir)/client.key
585		dh $(atf_get_srcdir)/dh.pem
586
587		keepalive 100 600
588	"
589
590	# Give the tunnel time to come up
591	sleep 10
592	jexec a ifconfig
593
594	atf_check -s exit:0 -o ignore jexec b ping6 -c 3 2001:db8:1::1
595	atf_check -s exit:0 -o ignore jexec b ping6 -c 3 -z 16 2001:db8:1::1
596}
597
598linklocal_cleanup()
599{
600	ovpn_cleanup
601}
602
603atf_test_case "timeout_client" "cleanup"
604timeout_client_head()
605{
606	atf_set descr 'IPv4 in IPv4 tunnel'
607	atf_set require.user root
608	atf_set require.progs openvpn
609}
610
611timeout_client_body()
612{
613	ovpn_init
614
615	l=$(vnet_mkepair)
616
617	vnet_mkjail a ${l}a
618	jexec a ifconfig ${l}a 192.0.2.1/24 up
619	jexec a ifconfig lo0 127.0.0.1/8 up
620	vnet_mkjail b ${l}b
621	jexec b ifconfig ${l}b 192.0.2.2/24 up
622
623	# Sanity check
624	atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2
625
626	ovpn_start a "
627		dev ovpn0
628		dev-type tun
629		proto udp4
630
631		cipher AES-256-GCM
632		auth SHA256
633
634		local 192.0.2.1
635		server 198.51.100.0 255.255.255.0
636		ca $(atf_get_srcdir)/ca.crt
637		cert $(atf_get_srcdir)/server.crt
638		key $(atf_get_srcdir)/server.key
639		dh $(atf_get_srcdir)/dh.pem
640
641		mode server
642		script-security 2
643		auth-user-pass-verify /usr/bin/true via-env
644		topology subnet
645
646		keepalive 2 10
647
648		management 192.0.2.1 1234
649	"
650	ovpn_start b "
651		dev tun0
652		dev-type tun
653
654		client
655
656		remote 192.0.2.1
657		auth-user-pass $(atf_get_srcdir)/user.pass
658
659		ca $(atf_get_srcdir)/ca.crt
660		cert $(atf_get_srcdir)/client.crt
661		key $(atf_get_srcdir)/client.key
662		dh $(atf_get_srcdir)/dh.pem
663
664		keepalive 2 10
665	"
666
667	# Give the tunnel time to come up
668	sleep 10
669
670	atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1
671
672	# Kill the client
673	jexec b killall openvpn
674
675	# Now wait for the server to notice
676	sleep 15
677
678	while echo "status" | jexec a nc -N 192.0.2.1 1234 | grep 192.0.2.2; do
679		echo "Client disconnect not discovered"
680		sleep 1
681	done
682}
683
684timeout_client_cleanup()
685{
686	ovpn_cleanup
687}
688
689atf_test_case "explicit_exit" "cleanup"
690explicit_exit_head()
691{
692	atf_set descr 'Test explicit exit notification'
693	atf_set require.user root
694	atf_set require.progs openvpn
695}
696
697explicit_exit_body()
698{
699	ovpn_init
700
701	l=$(vnet_mkepair)
702
703	vnet_mkjail a ${l}a
704	jexec a ifconfig ${l}a 192.0.2.1/24 up
705	jexec a ifconfig lo0 127.0.0.1/8 up
706	vnet_mkjail b ${l}b
707	jexec b ifconfig ${l}b 192.0.2.2/24 up
708
709	# Sanity check
710	atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2
711
712	ovpn_start a "
713		dev ovpn0
714		dev-type tun
715		proto udp4
716
717		cipher AES-256-GCM
718		auth SHA256
719
720		local 192.0.2.1
721		server 198.51.100.0 255.255.255.0
722		ca $(atf_get_srcdir)/ca.crt
723		cert $(atf_get_srcdir)/server.crt
724		key $(atf_get_srcdir)/server.key
725		dh $(atf_get_srcdir)/dh.pem
726
727		mode server
728		script-security 2
729		auth-user-pass-verify /usr/bin/true via-env
730		topology subnet
731
732		management 192.0.2.1 1234
733	"
734	ovpn_start b "
735		dev tun0
736		dev-type tun
737
738		client
739
740		remote 192.0.2.1
741		auth-user-pass $(atf_get_srcdir)/user.pass
742
743		ca $(atf_get_srcdir)/ca.crt
744		cert $(atf_get_srcdir)/client.crt
745		key $(atf_get_srcdir)/client.key
746		dh $(atf_get_srcdir)/dh.pem
747
748		explicit-exit-notify
749	"
750
751	# Give the tunnel time to come up
752	sleep 10
753
754	atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1
755
756	if ! echo "status" | jexec a nc -N 192.0.2.1 1234 | grep 192.0.2.2; then
757		atf_fail "Client not found in status list!"
758	fi
759
760	# Kill the client
761	jexec b killall openvpn
762
763	while echo "status" | jexec a nc -N 192.0.2.1 1234 | grep 192.0.2.2; do
764		jexec a ps auxf
765		echo "Client disconnect not discovered"
766		sleep 1
767	done
768}
769
770explicit_exit_cleanup()
771{
772	ovpn_cleanup
773}
774
775atf_test_case "multi_client" "cleanup"
776multi_client_head()
777{
778	atf_set descr 'Multiple simultaneous clients'
779	atf_set require.user root
780	atf_set require.progs openvpn
781}
782
783multi_client_body()
784{
785	ovpn_init
786	vnet_init_bridge
787
788	bridge=$(vnet_mkbridge)
789	srv=$(vnet_mkepair)
790	one=$(vnet_mkepair)
791	two=$(vnet_mkepair)
792
793	ifconfig ${bridge} up
794
795	ifconfig ${srv}a up
796	ifconfig ${bridge} addm ${srv}a
797	ifconfig ${one}a up
798	ifconfig ${bridge} addm ${one}a
799	ifconfig ${two}a up
800	ifconfig ${bridge} addm ${two}a
801
802	vnet_mkjail srv ${srv}b
803	jexec srv ifconfig ${srv}b 192.0.2.1/24 up
804	vnet_mkjail one ${one}b
805	jexec one ifconfig ${one}b 192.0.2.2/24 up
806	vnet_mkjail two ${two}b
807	jexec two ifconfig ${two}b 192.0.2.3/24 up
808	jexec two ifconfig lo0 127.0.0.1/8 up
809	jexec two ifconfig lo0 inet alias 203.0.113.1/24
810
811	# Sanity checks
812	atf_check -s exit:0 -o ignore jexec one ping -c 1 192.0.2.1
813	atf_check -s exit:0 -o ignore jexec two ping -c 1 192.0.2.1
814
815	jexec srv sysctl net.inet.ip.forwarding=1
816
817	ovpn_start srv "
818		dev ovpn0
819		dev-type tun
820		proto udp4
821
822		cipher AES-256-GCM
823		auth SHA256
824
825		local 192.0.2.1
826		server 198.51.100.0 255.255.255.0
827
828		push \"route 203.0.113.0 255.255.255.0 198.51.100.1\"
829
830		ca $(atf_get_srcdir)/ca.crt
831		cert $(atf_get_srcdir)/server.crt
832		key $(atf_get_srcdir)/server.key
833		dh $(atf_get_srcdir)/dh.pem
834
835		mode server
836		duplicate-cn
837		script-security 2
838		auth-user-pass-verify /usr/bin/true via-env
839		topology subnet
840
841		keepalive 100 600
842
843		client-config-dir $(atf_get_srcdir)/ccd
844	"
845	ovpn_start one "
846		dev tun0
847		dev-type tun
848
849		client
850
851		remote 192.0.2.1
852		auth-user-pass $(atf_get_srcdir)/user.pass
853
854		ca $(atf_get_srcdir)/ca.crt
855		cert $(atf_get_srcdir)/client.crt
856		key $(atf_get_srcdir)/client.key
857		dh $(atf_get_srcdir)/dh.pem
858
859		keepalive 100 600
860	"
861	ovpn_start two "
862		dev tun0
863		dev-type tun
864
865		client
866
867		remote 192.0.2.1
868		auth-user-pass $(atf_get_srcdir)/user.pass
869
870		ca $(atf_get_srcdir)/ca.crt
871		cert $(atf_get_srcdir)/client2.crt
872		key $(atf_get_srcdir)/client2.key
873		dh $(atf_get_srcdir)/dh.pem
874
875		keepalive 100 600
876	"
877
878	# Give the tunnel time to come up
879	sleep 10
880
881	atf_check -s exit:0 -o ignore jexec one ping -c 3 198.51.100.1
882	atf_check -s exit:0 -o ignore jexec two ping -c 3 198.51.100.1
883
884	# Client-to-client communication
885	atf_check -s exit:0 -o ignore jexec one ping -c 3 198.51.100.3
886	atf_check -s exit:0 -o ignore jexec two ping -c 3 198.51.100.2
887
888	# iroute test
889	atf_check -s exit:0 -o ignore jexec one ping -c 3 203.0.113.1
890}
891
892multi_client_cleanup()
893{
894	ovpn_cleanup
895}
896
897atf_test_case "route_to" "cleanup"
898route_to_head()
899{
900	atf_set descr "Test pf's route-to with OpenVPN tunnels"
901	atf_set require.user root
902	atf_set require.progs openvpn
903}
904
905route_to_body()
906{
907	pft_init
908	ovpn_init
909
910	l=$(vnet_mkepair)
911	n=$(vnet_mkepair)
912
913	vnet_mkjail a ${l}a
914	jexec a ifconfig ${l}a 192.0.2.1/24 up
915	vnet_mkjail b ${l}b ${n}a
916	jexec b ifconfig ${l}b 192.0.2.2/24 up
917	jexec b ifconfig ${n}a up
918
919	# Sanity check
920	atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2
921
922	ovpn_start a "
923		dev ovpn0
924		dev-type tun
925		proto udp4
926
927		cipher AES-256-GCM
928		auth SHA256
929
930		local 192.0.2.1
931		server 198.51.100.0 255.255.255.0
932		ca $(atf_get_srcdir)/ca.crt
933		cert $(atf_get_srcdir)/server.crt
934		key $(atf_get_srcdir)/server.key
935		dh $(atf_get_srcdir)/dh.pem
936
937		mode server
938		script-security 2
939		auth-user-pass-verify /usr/bin/true via-env
940		topology subnet
941
942		keepalive 100 600
943	"
944	ovpn_start b "
945		dev tun0
946		dev-type tun
947
948		client
949
950		remote 192.0.2.1
951		auth-user-pass $(atf_get_srcdir)/user.pass
952
953		ca $(atf_get_srcdir)/ca.crt
954		cert $(atf_get_srcdir)/client.crt
955		key $(atf_get_srcdir)/client.key
956		dh $(atf_get_srcdir)/dh.pem
957
958		keepalive 100 600
959	"
960
961	# Give the tunnel time to come up
962	sleep 10
963	jexec a ifconfig ovpn0 inet alias 198.51.100.254/24
964
965	# Check the tunnel
966	atf_check -s exit:0 -o ignore jexec b ping -c 1 -S 198.51.100.2 198.51.100.1
967	atf_check -s exit:0 -o ignore jexec b ping -c 1 -S 198.51.100.2 198.51.100.254
968
969	# Break our route to .254 so that we need a route-to to make things work.
970	jexec b ifconfig ${n}a 203.0.113.1/24 up
971	jexec b route add 198.51.100.254 -interface ${n}a
972
973	# Make sure it's broken.
974	atf_check -s exit:2 -o ignore jexec b ping -c 1 -S 198.51.100.2 198.51.100.254
975
976	jexec b pfctl -e
977	pft_set_rules b \
978		"pass out route-to (tun0 198.51.100.1) proto icmp from 198.51.100.2 "
979	atf_check -s exit:0 -o ignore jexec b ping -c 3 -S 198.51.100.2 198.51.100.254
980}
981
982route_to_cleanup()
983{
984	ovpn_cleanup
985	pft_cleanup
986}
987
988atf_test_case "ra" "cleanup"
989ra_head()
990{
991	atf_set descr 'Remote access with multiple clients'
992	atf_set require.user root
993	atf_set require.progs openvpn
994}
995
996ra_body()
997{
998	ovpn_init
999	vnet_init_bridge
1000
1001	bridge=$(vnet_mkbridge)
1002	srv=$(vnet_mkepair)
1003	lan=$(vnet_mkepair)
1004	one=$(vnet_mkepair)
1005	two=$(vnet_mkepair)
1006
1007	ifconfig ${bridge} up
1008
1009	ifconfig ${srv}a up
1010	ifconfig ${bridge} addm ${srv}a
1011	ifconfig ${one}a up
1012	ifconfig ${bridge} addm ${one}a
1013	ifconfig ${two}a up
1014	ifconfig ${bridge} addm ${two}a
1015
1016	vnet_mkjail srv ${srv}b ${lan}a
1017	jexec srv ifconfig lo0 inet 127.0.0.1/8 up
1018	jexec srv ifconfig ${srv}b 192.0.2.1/24 up
1019	jexec srv ifconfig ${lan}a 203.0.113.1/24 up
1020	vnet_mkjail lan ${lan}b
1021	jexec lan ifconfig lo0 inet 127.0.0.1/8 up
1022	jexec lan ifconfig ${lan}b 203.0.113.2/24 up
1023	jexec lan route add default 203.0.113.1
1024	vnet_mkjail one ${one}b
1025	jexec one ifconfig lo0 inet 127.0.0.1/8 up
1026	jexec one ifconfig ${one}b 192.0.2.2/24 up
1027	vnet_mkjail two ${two}b
1028	jexec two ifconfig lo0 inet 127.0.0.1/8 up
1029	jexec two ifconfig ${two}b 192.0.2.3/24 up
1030
1031	# Sanity checks
1032	atf_check -s exit:0 -o ignore jexec one ping -c 1 192.0.2.1
1033	atf_check -s exit:0 -o ignore jexec two ping -c 1 192.0.2.1
1034	atf_check -s exit:0 -o ignore jexec srv ping -c 1 203.0.113.2
1035
1036	jexec srv sysctl net.inet.ip.forwarding=1
1037
1038	ovpn_start srv "
1039		dev ovpn0
1040		dev-type tun
1041		proto udp4
1042
1043		cipher AES-256-GCM
1044		auth SHA256
1045
1046		local 192.0.2.1
1047		server 198.51.100.0 255.255.255.0
1048
1049		push \"route 203.0.113.0 255.255.255.0\"
1050
1051		ca $(atf_get_srcdir)/ca.crt
1052		cert $(atf_get_srcdir)/server.crt
1053		key $(atf_get_srcdir)/server.key
1054		dh $(atf_get_srcdir)/dh.pem
1055
1056		mode server
1057		duplicate-cn
1058		script-security 2
1059		auth-user-pass-verify /usr/bin/true via-env
1060		topology subnet
1061
1062		keepalive 100 600
1063	"
1064	ovpn_start one "
1065		dev tun0
1066		dev-type tun
1067
1068		client
1069
1070		remote 192.0.2.1
1071		auth-user-pass $(atf_get_srcdir)/user.pass
1072
1073		ca $(atf_get_srcdir)/ca.crt
1074		cert $(atf_get_srcdir)/client.crt
1075		key $(atf_get_srcdir)/client.key
1076		dh $(atf_get_srcdir)/dh.pem
1077
1078		keepalive 100 600
1079	"
1080	sleep 2
1081	ovpn_start two "
1082		dev tun0
1083		dev-type tun
1084
1085		client
1086
1087		remote 192.0.2.1
1088		auth-user-pass $(atf_get_srcdir)/user.pass
1089
1090		ca $(atf_get_srcdir)/ca.crt
1091		cert $(atf_get_srcdir)/client2.crt
1092		key $(atf_get_srcdir)/client2.key
1093		dh $(atf_get_srcdir)/dh.pem
1094
1095		keepalive 100 600
1096	"
1097
1098	# Give the tunnel time to come up
1099	sleep 10
1100
1101	atf_check -s exit:0 -o ignore jexec one ping -c 1 198.51.100.1
1102	atf_check -s exit:0 -o ignore jexec two ping -c 1 198.51.100.1
1103
1104	# Client-to-client communication
1105	atf_check -s exit:0 -o ignore jexec one ping -c 1 198.51.100.3
1106	atf_check -s exit:0 -o ignore jexec one ping -c 1 198.51.100.2
1107	atf_check -s exit:0 -o ignore jexec two ping -c 1 198.51.100.2
1108	atf_check -s exit:0 -o ignore jexec two ping -c 1 198.51.100.3
1109
1110	# RA test
1111	atf_check -s exit:0 -o ignore jexec one ping -c 1 203.0.113.1
1112	atf_check -s exit:0 -o ignore jexec two ping -c 1 203.0.113.1
1113
1114	atf_check -s exit:0 -o ignore jexec srv ping -c 1 -S 203.0.113.1 198.51.100.2
1115	atf_check -s exit:0 -o ignore jexec srv ping -c 1 -S 203.0.113.1 198.51.100.3
1116
1117	atf_check -s exit:0 -o ignore jexec one ping -c 1 203.0.113.2
1118	atf_check -s exit:0 -o ignore jexec two ping -c 1 203.0.113.2
1119
1120	atf_check -s exit:0 -o ignore jexec lan ping -c 1 198.51.100.1
1121	atf_check -s exit:0 -o ignore jexec lan ping -c 1 198.51.100.2
1122	atf_check -s exit:0 -o ignore jexec lan ping -c 1 198.51.100.3
1123	atf_check -s exit:2 -o ignore jexec lan ping -c 1 198.51.100.4
1124}
1125
1126ra_cleanup()
1127{
1128	ovpn_cleanup
1129}
1130
1131ovpn_algo_body()
1132{
1133	algo=$1
1134
1135	ovpn_init
1136
1137	l=$(vnet_mkepair)
1138
1139	vnet_mkjail a ${l}a
1140	jexec a ifconfig ${l}a 192.0.2.1/24 up
1141	vnet_mkjail b ${l}b
1142	jexec b ifconfig ${l}b 192.0.2.2/24 up
1143
1144	# Sanity check
1145	atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2
1146
1147	ovpn_start a "
1148		dev ovpn0
1149		dev-type tun
1150		proto udp4
1151
1152		cipher ${algo}
1153		data-ciphers ${algo}
1154		auth SHA256
1155
1156		local 192.0.2.1
1157		server 198.51.100.0 255.255.255.0
1158		ca $(atf_get_srcdir)/ca.crt
1159		cert $(atf_get_srcdir)/server.crt
1160		key $(atf_get_srcdir)/server.key
1161		dh $(atf_get_srcdir)/dh.pem
1162
1163		mode server
1164		script-security 2
1165		auth-user-pass-verify /usr/bin/true via-env
1166		topology subnet
1167
1168		keepalive 100 600
1169	"
1170	ovpn_start b "
1171		dev tun0
1172		dev-type tun
1173
1174		client
1175
1176		cipher ${algo}
1177		data-ciphers ${algo}
1178
1179		remote 192.0.2.1
1180		auth-user-pass $(atf_get_srcdir)/user.pass
1181
1182		ca $(atf_get_srcdir)/ca.crt
1183		cert $(atf_get_srcdir)/client.crt
1184		key $(atf_get_srcdir)/client.key
1185		dh $(atf_get_srcdir)/dh.pem
1186
1187		keepalive 100 600
1188	"
1189
1190	# Give the tunnel time to come up
1191	sleep 10
1192
1193	atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1
1194}
1195
1196atf_test_case "chacha" "cleanup"
1197chacha_head()
1198{
1199	atf_set descr 'Test DCO with the chacha algorithm'
1200	atf_set require.user root
1201	atf_set require.progs openvpn
1202}
1203
1204chacha_body()
1205{
1206	ovpn_algo_body CHACHA20-POLY1305
1207}
1208
1209chacha_cleanup()
1210{
1211	ovpn_cleanup
1212}
1213
1214atf_test_case "gcm_128" "cleanup"
1215gcm_128_head()
1216{
1217	atf_set descr 'Test DCO with AES-128-GCM'
1218	atf_set require.user root
1219	atf_set require.progs openvpn
1220}
1221
1222gcm_128_body()
1223{
1224	ovpn_algo_body AES-128-GCM
1225}
1226
1227gcm_128_cleanup()
1228{
1229	ovpn_cleanup
1230}
1231
1232atf_test_case "destroy_unused" "cleanup"
1233destroy_unused_head()
1234{
1235	atf_set descr 'Destroy an if_ovpn interface before it is used'
1236	atf_set require.user root
1237}
1238
1239destroy_unused_body()
1240{
1241	ovpn_init
1242
1243	intf=$(ifconfig ovpn create)
1244	atf_check -s exit:0 \
1245	    ifconfig ${intf} destroy
1246}
1247
1248destroy_unused_cleanup()
1249{
1250	ovpn_cleanup
1251}
1252
1253atf_test_case "multihome4" "cleanup"
1254multihome4_head()
1255{
1256	atf_set descr 'Test multihome IPv4 with OpenVPN'
1257	atf_set require.user root
1258	atf_set require.progs openvpn
1259}
1260
1261multihome4_body()
1262{
1263	pft_init
1264	ovpn_init
1265
1266	l=$(vnet_mkepair)
1267
1268	vnet_mkjail a ${l}a
1269	atf_check jexec a ifconfig ${l}a inet 192.0.2.1/24
1270	atf_check jexec a ifconfig ${l}a alias 192.0.2.2/24
1271	vnet_mkjail b ${l}b
1272	atf_check jexec b ifconfig ${l}b inet 192.0.2.3/24
1273
1274	# Sanity check
1275	atf_check -s exit:0 -o ignore jexec b ping -c 1 192.0.2.1
1276	atf_check -s exit:0 -o ignore jexec b ping -c 1 192.0.2.2
1277
1278	ovpn_start a "
1279		dev ovpn0
1280		dev-type tun
1281		proto udp4
1282
1283		cipher AES-256-GCM
1284		auth SHA256
1285
1286		multihome
1287		server 198.51.100.0 255.255.255.0
1288		ca $(atf_get_srcdir)/ca.crt
1289		cert $(atf_get_srcdir)/server.crt
1290		key $(atf_get_srcdir)/server.key
1291		dh $(atf_get_srcdir)/dh.pem
1292
1293		mode server
1294		script-security 2
1295		auth-user-pass-verify /usr/bin/true via-env
1296		topology subnet
1297
1298		keepalive 100 600
1299	"
1300	ovpn_start b "
1301		dev tun0
1302		dev-type tun
1303
1304		client
1305
1306		remote 192.0.2.2
1307		auth-user-pass $(atf_get_srcdir)/user.pass
1308
1309		ca $(atf_get_srcdir)/ca.crt
1310		cert $(atf_get_srcdir)/client.crt
1311		key $(atf_get_srcdir)/client.key
1312		dh $(atf_get_srcdir)/dh.pem
1313
1314		keepalive 100 600
1315	"
1316
1317	# Block packets from the primary address, openvpn should only use the
1318	# configured remote address.
1319	jexec b pfctl -e
1320	pft_set_rules b \
1321		"block in quick from 192.0.2.1 to any" \
1322		"pass all"
1323
1324	# Give the tunnel time to come up
1325	sleep 10
1326
1327	atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1
1328}
1329
1330multihome4_cleanup()
1331{
1332	ovpn_cleanup
1333	pft_cleanup
1334}
1335
1336atf_test_case "multihome6" "cleanup"
1337multihome6_head()
1338{
1339	atf_set descr 'Test multihome IPv6 with OpenVPN'
1340	atf_set require.user root
1341	atf_set require.progs openvpn
1342}
1343
1344multihome6_body()
1345{
1346	ovpn_init
1347
1348	l=$(vnet_mkepair)
1349
1350	vnet_mkjail a ${l}a
1351	atf_check jexec a ifconfig ${l}a inet6 2001:db8::1/64 no_dad
1352	atf_check jexec a ifconfig ${l}a inet6 alias 2001:db8::2/64 no_dad
1353	vnet_mkjail b ${l}b
1354	atf_check jexec b ifconfig ${l}b inet6 2001:db8::3/64 no_dad
1355
1356	# Sanity check
1357	atf_check -s exit:0 -o ignore jexec b ping6 -c 1 2001:db8::1
1358	atf_check -s exit:0 -o ignore jexec b ping6 -c 1 2001:db8::2
1359
1360	ovpn_start a "
1361		dev ovpn0
1362		dev-type tun
1363		proto udp6
1364
1365		cipher AES-256-GCM
1366		auth SHA256
1367
1368		multihome
1369		server-ipv6 2001:db8:1::/64
1370
1371		ca $(atf_get_srcdir)/ca.crt
1372		cert $(atf_get_srcdir)/server.crt
1373		key $(atf_get_srcdir)/server.key
1374		dh $(atf_get_srcdir)/dh.pem
1375
1376		mode server
1377		script-security 2
1378		auth-user-pass-verify /usr/bin/true via-env
1379		topology subnet
1380
1381		keepalive 100 600
1382	"
1383	ovpn_start b "
1384		dev tun0
1385		dev-type tun
1386
1387		client
1388
1389		remote 2001:db8::2
1390		auth-user-pass $(atf_get_srcdir)/user.pass
1391
1392		ca $(atf_get_srcdir)/ca.crt
1393		cert $(atf_get_srcdir)/client.crt
1394		key $(atf_get_srcdir)/client.key
1395		dh $(atf_get_srcdir)/dh.pem
1396
1397		keepalive 100 600
1398	"
1399
1400	# Block packets from the primary address, openvpn should only use the
1401	# configured remote address.
1402	jexec b pfctl -e
1403	pft_set_rules b \
1404		"block in quick from 2001:db8::1 to any" \
1405		"pass all"
1406
1407	# Give the tunnel time to come up
1408	sleep 10
1409
1410	atf_check -s exit:0 -o ignore jexec b ping6 -c 3 2001:db8:1::1
1411	atf_check -s exit:0 -o ignore jexec b ping6 -c 3 -z 16 2001:db8:1::1
1412}
1413
1414multihome6_cleanup()
1415{
1416	ovpn_cleanup
1417	pft_cleanup
1418}
1419
1420atf_test_case "float" "cleanup"
1421float_head()
1422{
1423	atf_set descr 'Test peer float notification'
1424	atf_set require.user root
1425}
1426
1427float_body()
1428{
1429	ovpn_init
1430	ovpn_check_version 2.7.0
1431
1432	l=$(vnet_mkepair)
1433
1434	vnet_mkjail a ${l}a
1435	jexec a ifconfig ${l}a 192.0.2.1/24 up
1436	jexec a ifconfig lo0 127.0.0.1/8 up
1437	vnet_mkjail b ${l}b
1438	jexec b ifconfig ${l}b 192.0.2.2/24 up
1439
1440	# Sanity check
1441	atf_check -s exit:0 -o ignore jexec a ping -c 1 192.0.2.2
1442
1443	ovpn_start a "
1444		dev ovpn0
1445		dev-type tun
1446		proto udp4
1447
1448		cipher AES-256-GCM
1449		auth SHA256
1450
1451		local 192.0.2.1
1452		server 198.51.100.0 255.255.255.0
1453		ca $(atf_get_srcdir)/ca.crt
1454		cert $(atf_get_srcdir)/server.crt
1455		key $(atf_get_srcdir)/server.key
1456		dh $(atf_get_srcdir)/dh.pem
1457
1458		mode server
1459		script-security 2
1460		auth-user-pass-verify /usr/bin/true via-env
1461		topology subnet
1462
1463		keepalive 2 10
1464
1465		management 192.0.2.1 1234
1466	"
1467	ovpn_start b "
1468		dev tun0
1469		dev-type tun
1470
1471		client
1472
1473		remote 192.0.2.1
1474		auth-user-pass $(atf_get_srcdir)/user.pass
1475
1476		ca $(atf_get_srcdir)/ca.crt
1477		cert $(atf_get_srcdir)/client.crt
1478		key $(atf_get_srcdir)/client.key
1479		dh $(atf_get_srcdir)/dh.pem
1480
1481		keepalive 2 10
1482	"
1483
1484	# Give the tunnel time to come up
1485	sleep 10
1486
1487	atf_check -s exit:0 -o ignore jexec b ping -c 3 198.51.100.1
1488
1489	# We expect the client on 192.0.2.2
1490	if ! echo "status" | jexec a nc -N 192.0.2.1 1234 | grep 192.0.2.2; then
1491		atf_fail "Client not found in status list!"
1492	fi
1493
1494	# Now change the client IP
1495	jexec b ifconfig ${l}b 192.0.2.3/24 up
1496
1497	# And wait for keepalives to trigger the float notification
1498	sleep 5
1499
1500	# So the client now has the new address in userspace
1501	if ! echo "status" | jexec a nc -N 192.0.2.1 1234 | grep 192.0.2.3; then
1502		atf_fail "Client not found in status list!"
1503	fi
1504}
1505
1506float_cleanup()
1507{
1508	ovpn_cleanup
1509}
1510
1511atf_init_test_cases()
1512{
1513	atf_add_test_case "4in4"
1514	atf_add_test_case "bz283426"
1515	atf_add_test_case "4mapped"
1516	atf_add_test_case "6in4"
1517	atf_add_test_case "6in6"
1518	atf_add_test_case "4in6"
1519	atf_add_test_case "linklocal"
1520	atf_add_test_case "timeout_client"
1521	atf_add_test_case "explicit_exit"
1522	atf_add_test_case "multi_client"
1523	atf_add_test_case "route_to"
1524	atf_add_test_case "ra"
1525	atf_add_test_case "chacha"
1526	atf_add_test_case "gcm_128"
1527	atf_add_test_case "destroy_unused"
1528	atf_add_test_case "multihome4"
1529	atf_add_test_case "multihome6"
1530	atf_add_test_case "float"
1531}
1532