1# $FreeBSD$ 2# 3# SPDX-License-Identifier: BSD-2-Clause 4# 5# Copyright (c) 2021 The FreeBSD Foundation 6# 7# This software was developed by Mark Johnston under sponsorship 8# from the FreeBSD Foundation. 9# 10# Redistribution and use in source and binary forms, with or without 11# modification, are permitted provided that the following conditions 12# are met: 13# 1. Redistributions of source code must retain the above copyright 14# notice, this list of conditions and the following disclaimer. 15# 2. Redistributions in binary form must reproduce the above copyright 16# notice, this list of conditions and the following disclaimer in the 17# documentation and/or other materials provided with the distribution. 18# 19# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29# SUCH DAMAGE. 30 31. $(atf_get_srcdir)/../common/vnet.subr 32 33atf_test_case "wg_basic" "cleanup" 34wg_basic_head() 35{ 36 atf_set descr 'Create a wg(4) tunnel over an epair and pass traffic between jails' 37 atf_set require.user root 38} 39 40wg_basic_body() 41{ 42 local epair pri1 pri2 pub1 pub2 wg1 wg2 43 local endpoint1 endpoint2 tunnel1 tunnel2 44 45 kldload -n if_wg || atf_skip "This test requires if_wg and could not load it" 46 47 pri1=$(wg genkey) 48 pri2=$(wg genkey) 49 50 endpoint1=192.168.2.1 51 endpoint2=192.168.2.2 52 tunnel1=169.254.0.1 53 tunnel2=169.254.0.2 54 55 epair=$(vnet_mkepair) 56 57 vnet_init 58 59 vnet_mkjail wgtest1 ${epair}a 60 vnet_mkjail wgtest2 ${epair}b 61 62 jexec wgtest1 ifconfig ${epair}a ${endpoint1}/24 up 63 jexec wgtest2 ifconfig ${epair}b ${endpoint2}/24 up 64 65 wg1=$(jexec wgtest1 ifconfig wg create) 66 echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \ 67 private-key /dev/stdin 68 pub1=$(jexec wgtest1 wg show $wg1 public-key) 69 wg2=$(jexec wgtest2 ifconfig wg create) 70 echo "$pri2" | jexec wgtest2 wg set $wg2 listen-port 12345 \ 71 private-key /dev/stdin 72 pub2=$(jexec wgtest2 wg show $wg2 public-key) 73 74 atf_check -s exit:0 -o ignore \ 75 jexec wgtest1 wg set $wg1 peer "$pub2" \ 76 endpoint ${endpoint2}:12345 allowed-ips ${tunnel2}/32 77 atf_check -s exit:0 \ 78 jexec wgtest1 ifconfig $wg1 inet ${tunnel1}/24 up 79 80 atf_check -s exit:0 -o ignore \ 81 jexec wgtest2 wg set $wg2 peer "$pub1" \ 82 endpoint ${endpoint1}:12345 allowed-ips ${tunnel1}/32 83 atf_check -s exit:0 \ 84 jexec wgtest2 ifconfig $wg2 inet ${tunnel2}/24 up 85 86 # Generous timeout since the handshake takes some time. 87 atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 $tunnel2 88 atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1 89} 90 91wg_basic_cleanup() 92{ 93 vnet_cleanup 94} 95 96# The kernel is expected to silently ignore any attempt to add a peer with a 97# public key identical to the host's. 98atf_test_case "wg_key_peerdev_shared" "cleanup" 99wg_key_peerdev_shared_head() 100{ 101 atf_set descr 'Create a wg(4) interface with a shared pubkey between device and a peer' 102 atf_set require.user root 103} 104 105wg_key_peerdev_shared_body() 106{ 107 local epair pri1 pub1 wg1 108 local endpoint1 tunnel1 109 110 kldload -n if_wg || atf_skip "This test requires if_wg and could not load it" 111 112 pri1=$(wg genkey) 113 114 endpoint1=192.168.2.1 115 tunnel1=169.254.0.1 116 117 vnet_mkjail wgtest1 118 119 wg1=$(jexec wgtest1 ifconfig wg create) 120 echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \ 121 private-key /dev/stdin 122 pub1=$(jexec wgtest1 wg show $wg1 public-key) 123 124 atf_check -s exit:0 \ 125 jexec wgtest1 wg set ${wg1} peer "${pub1}" \ 126 allowed-ips "${tunnel1}/32" 127 128 atf_check -o empty jexec wgtest1 wg show ${wg1} peers 129} 130 131wg_key_peerdev_shared_cleanup() 132{ 133 vnet_cleanup 134} 135 136# When a wg(8) interface has a private key reassigned that corresponds to the 137# public key already on a peer, the kernel is expected to deconfigure the peer 138# to resolve the conflict. 139atf_test_case "wg_key_peerdev_makeshared" "cleanup" 140wg_key_peerdev_makeshared_head() 141{ 142 atf_set descr 'Create a wg(4) interface and assign peer key to device' 143 atf_set require.progs wg 144} 145 146wg_key_peerdev_makeshared_body() 147{ 148 local epair pri1 pub1 pri2 wg1 wg2 149 local endpoint1 tunnel1 150 151 kldload -n if_wg || atf_skip "This test requires if_wg and could not load it" 152 153 pri1=$(wg genkey) 154 pri2=$(wg genkey) 155 156 endpoint1=192.168.2.1 157 tunnel1=169.254.0.1 158 159 vnet_mkjail wgtest1 160 161 wg1=$(jexec wgtest1 ifconfig wg create) 162 echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \ 163 private-key /dev/stdin 164 pub1=$(jexec wgtest1 wg show $wg1 public-key) 165 wg2=$(jexec wgtest1 ifconfig wg create) 166 echo "$pri2" | jexec wgtest1 wg set $wg2 listen-port 12345 \ 167 private-key /dev/stdin 168 169 atf_check -s exit:0 -o ignore \ 170 jexec wgtest1 wg set ${wg2} peer "${pub1}" \ 171 allowed-ips "${tunnel1}/32" 172 173 atf_check -o not-empty jexec wgtest1 wg show ${wg2} peers 174 175 jexec wgtest1 sh -c "echo '${pri1}' > pri1" 176 177 atf_check -s exit:0 \ 178 jexec wgtest1 wg set ${wg2} private-key pri1 179 180 atf_check -o empty jexec wgtest1 wg show ${wg2} peers 181} 182 183wg_key_peerdev_makeshared_cleanup() 184{ 185 vnet_cleanup 186} 187 188# The kernel is expected to create the wg socket in the jail context that the 189# wg interface was created in, even if the interface is moved to a different 190# vnet. 191atf_test_case "wg_vnet_parent_routing" "cleanup" 192wg_vnet_parent_routing_head() 193{ 194 atf_set descr 'Create a wg(4) tunnel without epairs and pass traffic between jails' 195 atf_set require.user root 196} 197 198wg_vnet_parent_routing_body() 199{ 200 local pri1 pri2 pub1 pub2 wg1 wg2 201 local tunnel1 tunnel2 202 203 kldload -n if_wg 204 205 pri1=$(wg genkey) 206 pri2=$(wg genkey) 207 208 tunnel1=169.254.0.1 209 tunnel2=169.254.0.2 210 211 vnet_init 212 213 wg1=$(ifconfig wg create) 214 wg2=$(ifconfig wg create) 215 216 vnet_mkjail wgtest1 ${wg1} 217 vnet_mkjail wgtest2 ${wg2} 218 219 echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \ 220 private-key /dev/stdin 221 pub1=$(jexec wgtest1 wg show $wg1 public-key) 222 echo "$pri2" | jexec wgtest2 wg set $wg2 listen-port 12346 \ 223 private-key /dev/stdin 224 pub2=$(jexec wgtest2 wg show $wg2 public-key) 225 226 atf_check -s exit:0 -o ignore \ 227 jexec wgtest1 wg set $wg1 peer "$pub2" \ 228 endpoint 127.0.0.1:12346 allowed-ips ${tunnel2}/32 229 atf_check -s exit:0 \ 230 jexec wgtest1 ifconfig $wg1 inet ${tunnel1}/24 up 231 232 atf_check -s exit:0 -o ignore \ 233 jexec wgtest2 wg set $wg2 peer "$pub1" \ 234 endpoint 127.0.0.1:12345 allowed-ips ${tunnel1}/32 235 atf_check -s exit:0 \ 236 jexec wgtest2 ifconfig $wg2 inet ${tunnel2}/24 up 237 238 # Sanity check ICMP counters; should clearly be nothing on these new 239 # jails. We'll check them as we go to ensure that the ICMP packets 240 # generated really are being handled by the jails' vnets. 241 atf_check -o not-match:"histogram" jexec wgtest1 netstat -s -p icmp 242 atf_check -o not-match:"histogram" jexec wgtest2 netstat -s -p icmp 243 244 # Generous timeout since the handshake takes some time. 245 atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 $tunnel2 246 atf_check -o match:"echo reply: 1" jexec wgtest1 netstat -s -p icmp 247 atf_check -o match:"echo: 1" jexec wgtest2 netstat -s -p icmp 248 249 atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1 250 atf_check -o match:"echo reply: 1" jexec wgtest2 netstat -s -p icmp 251 atf_check -o match:"echo: 1" jexec wgtest1 netstat -s -p icmp 252} 253 254wg_vnet_parent_routing_cleanup() 255{ 256 vnet_cleanup 257} 258 259atf_init_test_cases() 260{ 261 atf_add_test_case "wg_basic" 262 atf_add_test_case "wg_key_peerdev_shared" 263 atf_add_test_case "wg_key_peerdev_makeshared" 264 atf_add_test_case "wg_vnet_parent_routing" 265} 266