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