1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. 5# 6# This script tests the below topology: 7# 8# ┌─────────────────────┐ ┌──────────────────────────────────┐ ┌─────────────────────┐ 9# │ $ns1 namespace │ │ $ns0 namespace │ │ $ns2 namespace │ 10# │ │ │ │ │ │ 11# │┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐│ 12# ││ wg0 │───────────┼───┼────────────│ lo │────────────┼───┼───────────│ wg0 ││ 13# │├────────┴──────────┐│ │ ┌───────┴────────┴────────┐ │ │┌──────────┴────────┤│ 14# ││192.168.241.1/24 ││ │ │(ns1) (ns2) │ │ ││192.168.241.2/24 ││ 15# ││fd00::1/24 ││ │ │127.0.0.1:1 127.0.0.1:2│ │ ││fd00::2/24 ││ 16# │└───────────────────┘│ │ │[::]:1 [::]:2 │ │ │└───────────────────┘│ 17# └─────────────────────┘ │ └─────────────────────────┘ │ └─────────────────────┘ 18# └──────────────────────────────────┘ 19# 20# After the topology is prepared we run a series of TCP/UDP iperf3 tests between the 21# wireguard peers in $ns1 and $ns2. Note that $ns0 is the endpoint for the wg0 22# interfaces in $ns1 and $ns2. See https://www.wireguard.com/netns/ for further 23# details on how this is accomplished. 24set -e 25 26exec 3>&1 27export WG_HIDE_KEYS=never 28netns0="wg-test-$$-0" 29netns1="wg-test-$$-1" 30netns2="wg-test-$$-2" 31pretty() { echo -e "\x1b[32m\x1b[1m[+] ${1:+NS$1: }${2}\x1b[0m" >&3; } 32pp() { pretty "" "$*"; "$@"; } 33maybe_exec() { if [[ $BASHPID -eq $$ ]]; then "$@"; else exec "$@"; fi; } 34n0() { pretty 0 "$*"; maybe_exec ip netns exec $netns0 "$@"; } 35n1() { pretty 1 "$*"; maybe_exec ip netns exec $netns1 "$@"; } 36n2() { pretty 2 "$*"; maybe_exec ip netns exec $netns2 "$@"; } 37ip0() { pretty 0 "ip $*"; ip -n $netns0 "$@"; } 38ip1() { pretty 1 "ip $*"; ip -n $netns1 "$@"; } 39ip2() { pretty 2 "ip $*"; ip -n $netns2 "$@"; } 40sleep() { read -t "$1" -N 1 || true; } 41waitiperf() { pretty "${1//*-}" "wait for iperf:5201 pid $2"; while [[ $(ss -N "$1" -tlpH 'sport = 5201') != *\"iperf3\",pid=$2,fd=* ]]; do sleep 0.1; done; } 42waitncatudp() { pretty "${1//*-}" "wait for udp:1111 pid $2"; while [[ $(ss -N "$1" -ulpH 'sport = 1111') != *\"ncat\",pid=$2,fd=* ]]; do sleep 0.1; done; } 43waitiface() { pretty "${1//*-}" "wait for $2 to come up"; ip netns exec "$1" bash -c "while [[ \$(< \"/sys/class/net/$2/operstate\") != up ]]; do read -t .1 -N 0 || true; done;"; } 44 45cleanup() { 46 set +e 47 exec 2>/dev/null 48 printf "$orig_message_cost" > /proc/sys/net/core/message_cost 49 ip0 link del dev wg0 50 ip1 link del dev wg0 51 ip2 link del dev wg0 52 local to_kill="$(ip netns pids $netns0) $(ip netns pids $netns1) $(ip netns pids $netns2)" 53 [[ -n $to_kill ]] && kill $to_kill 54 pp ip netns del $netns1 55 pp ip netns del $netns2 56 pp ip netns del $netns0 57 exit 58} 59 60orig_message_cost="$(< /proc/sys/net/core/message_cost)" 61trap cleanup EXIT 62printf 0 > /proc/sys/net/core/message_cost 63 64ip netns del $netns0 2>/dev/null || true 65ip netns del $netns1 2>/dev/null || true 66ip netns del $netns2 2>/dev/null || true 67pp ip netns add $netns0 68pp ip netns add $netns1 69pp ip netns add $netns2 70ip0 link set up dev lo 71 72ip0 link add dev wg0 type wireguard 73ip0 link set wg0 netns $netns1 74ip0 link add dev wg0 type wireguard 75ip0 link set wg0 netns $netns2 76key1="$(pp wg genkey)" 77key2="$(pp wg genkey)" 78key3="$(pp wg genkey)" 79pub1="$(pp wg pubkey <<<"$key1")" 80pub2="$(pp wg pubkey <<<"$key2")" 81pub3="$(pp wg pubkey <<<"$key3")" 82psk="$(pp wg genpsk)" 83[[ -n $key1 && -n $key2 && -n $psk ]] 84 85configure_peers() { 86 ip1 addr add 192.168.241.1/24 dev wg0 87 ip1 addr add fd00::1/24 dev wg0 88 89 ip2 addr add 192.168.241.2/24 dev wg0 90 ip2 addr add fd00::2/24 dev wg0 91 92 n1 wg set wg0 \ 93 private-key <(echo "$key1") \ 94 listen-port 1 \ 95 peer "$pub2" \ 96 preshared-key <(echo "$psk") \ 97 allowed-ips 192.168.241.2/32,fd00::2/128 98 n2 wg set wg0 \ 99 private-key <(echo "$key2") \ 100 listen-port 2 \ 101 peer "$pub1" \ 102 preshared-key <(echo "$psk") \ 103 allowed-ips 192.168.241.1/32,fd00::1/128 104 105 ip1 link set up dev wg0 106 ip2 link set up dev wg0 107} 108configure_peers 109 110tests() { 111 # Ping over IPv4 112 n2 ping -c 10 -f -W 1 192.168.241.1 113 n1 ping -c 10 -f -W 1 192.168.241.2 114 115 # Ping over IPv6 116 n2 ping6 -c 10 -f -W 1 fd00::1 117 n1 ping6 -c 10 -f -W 1 fd00::2 118 119 # TCP over IPv4 120 n2 iperf3 -s -1 -B 192.168.241.2 & 121 waitiperf $netns2 $! 122 n1 iperf3 -Z -t 3 -c 192.168.241.2 123 124 # TCP over IPv6 125 n1 iperf3 -s -1 -B fd00::1 & 126 waitiperf $netns1 $! 127 n2 iperf3 -Z -t 3 -c fd00::1 128 129 # UDP over IPv4 130 n1 iperf3 -s -1 -B 192.168.241.1 & 131 waitiperf $netns1 $! 132 n2 iperf3 -Z -t 3 -b 0 -u -c 192.168.241.1 133 134 # UDP over IPv6 135 n2 iperf3 -s -1 -B fd00::2 & 136 waitiperf $netns2 $! 137 n1 iperf3 -Z -t 3 -b 0 -u -c fd00::2 138} 139 140[[ $(ip1 link show dev wg0) =~ mtu\ ([0-9]+) ]] && orig_mtu="${BASH_REMATCH[1]}" 141big_mtu=$(( 34816 - 1500 + $orig_mtu )) 142 143# Test using IPv4 as outer transport 144n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2 145n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1:1 146# Before calling tests, we first make sure that the stats counters and timestamper are working 147n2 ping -c 10 -f -W 1 192.168.241.1 148{ read _; read _; read _; read rx_bytes _; read _; read tx_bytes _; } < <(ip2 -stats link show dev wg0) 149(( rx_bytes == 1372 && (tx_bytes == 1428 || tx_bytes == 1460) )) 150{ read _; read _; read _; read rx_bytes _; read _; read tx_bytes _; } < <(ip1 -stats link show dev wg0) 151(( tx_bytes == 1372 && (rx_bytes == 1428 || rx_bytes == 1460) )) 152read _ rx_bytes tx_bytes < <(n2 wg show wg0 transfer) 153(( rx_bytes == 1372 && (tx_bytes == 1428 || tx_bytes == 1460) )) 154read _ rx_bytes tx_bytes < <(n1 wg show wg0 transfer) 155(( tx_bytes == 1372 && (rx_bytes == 1428 || rx_bytes == 1460) )) 156read _ timestamp < <(n1 wg show wg0 latest-handshakes) 157(( timestamp != 0 )) 158 159tests 160ip1 link set wg0 mtu $big_mtu 161ip2 link set wg0 mtu $big_mtu 162tests 163 164ip1 link set wg0 mtu $orig_mtu 165ip2 link set wg0 mtu $orig_mtu 166 167# Test using IPv6 as outer transport 168n1 wg set wg0 peer "$pub2" endpoint [::1]:2 169n2 wg set wg0 peer "$pub1" endpoint [::1]:1 170tests 171ip1 link set wg0 mtu $big_mtu 172ip2 link set wg0 mtu $big_mtu 173tests 174 175# Test that route MTUs work with the padding 176ip1 link set wg0 mtu 1300 177ip2 link set wg0 mtu 1300 178n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2 179n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1:1 180n0 iptables -A INPUT -m length --length 1360 -j DROP 181n1 ip route add 192.168.241.2/32 dev wg0 mtu 1299 182n2 ip route add 192.168.241.1/32 dev wg0 mtu 1299 183n2 ping -c 1 -W 1 -s 1269 192.168.241.1 184n2 ip route delete 192.168.241.1/32 dev wg0 mtu 1299 185n1 ip route delete 192.168.241.2/32 dev wg0 mtu 1299 186n0 iptables -F INPUT 187 188ip1 link set wg0 mtu $orig_mtu 189ip2 link set wg0 mtu $orig_mtu 190 191# Test using IPv4 that roaming works 192ip0 -4 addr del 127.0.0.1/8 dev lo 193ip0 -4 addr add 127.212.121.99/8 dev lo 194n1 wg set wg0 listen-port 9999 195n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2 196n1 ping6 -W 1 -c 1 fd00::2 197[[ $(n2 wg show wg0 endpoints) == "$pub1 127.212.121.99:9999" ]] 198 199# Test using IPv6 that roaming works 200n1 wg set wg0 listen-port 9998 201n1 wg set wg0 peer "$pub2" endpoint [::1]:2 202n1 ping -W 1 -c 1 192.168.241.2 203[[ $(n2 wg show wg0 endpoints) == "$pub1 [::1]:9998" ]] 204 205# Test that crypto-RP filter works 206n1 wg set wg0 peer "$pub2" allowed-ips 192.168.241.0/24 207exec 4< <(n1 ncat -l -u -p 1111) 208ncat_pid=$! 209waitncatudp $netns1 $ncat_pid 210n2 ncat -u 192.168.241.1 1111 <<<"X" 211read -r -N 1 -t 1 out <&4 && [[ $out == "X" ]] 212kill $ncat_pid 213more_specific_key="$(pp wg genkey | pp wg pubkey)" 214n1 wg set wg0 peer "$more_specific_key" allowed-ips 192.168.241.2/32 215n2 wg set wg0 listen-port 9997 216exec 4< <(n1 ncat -l -u -p 1111) 217ncat_pid=$! 218waitncatudp $netns1 $ncat_pid 219n2 ncat -u 192.168.241.1 1111 <<<"X" 220! read -r -N 1 -t 1 out <&4 || false 221kill $ncat_pid 222n1 wg set wg0 peer "$more_specific_key" remove 223[[ $(n1 wg show wg0 endpoints) == "$pub2 [::1]:9997" ]] 224 225# Test that we can change private keys keys and immediately handshake 226n1 wg set wg0 private-key <(echo "$key1") peer "$pub2" preshared-key <(echo "$psk") allowed-ips 192.168.241.2/32 endpoint 127.0.0.1:2 227n2 wg set wg0 private-key <(echo "$key2") listen-port 2 peer "$pub1" preshared-key <(echo "$psk") allowed-ips 192.168.241.1/32 228n1 ping -W 1 -c 1 192.168.241.2 229n1 wg set wg0 private-key <(echo "$key3") 230n2 wg set wg0 peer "$pub3" preshared-key <(echo "$psk") allowed-ips 192.168.241.1/32 peer "$pub1" remove 231n1 ping -W 1 -c 1 192.168.241.2 232 233ip1 link del wg0 234ip2 link del wg0 235 236# Test using NAT. We now change the topology to this: 237# ┌────────────────────────────────────────┐ ┌────────────────────────────────────────────────┐ ┌────────────────────────────────────────┐ 238# │ $ns1 namespace │ │ $ns0 namespace │ │ $ns2 namespace │ 239# │ │ │ │ │ │ 240# │ ┌─────┐ ┌─────┐ │ │ ┌──────┐ ┌──────┐ │ │ ┌─────┐ ┌─────┐ │ 241# │ │ wg0 │─────────────│vethc│───────────┼────┼────│vethrc│ │vethrs│──────────────┼─────┼──│veths│────────────│ wg0 │ │ 242# │ ├─────┴──────────┐ ├─────┴──────────┐│ │ ├──────┴─────────┐ ├──────┴────────────┐ │ │ ├─────┴──────────┐ ├─────┴──────────┐ │ 243# │ │192.168.241.1/24│ │192.168.1.100/24││ │ │192.168.1.1/24 │ │10.0.0.1/24 │ │ │ │10.0.0.100/24 │ │192.168.241.2/24│ │ 244# │ │fd00::1/24 │ │ ││ │ │ │ │SNAT:192.168.1.0/24│ │ │ │ │ │fd00::2/24 │ │ 245# │ └────────────────┘ └────────────────┘│ │ └────────────────┘ └───────────────────┘ │ │ └────────────────┘ └────────────────┘ │ 246# └────────────────────────────────────────┘ └────────────────────────────────────────────────┘ └────────────────────────────────────────┘ 247 248ip1 link add dev wg0 type wireguard 249ip2 link add dev wg0 type wireguard 250configure_peers 251 252ip0 link add vethrc type veth peer name vethc 253ip0 link add vethrs type veth peer name veths 254ip0 link set vethc netns $netns1 255ip0 link set veths netns $netns2 256ip0 link set vethrc up 257ip0 link set vethrs up 258ip0 addr add 192.168.1.1/24 dev vethrc 259ip0 addr add 10.0.0.1/24 dev vethrs 260ip1 addr add 192.168.1.100/24 dev vethc 261ip1 link set vethc up 262ip1 route add default via 192.168.1.1 263ip2 addr add 10.0.0.100/24 dev veths 264ip2 link set veths up 265waitiface $netns0 vethrc 266waitiface $netns0 vethrs 267waitiface $netns1 vethc 268waitiface $netns2 veths 269 270n0 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_forward' 271n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout' 272n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream' 273n0 iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 10.0.0.0/24 -j SNAT --to 10.0.0.1 274 275n1 wg set wg0 peer "$pub2" endpoint 10.0.0.100:2 persistent-keepalive 1 276n1 ping -W 1 -c 1 192.168.241.2 277n2 ping -W 1 -c 1 192.168.241.1 278[[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.1:1" ]] 279# Demonstrate n2 can still send packets to n1, since persistent-keepalive will prevent connection tracking entry from expiring (to see entries: `n0 conntrack -L`). 280pp sleep 3 281n2 ping -W 1 -c 1 192.168.241.1 282n1 wg set wg0 peer "$pub2" persistent-keepalive 0 283 284# Do a wg-quick(8)-style policy routing for the default route, making sure vethc has a v6 address to tease out bugs. 285ip1 -6 addr add fc00::9/96 dev vethc 286ip1 -6 route add default via fc00::1 287ip2 -4 addr add 192.168.99.7/32 dev wg0 288ip2 -6 addr add abab::1111/128 dev wg0 289n1 wg set wg0 fwmark 51820 peer "$pub2" allowed-ips 192.168.99.7,abab::1111 290ip1 -6 route add default dev wg0 table 51820 291ip1 -6 rule add not fwmark 51820 table 51820 292ip1 -6 rule add table main suppress_prefixlength 0 293ip1 -4 route add default dev wg0 table 51820 294ip1 -4 rule add not fwmark 51820 table 51820 295ip1 -4 rule add table main suppress_prefixlength 0 296# Flood the pings instead of sending just one, to trigger routing table reference counting bugs. 297n1 ping -W 1 -c 100 -f 192.168.99.7 298n1 ping -W 1 -c 100 -f abab::1111 299 300n0 iptables -t nat -F 301ip0 link del vethrc 302ip0 link del vethrs 303ip1 link del wg0 304ip2 link del wg0 305 306# Test that saddr routing is sticky but not too sticky, changing to this topology: 307# ┌────────────────────────────────────────┐ ┌────────────────────────────────────────┐ 308# │ $ns1 namespace │ │ $ns2 namespace │ 309# │ │ │ │ 310# │ ┌─────┐ ┌─────┐ │ │ ┌─────┐ ┌─────┐ │ 311# │ │ wg0 │─────────────│veth1│───────────┼────┼──│veth2│────────────│ wg0 │ │ 312# │ ├─────┴──────────┐ ├─────┴──────────┐│ │ ├─────┴──────────┐ ├─────┴──────────┐ │ 313# │ │192.168.241.1/24│ │10.0.0.1/24 ││ │ │10.0.0.2/24 │ │192.168.241.2/24│ │ 314# │ │fd00::1/24 │ │fd00:aa::1/96 ││ │ │fd00:aa::2/96 │ │fd00::2/24 │ │ 315# │ └────────────────┘ └────────────────┘│ │ └────────────────┘ └────────────────┘ │ 316# └────────────────────────────────────────┘ └────────────────────────────────────────┘ 317 318ip1 link add dev wg0 type wireguard 319ip2 link add dev wg0 type wireguard 320configure_peers 321ip1 link add veth1 type veth peer name veth2 322ip1 link set veth2 netns $netns2 323n1 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/all/accept_dad' 324n2 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/all/accept_dad' 325n1 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/veth1/accept_dad' 326n2 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/veth2/accept_dad' 327n1 bash -c 'printf 1 > /proc/sys/net/ipv4/conf/veth1/promote_secondaries' 328 329# First we check that we aren't overly sticky and can fall over to new IPs when old ones are removed 330ip1 addr add 10.0.0.1/24 dev veth1 331ip1 addr add fd00:aa::1/96 dev veth1 332ip2 addr add 10.0.0.2/24 dev veth2 333ip2 addr add fd00:aa::2/96 dev veth2 334ip1 link set veth1 up 335ip2 link set veth2 up 336waitiface $netns1 veth1 337waitiface $netns2 veth2 338n1 wg set wg0 peer "$pub2" endpoint 10.0.0.2:2 339n1 ping -W 1 -c 1 192.168.241.2 340ip1 addr add 10.0.0.10/24 dev veth1 341ip1 addr del 10.0.0.1/24 dev veth1 342n1 ping -W 1 -c 1 192.168.241.2 343n1 wg set wg0 peer "$pub2" endpoint [fd00:aa::2]:2 344n1 ping -W 1 -c 1 192.168.241.2 345ip1 addr add fd00:aa::10/96 dev veth1 346ip1 addr del fd00:aa::1/96 dev veth1 347n1 ping -W 1 -c 1 192.168.241.2 348 349# Now we show that we can successfully do reply to sender routing 350ip1 link set veth1 down 351ip2 link set veth2 down 352ip1 addr flush dev veth1 353ip2 addr flush dev veth2 354ip1 addr add 10.0.0.1/24 dev veth1 355ip1 addr add 10.0.0.2/24 dev veth1 356ip1 addr add fd00:aa::1/96 dev veth1 357ip1 addr add fd00:aa::2/96 dev veth1 358ip2 addr add 10.0.0.3/24 dev veth2 359ip2 addr add fd00:aa::3/96 dev veth2 360ip1 link set veth1 up 361ip2 link set veth2 up 362waitiface $netns1 veth1 363waitiface $netns2 veth2 364n2 wg set wg0 peer "$pub1" endpoint 10.0.0.1:1 365n2 ping -W 1 -c 1 192.168.241.1 366[[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.1:1" ]] 367n2 wg set wg0 peer "$pub1" endpoint [fd00:aa::1]:1 368n2 ping -W 1 -c 1 192.168.241.1 369[[ $(n2 wg show wg0 endpoints) == "$pub1 [fd00:aa::1]:1" ]] 370n2 wg set wg0 peer "$pub1" endpoint 10.0.0.2:1 371n2 ping -W 1 -c 1 192.168.241.1 372[[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.2:1" ]] 373n2 wg set wg0 peer "$pub1" endpoint [fd00:aa::2]:1 374n2 ping -W 1 -c 1 192.168.241.1 375[[ $(n2 wg show wg0 endpoints) == "$pub1 [fd00:aa::2]:1" ]] 376 377# What happens if the inbound destination address belongs to a different interface as the default route? 378ip1 link add dummy0 type dummy 379ip1 addr add 10.50.0.1/24 dev dummy0 380ip1 link set dummy0 up 381ip2 route add 10.50.0.0/24 dev veth2 382n2 wg set wg0 peer "$pub1" endpoint 10.50.0.1:1 383n2 ping -W 1 -c 1 192.168.241.1 384[[ $(n2 wg show wg0 endpoints) == "$pub1 10.50.0.1:1" ]] 385 386ip1 link del dummy0 387ip1 addr flush dev veth1 388ip2 addr flush dev veth2 389ip1 route flush dev veth1 390ip2 route flush dev veth2 391 392# Now we see what happens if another interface route takes precedence over an ongoing one 393ip1 link add veth3 type veth peer name veth4 394ip1 link set veth4 netns $netns2 395ip1 addr add 10.0.0.1/24 dev veth1 396ip2 addr add 10.0.0.2/24 dev veth2 397ip1 addr add 10.0.0.3/24 dev veth3 398ip1 link set veth1 up 399ip2 link set veth2 up 400ip1 link set veth3 up 401ip2 link set veth4 up 402waitiface $netns1 veth1 403waitiface $netns2 veth2 404waitiface $netns1 veth3 405waitiface $netns2 veth4 406ip1 route flush dev veth1 407ip1 route flush dev veth3 408ip1 route add 10.0.0.0/24 dev veth1 src 10.0.0.1 metric 2 409n1 wg set wg0 peer "$pub2" endpoint 10.0.0.2:2 410n1 ping -W 1 -c 1 192.168.241.2 411[[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.1:1" ]] 412ip1 route add 10.0.0.0/24 dev veth3 src 10.0.0.3 metric 1 413n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/veth1/rp_filter' 414n2 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/veth4/rp_filter' 415n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/all/rp_filter' 416n2 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/all/rp_filter' 417n1 ping -W 1 -c 1 192.168.241.2 418[[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.3:1" ]] 419 420ip1 link del veth1 421ip1 link del veth3 422ip1 link del wg0 423ip2 link del wg0 424 425# We test that Netlink/IPC is working properly by doing things that usually cause split responses 426ip0 link add dev wg0 type wireguard 427config=( "[Interface]" "PrivateKey=$(wg genkey)" "[Peer]" "PublicKey=$(wg genkey)" ) 428for a in {1..255}; do 429 for b in {0..255}; do 430 config+=( "AllowedIPs=$a.$b.0.0/16,$a::$b/128" ) 431 done 432done 433n0 wg setconf wg0 <(printf '%s\n' "${config[@]}") 434i=0 435for ip in $(n0 wg show wg0 allowed-ips); do 436 ((++i)) 437done 438((i == 255*256*2+1)) 439ip0 link del wg0 440ip0 link add dev wg0 type wireguard 441config=( "[Interface]" "PrivateKey=$(wg genkey)" ) 442for a in {1..40}; do 443 config+=( "[Peer]" "PublicKey=$(wg genkey)" ) 444 for b in {1..52}; do 445 config+=( "AllowedIPs=$a.$b.0.0/16" ) 446 done 447done 448n0 wg setconf wg0 <(printf '%s\n' "${config[@]}") 449i=0 450while read -r line; do 451 j=0 452 for ip in $line; do 453 ((++j)) 454 done 455 ((j == 53)) 456 ((++i)) 457done < <(n0 wg show wg0 allowed-ips) 458((i == 40)) 459ip0 link del wg0 460ip0 link add wg0 type wireguard 461config=( ) 462for i in {1..29}; do 463 config+=( "[Peer]" "PublicKey=$(wg genkey)" ) 464done 465config+=( "[Peer]" "PublicKey=$(wg genkey)" "AllowedIPs=255.2.3.4/32,abcd::255/128" ) 466n0 wg setconf wg0 <(printf '%s\n' "${config[@]}") 467n0 wg showconf wg0 > /dev/null 468ip0 link del wg0 469 470allowedips=( ) 471for i in {1..197}; do 472 allowedips+=( abcd::$i ) 473done 474saved_ifs="$IFS" 475IFS=, 476allowedips="${allowedips[*]}" 477IFS="$saved_ifs" 478ip0 link add wg0 type wireguard 479n0 wg set wg0 peer "$pub1" 480n0 wg set wg0 peer "$pub2" allowed-ips "$allowedips" 481{ 482 read -r pub allowedips 483 [[ $pub == "$pub1" && $allowedips == "(none)" ]] 484 read -r pub allowedips 485 [[ $pub == "$pub2" ]] 486 i=0 487 for _ in $allowedips; do 488 ((++i)) 489 done 490 ((i == 197)) 491} < <(n0 wg show wg0 allowed-ips) 492ip0 link del wg0 493 494! n0 wg show doesnotexist || false 495 496ip0 link add wg0 type wireguard 497n0 wg set wg0 private-key <(echo "$key1") peer "$pub2" preshared-key <(echo "$psk") 498[[ $(n0 wg show wg0 private-key) == "$key1" ]] 499[[ $(n0 wg show wg0 preshared-keys) == "$pub2 $psk" ]] 500n0 wg set wg0 private-key /dev/null peer "$pub2" preshared-key /dev/null 501[[ $(n0 wg show wg0 private-key) == "(none)" ]] 502[[ $(n0 wg show wg0 preshared-keys) == "$pub2 (none)" ]] 503n0 wg set wg0 peer "$pub2" 504n0 wg set wg0 private-key <(echo "$key2") 505[[ $(n0 wg show wg0 public-key) == "$pub2" ]] 506[[ -z $(n0 wg show wg0 peers) ]] 507n0 wg set wg0 peer "$pub2" 508[[ -z $(n0 wg show wg0 peers) ]] 509n0 wg set wg0 private-key <(echo "$key1") 510n0 wg set wg0 peer "$pub2" 511[[ $(n0 wg show wg0 peers) == "$pub2" ]] 512n0 wg set wg0 private-key <(echo "/${key1:1}") 513[[ $(n0 wg show wg0 private-key) == "+${key1:1}" ]] 514n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0,10.0.0.0/8,100.0.0.0/10,172.16.0.0/12,192.168.0.0/16 515n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0 516n0 wg set wg0 peer "$pub2" allowed-ips ::/0,1700::/111,5000::/4,e000::/37,9000::/75 517n0 wg set wg0 peer "$pub2" allowed-ips ::/0 518n0 wg set wg0 peer "$pub2" remove 519low_order_points=( AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 4Ot6fDtBuK4WVuP68Z/EatoJjeucMrH9hmIFFl9JuAA= X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEVc= 7P///////////////////////////////////////38= 7f///////////////////////////////////////38= 7v///////////////////////////////////////38= ) 520n0 wg set wg0 private-key /dev/null ${low_order_points[@]/#/peer } 521[[ -z $(n0 wg show wg0 peers) ]] 522n0 wg set wg0 private-key <(echo "$key1") ${low_order_points[@]/#/peer } 523[[ -z $(n0 wg show wg0 peers) ]] 524ip0 link del wg0 525 526declare -A objects 527while read -t 0.1 -r line 2>/dev/null || [[ $? -ne 142 ]]; do 528 [[ $line =~ .*(wg[0-9]+:\ [A-Z][a-z]+\ [0-9]+)\ .*(created|destroyed).* ]] || continue 529 objects["${BASH_REMATCH[1]}"]+="${BASH_REMATCH[2]}" 530done < /dev/kmsg 531alldeleted=1 532for object in "${!objects[@]}"; do 533 if [[ ${objects["$object"]} != *createddestroyed ]]; then 534 echo "Error: $object: merely ${objects["$object"]}" >&3 535 alldeleted=0 536 fi 537done 538[[ $alldeleted -eq 1 ]] 539pretty "" "Objects that were created were also destroyed." 540