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 atf_set require.kmods if_wg 38} 39 40wg_basic_body() 41{ 42 local epair pri1 pri2 pub1 pub2 wg1 wg2 43 local endpoint1 endpoint2 tunnel1 tunnel2 44 45 pri1=$(wg genkey) 46 pri2=$(wg genkey) 47 48 endpoint1=192.168.2.1 49 endpoint2=192.168.2.2 50 tunnel1=169.254.0.1 51 tunnel2=169.254.0.2 52 53 epair=$(vnet_mkepair) 54 55 vnet_init 56 57 vnet_mkjail wgtest1 ${epair}a 58 vnet_mkjail wgtest2 ${epair}b 59 60 jexec wgtest1 ifconfig ${epair}a ${endpoint1}/24 up 61 jexec wgtest2 ifconfig ${epair}b ${endpoint2}/24 up 62 63 wg1=$(jexec wgtest1 ifconfig wg create) 64 echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \ 65 private-key /dev/stdin 66 pub1=$(jexec wgtest1 wg show $wg1 public-key) 67 wg2=$(jexec wgtest2 ifconfig wg create) 68 echo "$pri2" | jexec wgtest2 wg set $wg2 listen-port 12345 \ 69 private-key /dev/stdin 70 pub2=$(jexec wgtest2 wg show $wg2 public-key) 71 72 atf_check -s exit:0 -o ignore \ 73 jexec wgtest1 wg set $wg1 peer "$pub2" \ 74 endpoint ${endpoint2}:12345 allowed-ips ${tunnel2}/32 75 atf_check -s exit:0 \ 76 jexec wgtest1 ifconfig $wg1 inet ${tunnel1}/24 up 77 78 atf_check -s exit:0 -o ignore \ 79 jexec wgtest2 wg set $wg2 peer "$pub1" \ 80 endpoint ${endpoint1}:12345 allowed-ips ${tunnel1}/32 81 atf_check -s exit:0 \ 82 jexec wgtest2 ifconfig $wg2 inet ${tunnel2}/24 up 83 84 # Generous timeout since the handshake takes some time. 85 atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 $tunnel2 86 atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1 87} 88 89wg_basic_cleanup() 90{ 91 vnet_cleanup 92} 93 94atf_test_case "wg_basic_crossaf" "cleanup" 95wg_basic_crossaf_head() 96{ 97 atf_set descr 'Create a wg(4) tunnel and pass IPv4 traffic over an IPv6 nexthop' 98 atf_set require.user root 99} 100 101wg_basic_crossaf_body() 102{ 103 local epair pri1 pri2 pub1 pub2 wg1 wg2 104 local endpoint1 endpoint2 tunnel1 tunnel2 105 local testnet testlocal testremote 106 107 kldload -n if_wg || atf_skip "This test requires if_wg and could not load it" 108 109 pri1=$(wg genkey) 110 pri2=$(wg genkey) 111 112 endpoint1=192.168.2.1 113 endpoint2=192.168.2.2 114 tunnel1=2001:db8:1::1 115 tunnel2=2001:db8:1::2 116 117 testnet=192.168.3.0/24 118 testlocal=192.168.3.1 119 testremote=192.168.3.2 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}/128,${testnet} 143 atf_check -s exit:0 \ 144 jexec wgtest1 ifconfig $wg1 inet6 ${tunnel1}/64 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}/128,${testnet} 149 atf_check -s exit:0 \ 150 jexec wgtest2 ifconfig $wg2 inet6 ${tunnel2}/64 up 151 152 atf_check -s exit:0 jexec wgtest1 ifconfig $wg1 inet ${testlocal}/32 153 atf_check -s exit:0 jexec wgtest2 ifconfig $wg2 inet ${testremote}/32 154 155 # Generous timeout since the handshake takes some time. 156 atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 "$tunnel2" 157 158 # Setup our IPv6 endpoint and routing 159 atf_check -s exit:0 -o ignore \ 160 jexec wgtest1 route add -inet ${testnet} -inet6 "$tunnel2" 161 atf_check -s exit:0 -o ignore \ 162 jexec wgtest2 route add -inet ${testnet} -inet6 "$tunnel1" 163 # Now ping an address on the other side 164 atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 3 ${testremote} 165} 166 167wg_basic_crossaf_cleanup() 168{ 169 vnet_cleanup 170} 171 172atf_test_case "wg_basic_netmap" "cleanup" 173wg_basic_netmap_head() 174{ 175 atf_set descr 'Create a wg(4) tunnel over an epair and pass traffic between jails with netmap' 176 atf_set require.user root 177 atf_set require.kmods if_wg netmap 178} 179 180wg_basic_netmap_body() 181{ 182 local epair pri1 pri2 pub1 pub2 wg1 wg2 183 local endpoint1 endpoint2 tunnel1 tunnel2 tunnel3 tunnel4 184 local pid status 185 186 pri1=$(wg genkey) 187 pri2=$(wg genkey) 188 189 endpoint1=192.168.2.1 190 endpoint2=192.168.2.2 191 tunnel1=192.168.3.1 192 tunnel2=192.168.3.2 193 tunnel3=192.168.3.3 194 tunnel4=192.168.3.4 195 196 epair=$(vnet_mkepair) 197 198 vnet_init 199 200 vnet_mkjail wgtest1 ${epair}a 201 vnet_mkjail wgtest2 ${epair}b 202 203 jexec wgtest1 ifconfig ${epair}a ${endpoint1}/24 up 204 jexec wgtest2 ifconfig ${epair}b ${endpoint2}/24 up 205 206 wg1=$(jexec wgtest1 ifconfig wg create) 207 echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \ 208 private-key /dev/stdin 209 pub1=$(jexec wgtest1 wg show $wg1 public-key) 210 wg2=$(jexec wgtest2 ifconfig wg create) 211 echo "$pri2" | jexec wgtest2 wg set $wg2 listen-port 12345 \ 212 private-key /dev/stdin 213 pub2=$(jexec wgtest2 wg show $wg2 public-key) 214 215 atf_check -s exit:0 -o ignore \ 216 jexec wgtest1 wg set $wg1 peer "$pub2" \ 217 endpoint ${endpoint2}:12345 allowed-ips ${tunnel2}/32,${tunnel4}/32 218 atf_check -s exit:0 \ 219 jexec wgtest1 ifconfig $wg1 inet ${tunnel1}/24 up 220 221 atf_check -s exit:0 -o ignore \ 222 jexec wgtest2 wg set $wg2 peer "$pub1" \ 223 endpoint ${endpoint1}:12345 allowed-ips ${tunnel1}/32,${tunnel3}/32 224 atf_check -s exit:0 \ 225 jexec wgtest2 ifconfig $wg2 inet ${tunnel2}/24 up 226 227 atf_check -s exit:0 -o ignore \ 228 jexec wgtest1 sysctl net.inet.ip.forwarding=1 229 atf_check -s exit:0 -o ignore \ 230 jexec wgtest2 sysctl net.inet.ip.forwarding=1 231 232 jexec wgtest1 $(atf_get_srcdir)/bridge -w 0 -i netmap:wg0 -i netmap:wg0^ & 233 pid=$! 234 235 # Generous timeout since the handshake takes some time. 236 atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 $tunnel2 237 atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1 238 239 # Verify that we cannot ping non-existent tunnel addresses. In general 240 # the remote side should respond with an ICMP message. 241 atf_check -s exit:2 -o ignore jexec wgtest1 ping -c 1 -t 2 $tunnel4 242 atf_check -s exit:2 -o ignore jexec wgtest2 ping -c 1 -t 2 $tunnel3 243 244 # Make sure that the bridge is still functional. 245 atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 $tunnel2 246 atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1 247 248 atf_check -s exit:0 kill -TERM $pid 249 wait $pid 250 status=$? 251 252 # Make sure that SIGTERM was received and handled. 253 atf_check_equal $status 143 254} 255 256wg_basic_netmap_cleanup() 257{ 258 vnet_cleanup 259} 260 261# The kernel is expected to silently ignore any attempt to add a peer with a 262# public key identical to the host's. 263atf_test_case "wg_key_peerdev_shared" "cleanup" 264wg_key_peerdev_shared_head() 265{ 266 atf_set descr 'Create a wg(4) interface with a shared pubkey between device and a peer' 267 atf_set require.user root 268 atf_set require.kmods if_wg 269} 270 271wg_key_peerdev_shared_body() 272{ 273 local epair pri1 pub1 wg1 274 local endpoint1 tunnel1 275 276 pri1=$(wg genkey) 277 278 endpoint1=192.168.2.1 279 tunnel1=169.254.0.1 280 281 vnet_mkjail wgtest1 282 283 wg1=$(jexec wgtest1 ifconfig wg create) 284 echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \ 285 private-key /dev/stdin 286 pub1=$(jexec wgtest1 wg show $wg1 public-key) 287 288 atf_check -s exit:0 \ 289 jexec wgtest1 wg set ${wg1} peer "${pub1}" \ 290 allowed-ips "${tunnel1}/32" 291 292 atf_check -o empty jexec wgtest1 wg show ${wg1} peers 293} 294 295wg_key_peerdev_shared_cleanup() 296{ 297 vnet_cleanup 298} 299 300# When a wg(8) interface has a private key reassigned that corresponds to the 301# public key already on a peer, the kernel is expected to deconfigure the peer 302# to resolve the conflict. 303atf_test_case "wg_key_peerdev_makeshared" "cleanup" 304wg_key_peerdev_makeshared_head() 305{ 306 atf_set descr 'Create a wg(4) interface and assign peer key to device' 307 atf_set require.progs wg 308} 309 310wg_key_peerdev_makeshared_body() 311{ 312 local epair pri1 pub1 pri2 wg1 wg2 313 local endpoint1 tunnel1 314 315 pri1=$(wg genkey) 316 pri2=$(wg genkey) 317 318 endpoint1=192.168.2.1 319 tunnel1=169.254.0.1 320 321 vnet_mkjail wgtest1 322 323 wg1=$(jexec wgtest1 ifconfig wg create) 324 echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \ 325 private-key /dev/stdin 326 pub1=$(jexec wgtest1 wg show $wg1 public-key) 327 wg2=$(jexec wgtest1 ifconfig wg create) 328 echo "$pri2" | jexec wgtest1 wg set $wg2 listen-port 12345 \ 329 private-key /dev/stdin 330 331 atf_check -s exit:0 -o ignore \ 332 jexec wgtest1 wg set ${wg2} peer "${pub1}" \ 333 allowed-ips "${tunnel1}/32" 334 335 atf_check -o not-empty jexec wgtest1 wg show ${wg2} peers 336 337 jexec wgtest1 sh -c "echo '${pri1}' > pri1" 338 339 atf_check -s exit:0 \ 340 jexec wgtest1 wg set ${wg2} private-key pri1 341 342 atf_check -o empty jexec wgtest1 wg show ${wg2} peers 343} 344 345wg_key_peerdev_makeshared_cleanup() 346{ 347 vnet_cleanup 348} 349 350# The kernel is expected to create the wg socket in the jail context that the 351# wg interface was created in, even if the interface is moved to a different 352# vnet. 353atf_test_case "wg_vnet_parent_routing" "cleanup" 354wg_vnet_parent_routing_head() 355{ 356 atf_set descr 'Create a wg(4) tunnel without epairs and pass traffic between jails' 357 atf_set require.user root 358 atf_set require.kmods if_wg 359} 360 361wg_vnet_parent_routing_body() 362{ 363 local pri1 pri2 pub1 pub2 wg1 wg2 364 local tunnel1 tunnel2 365 366 pri1=$(wg genkey) 367 pri2=$(wg genkey) 368 369 tunnel1=169.254.0.1 370 tunnel2=169.254.0.2 371 372 vnet_init 373 374 wg1=$(ifconfig wg create) 375 wg2=$(ifconfig wg create) 376 377 vnet_mkjail wgtest1 ${wg1} 378 vnet_mkjail wgtest2 ${wg2} 379 380 echo "$pri1" | jexec wgtest1 wg set $wg1 listen-port 12345 \ 381 private-key /dev/stdin 382 pub1=$(jexec wgtest1 wg show $wg1 public-key) 383 echo "$pri2" | jexec wgtest2 wg set $wg2 listen-port 12346 \ 384 private-key /dev/stdin 385 pub2=$(jexec wgtest2 wg show $wg2 public-key) 386 387 atf_check -s exit:0 -o ignore \ 388 jexec wgtest1 wg set $wg1 peer "$pub2" \ 389 endpoint 127.0.0.1:12346 allowed-ips ${tunnel2}/32 390 atf_check -s exit:0 \ 391 jexec wgtest1 ifconfig $wg1 inet ${tunnel1}/24 up 392 393 atf_check -s exit:0 -o ignore \ 394 jexec wgtest2 wg set $wg2 peer "$pub1" \ 395 endpoint 127.0.0.1:12345 allowed-ips ${tunnel1}/32 396 atf_check -s exit:0 \ 397 jexec wgtest2 ifconfig $wg2 inet ${tunnel2}/24 up 398 399 # Sanity check ICMP counters; should clearly be nothing on these new 400 # jails. We'll check them as we go to ensure that the ICMP packets 401 # generated really are being handled by the jails' vnets. 402 atf_check -o not-match:"histogram" jexec wgtest1 netstat -s -p icmp 403 atf_check -o not-match:"histogram" jexec wgtest2 netstat -s -p icmp 404 405 # Generous timeout since the handshake takes some time. 406 atf_check -s exit:0 -o ignore jexec wgtest1 ping -c 1 -t 5 $tunnel2 407 atf_check -o match:"echo reply: 1" jexec wgtest1 netstat -s -p icmp 408 atf_check -o match:"echo: 1" jexec wgtest2 netstat -s -p icmp 409 410 atf_check -s exit:0 -o ignore jexec wgtest2 ping -c 1 $tunnel1 411 atf_check -o match:"echo reply: 1" jexec wgtest2 netstat -s -p icmp 412 atf_check -o match:"echo: 1" jexec wgtest1 netstat -s -p icmp 413} 414 415wg_vnet_parent_routing_cleanup() 416{ 417 vnet_cleanup 418} 419 420atf_init_test_cases() 421{ 422 atf_add_test_case "wg_basic" 423 atf_add_test_case "wg_basic_crossaf" 424 atf_add_test_case "wg_basic_netmap" 425 atf_add_test_case "wg_key_peerdev_shared" 426 atf_add_test_case "wg_key_peerdev_makeshared" 427 atf_add_test_case "wg_vnet_parent_routing" 428} 429