xref: /freebsd/tests/sys/net/if_wg.sh (revision 4d846d260e2b9a3d4d0a701462568268cbfe7a5b)
18fb97396SJohn Baldwin# $FreeBSD$
28fb97396SJohn Baldwin#
3*4d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause
48fb97396SJohn Baldwin#
58fb97396SJohn Baldwin# Copyright (c) 2021 The FreeBSD Foundation
68fb97396SJohn Baldwin#
78fb97396SJohn Baldwin# This software was developed by Mark Johnston under sponsorship
88fb97396SJohn Baldwin# from the FreeBSD Foundation.
98fb97396SJohn Baldwin#
108fb97396SJohn Baldwin# Redistribution and use in source and binary forms, with or without
118fb97396SJohn Baldwin# modification, are permitted provided that the following conditions
128fb97396SJohn Baldwin# are met:
138fb97396SJohn Baldwin# 1. Redistributions of source code must retain the above copyright
148fb97396SJohn Baldwin#    notice, this list of conditions and the following disclaimer.
158fb97396SJohn Baldwin# 2. Redistributions in binary form must reproduce the above copyright
168fb97396SJohn Baldwin#    notice, this list of conditions and the following disclaimer in the
178fb97396SJohn Baldwin#    documentation and/or other materials provided with the distribution.
188fb97396SJohn Baldwin#
198fb97396SJohn Baldwin# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
208fb97396SJohn Baldwin# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
218fb97396SJohn Baldwin# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
228fb97396SJohn Baldwin# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
238fb97396SJohn Baldwin# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
248fb97396SJohn Baldwin# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
258fb97396SJohn Baldwin# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
268fb97396SJohn Baldwin# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
278fb97396SJohn Baldwin# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
288fb97396SJohn Baldwin# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
298fb97396SJohn Baldwin# SUCH DAMAGE.
308fb97396SJohn Baldwin
318fb97396SJohn Baldwin. $(atf_get_srcdir)/../common/vnet.subr
328fb97396SJohn Baldwin
338fb97396SJohn Baldwinatf_test_case "wg_basic" "cleanup"
348fb97396SJohn Baldwinwg_basic_head()
358fb97396SJohn Baldwin{
368fb97396SJohn Baldwin	atf_set descr 'Create a wg(4) tunnel over an epair and pass traffic between jails'
378fb97396SJohn Baldwin	atf_set require.user root
388fb97396SJohn Baldwin}
398fb97396SJohn Baldwin
408fb97396SJohn Baldwinwg_basic_body()
418fb97396SJohn Baldwin{
428fb97396SJohn Baldwin	local epair pri1 pri2 pub1 pub2 wg1 wg2
438fb97396SJohn Baldwin        local endpoint1 endpoint2 tunnel1 tunnel2
448fb97396SJohn Baldwin
45d22c5c42SOlivier Cochard	kldload -n if_wg || atf_skip "This test requires if_wg and could not load it"
468fb97396SJohn Baldwin
478fb97396SJohn Baldwin	pri1=$(wg genkey)
488fb97396SJohn Baldwin	pri2=$(wg genkey)
498fb97396SJohn Baldwin
508fb97396SJohn Baldwin	endpoint1=192.168.2.1
518fb97396SJohn Baldwin	endpoint2=192.168.2.2
528fb97396SJohn Baldwin	tunnel1=169.254.0.1
538fb97396SJohn Baldwin	tunnel2=169.254.0.2
548fb97396SJohn Baldwin
558fb97396SJohn Baldwin	epair=$(vnet_mkepair)
568fb97396SJohn Baldwin
578fb97396SJohn Baldwin	vnet_init
588fb97396SJohn Baldwin
598fb97396SJohn Baldwin	vnet_mkjail wgtest1 ${epair}a
608fb97396SJohn Baldwin	vnet_mkjail wgtest2 ${epair}b
618fb97396SJohn Baldwin
628fb97396SJohn Baldwin	jexec wgtest1 ifconfig ${epair}a ${endpoint1}/24 up
638fb97396SJohn Baldwin	jexec wgtest2 ifconfig ${epair}b ${endpoint2}/24 up
648fb97396SJohn Baldwin
658fb97396SJohn Baldwin	wg1=$(jexec wgtest1 ifconfig wg create)
668fb97396SJohn Baldwin	echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \
678fb97396SJohn Baldwin	    private-key /dev/stdin
688fb97396SJohn Baldwin	pub1=$(jexec wgtest1 wg show $wg1 public-key)
698fb97396SJohn Baldwin	wg2=$(jexec wgtest2 ifconfig wg create)
708fb97396SJohn Baldwin	echo "$pri2" | jexec wgtest2 wg set $wg2 listen-port 12345 \
718fb97396SJohn Baldwin	    private-key /dev/stdin
728fb97396SJohn Baldwin	pub2=$(jexec wgtest2 wg show $wg2 public-key)
738fb97396SJohn Baldwin
748fb97396SJohn Baldwin	atf_check -s exit:0 -o ignore \
758fb97396SJohn Baldwin	    jexec wgtest1 wg set $wg1 peer "$pub2" \
768fb97396SJohn Baldwin	    endpoint ${endpoint2}:12345 allowed-ips ${tunnel2}/32
778fb97396SJohn Baldwin	atf_check -s exit:0 \
788fb97396SJohn Baldwin	    jexec wgtest1 ifconfig $wg1 inet ${tunnel1}/24 up
798fb97396SJohn Baldwin
808fb97396SJohn Baldwin	atf_check -s exit:0 -o ignore \
818fb97396SJohn Baldwin	    jexec wgtest2 wg set $wg2 peer "$pub1" \
828fb97396SJohn Baldwin	    endpoint ${endpoint1}:12345 allowed-ips ${tunnel1}/32
838fb97396SJohn Baldwin	atf_check -s exit:0 \
848fb97396SJohn Baldwin	    jexec wgtest2 ifconfig $wg2 inet ${tunnel2}/24 up
858fb97396SJohn Baldwin
868fb97396SJohn Baldwin	# Generous timeout since the handshake takes some time.
878fb97396SJohn Baldwin	atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 $tunnel2
888fb97396SJohn Baldwin	atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1
898fb97396SJohn Baldwin}
908fb97396SJohn Baldwin
918fb97396SJohn Baldwinwg_basic_cleanup()
928fb97396SJohn Baldwin{
938fb97396SJohn Baldwin	vnet_cleanup
948fb97396SJohn Baldwin}
958fb97396SJohn Baldwin
968fb97396SJohn Baldwin# The kernel is expected to silently ignore any attempt to add a peer with a
978fb97396SJohn Baldwin# public key identical to the host's.
988fb97396SJohn Baldwinatf_test_case "wg_key_peerdev_shared" "cleanup"
998fb97396SJohn Baldwinwg_key_peerdev_shared_head()
1008fb97396SJohn Baldwin{
1018fb97396SJohn Baldwin	atf_set descr 'Create a wg(4) interface with a shared pubkey between device and a peer'
1028fb97396SJohn Baldwin	atf_set require.user root
1038fb97396SJohn Baldwin}
1048fb97396SJohn Baldwin
1058fb97396SJohn Baldwinwg_key_peerdev_shared_body()
1068fb97396SJohn Baldwin{
1078fb97396SJohn Baldwin	local epair pri1 pub1 wg1
1088fb97396SJohn Baldwin        local endpoint1 tunnel1
1098fb97396SJohn Baldwin
110d22c5c42SOlivier Cochard	kldload -n if_wg || atf_skip "This test requires if_wg and could not load it"
1118fb97396SJohn Baldwin
1128fb97396SJohn Baldwin	pri1=$(wg genkey)
1138fb97396SJohn Baldwin
1148fb97396SJohn Baldwin	endpoint1=192.168.2.1
1158fb97396SJohn Baldwin	tunnel1=169.254.0.1
1168fb97396SJohn Baldwin
1178fb97396SJohn Baldwin	vnet_mkjail wgtest1
1188fb97396SJohn Baldwin
1198fb97396SJohn Baldwin	wg1=$(jexec wgtest1 ifconfig wg create)
1208fb97396SJohn Baldwin	echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \
1218fb97396SJohn Baldwin	    private-key /dev/stdin
1228fb97396SJohn Baldwin	pub1=$(jexec wgtest1 wg show $wg1 public-key)
1238fb97396SJohn Baldwin
1248fb97396SJohn Baldwin	atf_check -s exit:0 \
1258fb97396SJohn Baldwin	    jexec wgtest1 wg set ${wg1} peer "${pub1}" \
1268fb97396SJohn Baldwin	    allowed-ips "${tunnel1}/32"
1278fb97396SJohn Baldwin
1288fb97396SJohn Baldwin	atf_check -o empty jexec wgtest1 wg show ${wg1} peers
1298fb97396SJohn Baldwin}
1308fb97396SJohn Baldwin
1318fb97396SJohn Baldwinwg_key_peerdev_shared_cleanup()
1328fb97396SJohn Baldwin{
1338fb97396SJohn Baldwin	vnet_cleanup
1348fb97396SJohn Baldwin}
1358fb97396SJohn Baldwin
1368fb97396SJohn Baldwin# When a wg(8) interface has a private key reassigned that corresponds to the
1378fb97396SJohn Baldwin# public key already on a peer, the kernel is expected to deconfigure the peer
1388fb97396SJohn Baldwin# to resolve the conflict.
1398fb97396SJohn Baldwinatf_test_case "wg_key_peerdev_makeshared" "cleanup"
1408fb97396SJohn Baldwinwg_key_peerdev_makeshared_head()
1418fb97396SJohn Baldwin{
1428fb97396SJohn Baldwin	atf_set descr 'Create a wg(4) interface and assign peer key to device'
1438fb97396SJohn Baldwin	atf_set require.progs wg
1448fb97396SJohn Baldwin}
1458fb97396SJohn Baldwin
1468fb97396SJohn Baldwinwg_key_peerdev_makeshared_body()
1478fb97396SJohn Baldwin{
1488fb97396SJohn Baldwin	local epair pri1 pub1 pri2 wg1 wg2
1498fb97396SJohn Baldwin        local endpoint1 tunnel1
1508fb97396SJohn Baldwin
151d22c5c42SOlivier Cochard	kldload -n if_wg || atf_skip "This test requires if_wg and could not load it"
1528fb97396SJohn Baldwin
1538fb97396SJohn Baldwin	pri1=$(wg genkey)
1548fb97396SJohn Baldwin	pri2=$(wg genkey)
1558fb97396SJohn Baldwin
1568fb97396SJohn Baldwin	endpoint1=192.168.2.1
1578fb97396SJohn Baldwin	tunnel1=169.254.0.1
1588fb97396SJohn Baldwin
1598fb97396SJohn Baldwin	vnet_mkjail wgtest1
1608fb97396SJohn Baldwin
1618fb97396SJohn Baldwin	wg1=$(jexec wgtest1 ifconfig wg create)
1628fb97396SJohn Baldwin	echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \
1638fb97396SJohn Baldwin	    private-key /dev/stdin
1648fb97396SJohn Baldwin	pub1=$(jexec wgtest1 wg show $wg1 public-key)
1658fb97396SJohn Baldwin	wg2=$(jexec wgtest1 ifconfig wg create)
1668fb97396SJohn Baldwin	echo "$pri2" | jexec wgtest1 wg set $wg2 listen-port 12345 \
1678fb97396SJohn Baldwin	    private-key /dev/stdin
1688fb97396SJohn Baldwin
1698fb97396SJohn Baldwin	atf_check -s exit:0 -o ignore \
1708fb97396SJohn Baldwin	    jexec wgtest1 wg set ${wg2} peer "${pub1}" \
1718fb97396SJohn Baldwin	    allowed-ips "${tunnel1}/32"
1728fb97396SJohn Baldwin
1738fb97396SJohn Baldwin	atf_check -o not-empty jexec wgtest1 wg show ${wg2} peers
1748fb97396SJohn Baldwin
1758fb97396SJohn Baldwin	jexec wgtest1 sh -c "echo '${pri1}' > pri1"
1768fb97396SJohn Baldwin
1778fb97396SJohn Baldwin	atf_check -s exit:0 \
1788fb97396SJohn Baldwin	   jexec wgtest1 wg set ${wg2} private-key pri1
1798fb97396SJohn Baldwin
1808fb97396SJohn Baldwin	atf_check -o empty jexec wgtest1 wg show ${wg2} peers
1818fb97396SJohn Baldwin}
1828fb97396SJohn Baldwin
1838fb97396SJohn Baldwinwg_key_peerdev_makeshared_cleanup()
1848fb97396SJohn Baldwin{
1858fb97396SJohn Baldwin	vnet_cleanup
1868fb97396SJohn Baldwin}
1878fb97396SJohn Baldwin
18896f4ab26SKyle Evans# The kernel is expected to create the wg socket in the jail context that the
18996f4ab26SKyle Evans# wg interface was created in, even if the interface is moved to a different
19096f4ab26SKyle Evans# vnet.
19196f4ab26SKyle Evansatf_test_case "wg_vnet_parent_routing" "cleanup"
19296f4ab26SKyle Evanswg_vnet_parent_routing_head()
19396f4ab26SKyle Evans{
19496f4ab26SKyle Evans	atf_set descr 'Create a wg(4) tunnel without epairs and pass traffic between jails'
19596f4ab26SKyle Evans	atf_set require.user root
19696f4ab26SKyle Evans}
19796f4ab26SKyle Evans
19896f4ab26SKyle Evanswg_vnet_parent_routing_body()
19996f4ab26SKyle Evans{
20096f4ab26SKyle Evans	local pri1 pri2 pub1 pub2 wg1 wg2
20196f4ab26SKyle Evans        local tunnel1 tunnel2
20296f4ab26SKyle Evans
20396f4ab26SKyle Evans	kldload -n if_wg
20496f4ab26SKyle Evans
20596f4ab26SKyle Evans	pri1=$(wg genkey)
20696f4ab26SKyle Evans	pri2=$(wg genkey)
20796f4ab26SKyle Evans
20896f4ab26SKyle Evans	tunnel1=169.254.0.1
20996f4ab26SKyle Evans	tunnel2=169.254.0.2
21096f4ab26SKyle Evans
21196f4ab26SKyle Evans	vnet_init
21296f4ab26SKyle Evans
21396f4ab26SKyle Evans	wg1=$(ifconfig wg create)
21496f4ab26SKyle Evans	wg2=$(ifconfig wg create)
21596f4ab26SKyle Evans
21696f4ab26SKyle Evans	vnet_mkjail wgtest1 ${wg1}
21796f4ab26SKyle Evans	vnet_mkjail wgtest2 ${wg2}
21896f4ab26SKyle Evans
21996f4ab26SKyle Evans	echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \
22096f4ab26SKyle Evans	    private-key /dev/stdin
22196f4ab26SKyle Evans	pub1=$(jexec wgtest1 wg show $wg1 public-key)
22296f4ab26SKyle Evans	echo "$pri2" | jexec wgtest2 wg set $wg2 listen-port 12346 \
22396f4ab26SKyle Evans	    private-key /dev/stdin
22496f4ab26SKyle Evans	pub2=$(jexec wgtest2 wg show $wg2 public-key)
22596f4ab26SKyle Evans
22696f4ab26SKyle Evans	atf_check -s exit:0 -o ignore \
22796f4ab26SKyle Evans	    jexec wgtest1 wg set $wg1 peer "$pub2" \
22896f4ab26SKyle Evans	    endpoint 127.0.0.1:12346 allowed-ips ${tunnel2}/32
22996f4ab26SKyle Evans	atf_check -s exit:0 \
23096f4ab26SKyle Evans	    jexec wgtest1 ifconfig $wg1 inet ${tunnel1}/24 up
23196f4ab26SKyle Evans
23296f4ab26SKyle Evans	atf_check -s exit:0 -o ignore \
23396f4ab26SKyle Evans	    jexec wgtest2 wg set $wg2 peer "$pub1" \
23496f4ab26SKyle Evans	    endpoint 127.0.0.1:12345 allowed-ips ${tunnel1}/32
23596f4ab26SKyle Evans	atf_check -s exit:0 \
23696f4ab26SKyle Evans	    jexec wgtest2 ifconfig $wg2 inet ${tunnel2}/24 up
23796f4ab26SKyle Evans
23896f4ab26SKyle Evans	# Sanity check ICMP counters; should clearly be nothing on these new
23996f4ab26SKyle Evans	# jails.  We'll check them as we go to ensure that the ICMP packets
24096f4ab26SKyle Evans	# generated really are being handled by the jails' vnets.
24196f4ab26SKyle Evans	atf_check -o not-match:"histogram" jexec wgtest1 netstat -s -p icmp
24296f4ab26SKyle Evans	atf_check -o not-match:"histogram" jexec wgtest2 netstat -s -p icmp
24396f4ab26SKyle Evans
24496f4ab26SKyle Evans	# Generous timeout since the handshake takes some time.
24596f4ab26SKyle Evans	atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 $tunnel2
24696f4ab26SKyle Evans	atf_check -o match:"echo reply: 1" jexec wgtest1 netstat -s -p icmp
24796f4ab26SKyle Evans	atf_check -o match:"echo: 1" jexec wgtest2 netstat -s -p icmp
24896f4ab26SKyle Evans
24996f4ab26SKyle Evans	atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1
25096f4ab26SKyle Evans	atf_check -o match:"echo reply: 1" jexec wgtest2 netstat -s -p icmp
25196f4ab26SKyle Evans	atf_check -o match:"echo: 1" jexec wgtest1 netstat -s -p icmp
25296f4ab26SKyle Evans}
25396f4ab26SKyle Evans
25496f4ab26SKyle Evanswg_vnet_parent_routing_cleanup()
25596f4ab26SKyle Evans{
25696f4ab26SKyle Evans	vnet_cleanup
25796f4ab26SKyle Evans}
25896f4ab26SKyle Evans
2598fb97396SJohn Baldwinatf_init_test_cases()
2608fb97396SJohn Baldwin{
2618fb97396SJohn Baldwin	atf_add_test_case "wg_basic"
2628fb97396SJohn Baldwin	atf_add_test_case "wg_key_peerdev_shared"
2638fb97396SJohn Baldwin	atf_add_test_case "wg_key_peerdev_makeshared"
26496f4ab26SKyle Evans	atf_add_test_case "wg_vnet_parent_routing"
2658fb97396SJohn Baldwin}
266