xref: /freebsd/tests/sys/net/if_wg.sh (revision 96f4ab26633a457c52fdb9c45f48dcb052b408a4)
18fb97396SJohn Baldwin# $FreeBSD$
28fb97396SJohn Baldwin#
38fb97396SJohn Baldwin# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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	# Workaround for PR 254212.
638fb97396SJohn Baldwin	jexec wgtest1 ifconfig lo0 up
648fb97396SJohn Baldwin	jexec wgtest2 ifconfig lo0 up
658fb97396SJohn Baldwin
668fb97396SJohn Baldwin	jexec wgtest1 ifconfig ${epair}a ${endpoint1}/24 up
678fb97396SJohn Baldwin	jexec wgtest2 ifconfig ${epair}b ${endpoint2}/24 up
688fb97396SJohn Baldwin
698fb97396SJohn Baldwin	wg1=$(jexec wgtest1 ifconfig wg create)
708fb97396SJohn Baldwin	echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \
718fb97396SJohn Baldwin	    private-key /dev/stdin
728fb97396SJohn Baldwin	pub1=$(jexec wgtest1 wg show $wg1 public-key)
738fb97396SJohn Baldwin	wg2=$(jexec wgtest2 ifconfig wg create)
748fb97396SJohn Baldwin	echo "$pri2" | jexec wgtest2 wg set $wg2 listen-port 12345 \
758fb97396SJohn Baldwin	    private-key /dev/stdin
768fb97396SJohn Baldwin	pub2=$(jexec wgtest2 wg show $wg2 public-key)
778fb97396SJohn Baldwin
788fb97396SJohn Baldwin	atf_check -s exit:0 -o ignore \
798fb97396SJohn Baldwin	    jexec wgtest1 wg set $wg1 peer "$pub2" \
808fb97396SJohn Baldwin	    endpoint ${endpoint2}:12345 allowed-ips ${tunnel2}/32
818fb97396SJohn Baldwin	atf_check -s exit:0 \
828fb97396SJohn Baldwin	    jexec wgtest1 ifconfig $wg1 inet ${tunnel1}/24 up
838fb97396SJohn Baldwin
848fb97396SJohn Baldwin	atf_check -s exit:0 -o ignore \
858fb97396SJohn Baldwin	    jexec wgtest2 wg set $wg2 peer "$pub1" \
868fb97396SJohn Baldwin	    endpoint ${endpoint1}:12345 allowed-ips ${tunnel1}/32
878fb97396SJohn Baldwin	atf_check -s exit:0 \
888fb97396SJohn Baldwin	    jexec wgtest2 ifconfig $wg2 inet ${tunnel2}/24 up
898fb97396SJohn Baldwin
908fb97396SJohn Baldwin	# Generous timeout since the handshake takes some time.
918fb97396SJohn Baldwin	atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 $tunnel2
928fb97396SJohn Baldwin	atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1
938fb97396SJohn Baldwin}
948fb97396SJohn Baldwin
958fb97396SJohn Baldwinwg_basic_cleanup()
968fb97396SJohn Baldwin{
978fb97396SJohn Baldwin	vnet_cleanup
988fb97396SJohn Baldwin}
998fb97396SJohn Baldwin
1008fb97396SJohn Baldwin# The kernel is expected to silently ignore any attempt to add a peer with a
1018fb97396SJohn Baldwin# public key identical to the host's.
1028fb97396SJohn Baldwinatf_test_case "wg_key_peerdev_shared" "cleanup"
1038fb97396SJohn Baldwinwg_key_peerdev_shared_head()
1048fb97396SJohn Baldwin{
1058fb97396SJohn Baldwin	atf_set descr 'Create a wg(4) interface with a shared pubkey between device and a peer'
1068fb97396SJohn Baldwin	atf_set require.user root
1078fb97396SJohn Baldwin}
1088fb97396SJohn Baldwin
1098fb97396SJohn Baldwinwg_key_peerdev_shared_body()
1108fb97396SJohn Baldwin{
1118fb97396SJohn Baldwin	local epair pri1 pub1 wg1
1128fb97396SJohn Baldwin        local endpoint1 tunnel1
1138fb97396SJohn Baldwin
114d22c5c42SOlivier Cochard	kldload -n if_wg || atf_skip "This test requires if_wg and could not load it"
1158fb97396SJohn Baldwin
1168fb97396SJohn Baldwin	pri1=$(wg genkey)
1178fb97396SJohn Baldwin
1188fb97396SJohn Baldwin	endpoint1=192.168.2.1
1198fb97396SJohn Baldwin	tunnel1=169.254.0.1
1208fb97396SJohn Baldwin
1218fb97396SJohn Baldwin	vnet_mkjail wgtest1
1228fb97396SJohn Baldwin
1238fb97396SJohn Baldwin	wg1=$(jexec wgtest1 ifconfig wg create)
1248fb97396SJohn Baldwin	echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \
1258fb97396SJohn Baldwin	    private-key /dev/stdin
1268fb97396SJohn Baldwin	pub1=$(jexec wgtest1 wg show $wg1 public-key)
1278fb97396SJohn Baldwin
1288fb97396SJohn Baldwin	atf_check -s exit:0 \
1298fb97396SJohn Baldwin	    jexec wgtest1 wg set ${wg1} peer "${pub1}" \
1308fb97396SJohn Baldwin	    allowed-ips "${tunnel1}/32"
1318fb97396SJohn Baldwin
1328fb97396SJohn Baldwin	atf_check -o empty jexec wgtest1 wg show ${wg1} peers
1338fb97396SJohn Baldwin}
1348fb97396SJohn Baldwin
1358fb97396SJohn Baldwinwg_key_peerdev_shared_cleanup()
1368fb97396SJohn Baldwin{
1378fb97396SJohn Baldwin	vnet_cleanup
1388fb97396SJohn Baldwin}
1398fb97396SJohn Baldwin
1408fb97396SJohn Baldwin# When a wg(8) interface has a private key reassigned that corresponds to the
1418fb97396SJohn Baldwin# public key already on a peer, the kernel is expected to deconfigure the peer
1428fb97396SJohn Baldwin# to resolve the conflict.
1438fb97396SJohn Baldwinatf_test_case "wg_key_peerdev_makeshared" "cleanup"
1448fb97396SJohn Baldwinwg_key_peerdev_makeshared_head()
1458fb97396SJohn Baldwin{
1468fb97396SJohn Baldwin	atf_set descr 'Create a wg(4) interface and assign peer key to device'
1478fb97396SJohn Baldwin	atf_set require.progs wg
1488fb97396SJohn Baldwin}
1498fb97396SJohn Baldwin
1508fb97396SJohn Baldwinwg_key_peerdev_makeshared_body()
1518fb97396SJohn Baldwin{
1528fb97396SJohn Baldwin	local epair pri1 pub1 pri2 wg1 wg2
1538fb97396SJohn Baldwin        local endpoint1 tunnel1
1548fb97396SJohn Baldwin
155d22c5c42SOlivier Cochard	kldload -n if_wg || atf_skip "This test requires if_wg and could not load it"
1568fb97396SJohn Baldwin
1578fb97396SJohn Baldwin	pri1=$(wg genkey)
1588fb97396SJohn Baldwin	pri2=$(wg genkey)
1598fb97396SJohn Baldwin
1608fb97396SJohn Baldwin	endpoint1=192.168.2.1
1618fb97396SJohn Baldwin	tunnel1=169.254.0.1
1628fb97396SJohn Baldwin
1638fb97396SJohn Baldwin	vnet_mkjail wgtest1
1648fb97396SJohn Baldwin
1658fb97396SJohn Baldwin	wg1=$(jexec wgtest1 ifconfig wg create)
1668fb97396SJohn Baldwin	echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \
1678fb97396SJohn Baldwin	    private-key /dev/stdin
1688fb97396SJohn Baldwin	pub1=$(jexec wgtest1 wg show $wg1 public-key)
1698fb97396SJohn Baldwin	wg2=$(jexec wgtest1 ifconfig wg create)
1708fb97396SJohn Baldwin	echo "$pri2" | jexec wgtest1 wg set $wg2 listen-port 12345 \
1718fb97396SJohn Baldwin	    private-key /dev/stdin
1728fb97396SJohn Baldwin
1738fb97396SJohn Baldwin	atf_check -s exit:0 -o ignore \
1748fb97396SJohn Baldwin	    jexec wgtest1 wg set ${wg2} peer "${pub1}" \
1758fb97396SJohn Baldwin	    allowed-ips "${tunnel1}/32"
1768fb97396SJohn Baldwin
1778fb97396SJohn Baldwin	atf_check -o not-empty jexec wgtest1 wg show ${wg2} peers
1788fb97396SJohn Baldwin
1798fb97396SJohn Baldwin	jexec wgtest1 sh -c "echo '${pri1}' > pri1"
1808fb97396SJohn Baldwin
1818fb97396SJohn Baldwin	atf_check -s exit:0 \
1828fb97396SJohn Baldwin	   jexec wgtest1 wg set ${wg2} private-key pri1
1838fb97396SJohn Baldwin
1848fb97396SJohn Baldwin	atf_check -o empty jexec wgtest1 wg show ${wg2} peers
1858fb97396SJohn Baldwin}
1868fb97396SJohn Baldwin
1878fb97396SJohn Baldwinwg_key_peerdev_makeshared_cleanup()
1888fb97396SJohn Baldwin{
1898fb97396SJohn Baldwin	vnet_cleanup
1908fb97396SJohn Baldwin}
1918fb97396SJohn Baldwin
192*96f4ab26SKyle Evans# The kernel is expected to create the wg socket in the jail context that the
193*96f4ab26SKyle Evans# wg interface was created in, even if the interface is moved to a different
194*96f4ab26SKyle Evans# vnet.
195*96f4ab26SKyle Evansatf_test_case "wg_vnet_parent_routing" "cleanup"
196*96f4ab26SKyle Evanswg_vnet_parent_routing_head()
197*96f4ab26SKyle Evans{
198*96f4ab26SKyle Evans	atf_set descr 'Create a wg(4) tunnel without epairs and pass traffic between jails'
199*96f4ab26SKyle Evans	atf_set require.user root
200*96f4ab26SKyle Evans}
201*96f4ab26SKyle Evans
202*96f4ab26SKyle Evanswg_vnet_parent_routing_body()
203*96f4ab26SKyle Evans{
204*96f4ab26SKyle Evans	local pri1 pri2 pub1 pub2 wg1 wg2
205*96f4ab26SKyle Evans        local tunnel1 tunnel2
206*96f4ab26SKyle Evans
207*96f4ab26SKyle Evans	kldload -n if_wg
208*96f4ab26SKyle Evans
209*96f4ab26SKyle Evans	pri1=$(wg genkey)
210*96f4ab26SKyle Evans	pri2=$(wg genkey)
211*96f4ab26SKyle Evans
212*96f4ab26SKyle Evans	tunnel1=169.254.0.1
213*96f4ab26SKyle Evans	tunnel2=169.254.0.2
214*96f4ab26SKyle Evans
215*96f4ab26SKyle Evans	vnet_init
216*96f4ab26SKyle Evans
217*96f4ab26SKyle Evans	wg1=$(ifconfig wg create)
218*96f4ab26SKyle Evans	wg2=$(ifconfig wg create)
219*96f4ab26SKyle Evans
220*96f4ab26SKyle Evans	vnet_mkjail wgtest1 ${wg1}
221*96f4ab26SKyle Evans	vnet_mkjail wgtest2 ${wg2}
222*96f4ab26SKyle Evans
223*96f4ab26SKyle Evans	echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \
224*96f4ab26SKyle Evans	    private-key /dev/stdin
225*96f4ab26SKyle Evans	pub1=$(jexec wgtest1 wg show $wg1 public-key)
226*96f4ab26SKyle Evans	echo "$pri2" | jexec wgtest2 wg set $wg2 listen-port 12346 \
227*96f4ab26SKyle Evans	    private-key /dev/stdin
228*96f4ab26SKyle Evans	pub2=$(jexec wgtest2 wg show $wg2 public-key)
229*96f4ab26SKyle Evans
230*96f4ab26SKyle Evans	atf_check -s exit:0 -o ignore \
231*96f4ab26SKyle Evans	    jexec wgtest1 wg set $wg1 peer "$pub2" \
232*96f4ab26SKyle Evans	    endpoint 127.0.0.1:12346 allowed-ips ${tunnel2}/32
233*96f4ab26SKyle Evans	atf_check -s exit:0 \
234*96f4ab26SKyle Evans	    jexec wgtest1 ifconfig $wg1 inet ${tunnel1}/24 up
235*96f4ab26SKyle Evans
236*96f4ab26SKyle Evans	atf_check -s exit:0 -o ignore \
237*96f4ab26SKyle Evans	    jexec wgtest2 wg set $wg2 peer "$pub1" \
238*96f4ab26SKyle Evans	    endpoint 127.0.0.1:12345 allowed-ips ${tunnel1}/32
239*96f4ab26SKyle Evans	atf_check -s exit:0 \
240*96f4ab26SKyle Evans	    jexec wgtest2 ifconfig $wg2 inet ${tunnel2}/24 up
241*96f4ab26SKyle Evans
242*96f4ab26SKyle Evans	# Sanity check ICMP counters; should clearly be nothing on these new
243*96f4ab26SKyle Evans	# jails.  We'll check them as we go to ensure that the ICMP packets
244*96f4ab26SKyle Evans	# generated really are being handled by the jails' vnets.
245*96f4ab26SKyle Evans	atf_check -o not-match:"histogram" jexec wgtest1 netstat -s -p icmp
246*96f4ab26SKyle Evans	atf_check -o not-match:"histogram" jexec wgtest2 netstat -s -p icmp
247*96f4ab26SKyle Evans
248*96f4ab26SKyle Evans	# Generous timeout since the handshake takes some time.
249*96f4ab26SKyle Evans	atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 $tunnel2
250*96f4ab26SKyle Evans	atf_check -o match:"echo reply: 1" jexec wgtest1 netstat -s -p icmp
251*96f4ab26SKyle Evans	atf_check -o match:"echo: 1" jexec wgtest2 netstat -s -p icmp
252*96f4ab26SKyle Evans
253*96f4ab26SKyle Evans	atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1
254*96f4ab26SKyle Evans	atf_check -o match:"echo reply: 1" jexec wgtest2 netstat -s -p icmp
255*96f4ab26SKyle Evans	atf_check -o match:"echo: 1" jexec wgtest1 netstat -s -p icmp
256*96f4ab26SKyle Evans}
257*96f4ab26SKyle Evans
258*96f4ab26SKyle Evanswg_vnet_parent_routing_cleanup()
259*96f4ab26SKyle Evans{
260*96f4ab26SKyle Evans	vnet_cleanup
261*96f4ab26SKyle Evans}
262*96f4ab26SKyle Evans
2638fb97396SJohn Baldwinatf_init_test_cases()
2648fb97396SJohn Baldwin{
2658fb97396SJohn Baldwin	atf_add_test_case "wg_basic"
2668fb97396SJohn Baldwin	atf_add_test_case "wg_key_peerdev_shared"
2678fb97396SJohn Baldwin	atf_add_test_case "wg_key_peerdev_makeshared"
268*96f4ab26SKyle Evans	atf_add_test_case "wg_vnet_parent_routing"
2698fb97396SJohn Baldwin}
270