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 95atf_test_case "wg_basic_netmap" "cleanup" 96wg_basic_netmap_head() 97{ 98 atf_set descr 'Create a wg(4) tunnel over an epair and pass traffic between jails with netmap' 99 atf_set require.user root 100} 101 102wg_basic_netmap_body() 103{ 104 local epair pri1 pri2 pub1 pub2 wg1 wg2 105 local endpoint1 endpoint2 tunnel1 tunnel2 tunnel3 tunnel4 106 local pid status 107 108 kldload -n if_wg || atf_skip "This test requires if_wg and could not load it" 109 kldload -n netmap || atf_skip "This test requires netmap and could not load it" 110 111 pri1=$(wg genkey) 112 pri2=$(wg genkey) 113 114 endpoint1=192.168.2.1 115 endpoint2=192.168.2.2 116 tunnel1=192.168.3.1 117 tunnel2=192.168.3.2 118 tunnel3=192.168.3.3 119 tunnel4=192.168.3.4 120 121 epair=$(vnet_mkepair) 122 123 vnet_init 124 125 vnet_mkjail wgtest1 ${epair}a 126 vnet_mkjail wgtest2 ${epair}b 127 128 jexec wgtest1 ifconfig ${epair}a ${endpoint1}/24 up 129 jexec wgtest2 ifconfig ${epair}b ${endpoint2}/24 up 130 131 wg1=$(jexec wgtest1 ifconfig wg create) 132 echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \ 133 private-key /dev/stdin 134 pub1=$(jexec wgtest1 wg show $wg1 public-key) 135 wg2=$(jexec wgtest2 ifconfig wg create) 136 echo "$pri2" | jexec wgtest2 wg set $wg2 listen-port 12345 \ 137 private-key /dev/stdin 138 pub2=$(jexec wgtest2 wg show $wg2 public-key) 139 140 atf_check -s exit:0 -o ignore \ 141 jexec wgtest1 wg set $wg1 peer "$pub2" \ 142 endpoint ${endpoint2}:12345 allowed-ips ${tunnel2}/32,${tunnel4}/32 143 atf_check -s exit:0 \ 144 jexec wgtest1 ifconfig $wg1 inet ${tunnel1}/24 up 145 146 atf_check -s exit:0 -o ignore \ 147 jexec wgtest2 wg set $wg2 peer "$pub1" \ 148 endpoint ${endpoint1}:12345 allowed-ips ${tunnel1}/32,${tunnel3}/32 149 atf_check -s exit:0 \ 150 jexec wgtest2 ifconfig $wg2 inet ${tunnel2}/24 up 151 152 atf_check -s exit:0 -o ignore \ 153 jexec wgtest1 sysctl net.inet.ip.forwarding=1 154 atf_check -s exit:0 -o ignore \ 155 jexec wgtest2 sysctl net.inet.ip.forwarding=1 156 157 jexec wgtest1 $(atf_get_srcdir)/bridge -w 0 -i netmap:wg0 -i netmap:wg0^ & 158 pid=$! 159 160 # Generous timeout since the handshake takes some time. 161 atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 $tunnel2 162 atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1 163 164 # Verify that we cannot ping non-existent tunnel addresses. In general 165 # the remote side should respond with an ICMP message. 166 atf_check -s exit:2 -o ignore jexec wgtest1 ping -c 1 -t 2 $tunnel4 167 atf_check -s exit:2 -o ignore jexec wgtest2 ping -c 1 -t 2 $tunnel3 168 169 # Make sure that the bridge is still functional. 170 atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 $tunnel2 171 atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1 172 173 atf_check -s exit:0 kill -TERM $pid 174 wait $pid 175 status=$? 176 177 # Make sure that SIGTERM was received and handled. 178 atf_check_equal $status 143 179} 180 181wg_basic_netmap_cleanup() 182{ 183 vnet_cleanup 184} 185 186# The kernel is expected to silently ignore any attempt to add a peer with a 187# public key identical to the host's. 188atf_test_case "wg_key_peerdev_shared" "cleanup" 189wg_key_peerdev_shared_head() 190{ 191 atf_set descr 'Create a wg(4) interface with a shared pubkey between device and a peer' 192 atf_set require.user root 193} 194 195wg_key_peerdev_shared_body() 196{ 197 local epair pri1 pub1 wg1 198 local endpoint1 tunnel1 199 200 kldload -n if_wg || atf_skip "This test requires if_wg and could not load it" 201 202 pri1=$(wg genkey) 203 204 endpoint1=192.168.2.1 205 tunnel1=169.254.0.1 206 207 vnet_mkjail wgtest1 208 209 wg1=$(jexec wgtest1 ifconfig wg create) 210 echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \ 211 private-key /dev/stdin 212 pub1=$(jexec wgtest1 wg show $wg1 public-key) 213 214 atf_check -s exit:0 \ 215 jexec wgtest1 wg set ${wg1} peer "${pub1}" \ 216 allowed-ips "${tunnel1}/32" 217 218 atf_check -o empty jexec wgtest1 wg show ${wg1} peers 219} 220 221wg_key_peerdev_shared_cleanup() 222{ 223 vnet_cleanup 224} 225 226# When a wg(8) interface has a private key reassigned that corresponds to the 227# public key already on a peer, the kernel is expected to deconfigure the peer 228# to resolve the conflict. 229atf_test_case "wg_key_peerdev_makeshared" "cleanup" 230wg_key_peerdev_makeshared_head() 231{ 232 atf_set descr 'Create a wg(4) interface and assign peer key to device' 233 atf_set require.progs wg 234} 235 236wg_key_peerdev_makeshared_body() 237{ 238 local epair pri1 pub1 pri2 wg1 wg2 239 local endpoint1 tunnel1 240 241 kldload -n if_wg || atf_skip "This test requires if_wg and could not load it" 242 243 pri1=$(wg genkey) 244 pri2=$(wg genkey) 245 246 endpoint1=192.168.2.1 247 tunnel1=169.254.0.1 248 249 vnet_mkjail wgtest1 250 251 wg1=$(jexec wgtest1 ifconfig wg create) 252 echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \ 253 private-key /dev/stdin 254 pub1=$(jexec wgtest1 wg show $wg1 public-key) 255 wg2=$(jexec wgtest1 ifconfig wg create) 256 echo "$pri2" | jexec wgtest1 wg set $wg2 listen-port 12345 \ 257 private-key /dev/stdin 258 259 atf_check -s exit:0 -o ignore \ 260 jexec wgtest1 wg set ${wg2} peer "${pub1}" \ 261 allowed-ips "${tunnel1}/32" 262 263 atf_check -o not-empty jexec wgtest1 wg show ${wg2} peers 264 265 jexec wgtest1 sh -c "echo '${pri1}' > pri1" 266 267 atf_check -s exit:0 \ 268 jexec wgtest1 wg set ${wg2} private-key pri1 269 270 atf_check -o empty jexec wgtest1 wg show ${wg2} peers 271} 272 273wg_key_peerdev_makeshared_cleanup() 274{ 275 vnet_cleanup 276} 277 278# The kernel is expected to create the wg socket in the jail context that the 279# wg interface was created in, even if the interface is moved to a different 280# vnet. 281atf_test_case "wg_vnet_parent_routing" "cleanup" 282wg_vnet_parent_routing_head() 283{ 284 atf_set descr 'Create a wg(4) tunnel without epairs and pass traffic between jails' 285 atf_set require.user root 286} 287 288wg_vnet_parent_routing_body() 289{ 290 local pri1 pri2 pub1 pub2 wg1 wg2 291 local tunnel1 tunnel2 292 293 kldload -n if_wg 294 295 pri1=$(wg genkey) 296 pri2=$(wg genkey) 297 298 tunnel1=169.254.0.1 299 tunnel2=169.254.0.2 300 301 vnet_init 302 303 wg1=$(ifconfig wg create) 304 wg2=$(ifconfig wg create) 305 306 vnet_mkjail wgtest1 ${wg1} 307 vnet_mkjail wgtest2 ${wg2} 308 309 echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \ 310 private-key /dev/stdin 311 pub1=$(jexec wgtest1 wg show $wg1 public-key) 312 echo "$pri2" | jexec wgtest2 wg set $wg2 listen-port 12346 \ 313 private-key /dev/stdin 314 pub2=$(jexec wgtest2 wg show $wg2 public-key) 315 316 atf_check -s exit:0 -o ignore \ 317 jexec wgtest1 wg set $wg1 peer "$pub2" \ 318 endpoint 127.0.0.1:12346 allowed-ips ${tunnel2}/32 319 atf_check -s exit:0 \ 320 jexec wgtest1 ifconfig $wg1 inet ${tunnel1}/24 up 321 322 atf_check -s exit:0 -o ignore \ 323 jexec wgtest2 wg set $wg2 peer "$pub1" \ 324 endpoint 127.0.0.1:12345 allowed-ips ${tunnel1}/32 325 atf_check -s exit:0 \ 326 jexec wgtest2 ifconfig $wg2 inet ${tunnel2}/24 up 327 328 # Sanity check ICMP counters; should clearly be nothing on these new 329 # jails. We'll check them as we go to ensure that the ICMP packets 330 # generated really are being handled by the jails' vnets. 331 atf_check -o not-match:"histogram" jexec wgtest1 netstat -s -p icmp 332 atf_check -o not-match:"histogram" jexec wgtest2 netstat -s -p icmp 333 334 # Generous timeout since the handshake takes some time. 335 atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 $tunnel2 336 atf_check -o match:"echo reply: 1" jexec wgtest1 netstat -s -p icmp 337 atf_check -o match:"echo: 1" jexec wgtest2 netstat -s -p icmp 338 339 atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1 340 atf_check -o match:"echo reply: 1" jexec wgtest2 netstat -s -p icmp 341 atf_check -o match:"echo: 1" jexec wgtest1 netstat -s -p icmp 342} 343 344wg_vnet_parent_routing_cleanup() 345{ 346 vnet_cleanup 347} 348 349atf_init_test_cases() 350{ 351 atf_add_test_case "wg_basic" 352 atf_add_test_case "wg_basic_netmap" 353 atf_add_test_case "wg_key_peerdev_shared" 354 atf_add_test_case "wg_key_peerdev_makeshared" 355 atf_add_test_case "wg_vnet_parent_routing" 356} 357