1 #!/bin/bash 1 #!/bin/bash 2 # SPDX-License-Identifier: GPL-2.0 2 # SPDX-License-Identifier: GPL-2.0 3 # 3 # 4 # Copyright (C) 2015-2019 Jason A. Donenfeld <J 4 # Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. 5 # 5 # 6 # This script tests the below topology: 6 # This script tests the below topology: 7 # 7 # 8 # ┌───────────── 8 # ┌─────────────────────┐ ┌──────────────────────────────────┐ ┌─────────────────────┐ 9 # │ $ns1 namespace │ │ $ 9 # │ $ns1 namespace │ │ $ns0 namespace │ │ $ns2 namespace │ 10 # │ │ │ 10 # │ │ │ │ │ │ 11 # │┌────────┐ 11 # │┌────────┐ │ │ ┌────────┐ │ │ ┌────────┐│ 12 # ││ wg0 │───────── 12 # ││ wg0 │───────────┼───┼────────────│ lo │────────────┼───┼───────────│ wg0 ││ 13 # │├────────┴─── 13 # │├────────┴──────────┐│ │ ┌───────┴────────┴────────┐ │ │┌──────────┴────────┤│ 14 # ││192.168.241.1/24 ││ │ │ 14 # ││192.168.241.1/24 ││ │ │(ns1) (ns2) │ │ ││192.168.241.2/24 ││ 15 # ││fd00::1/24 ││ │ │ 15 # ││fd00::1/24 ││ │ │127.0.0.1:1 127.0.0.1:2│ │ ││fd00::2/24 ││ 16 # │└──────────── 16 # │└───────────────────┘│ │ │[::]:1 [::]:2 │ │ │└───────────────────┘│ 17 # └───────────── 17 # └─────────────────────┘ │ └─────────────────────────┘ │ └─────────────────────┘ 18 # └───── 18 # └──────────────────────────────────┘ 19 # 19 # 20 # After the topology is prepared we run a seri 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 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 22 # interfaces in $ns1 and $ns2. See https://www.wireguard.com/netns/ for further 23 # details on how this is accomplished. 23 # details on how this is accomplished. 24 set -e 24 set -e 25 shopt -s extglob 25 shopt -s extglob 26 26 27 exec 3>&1 27 exec 3>&1 28 export LANG=C 28 export LANG=C 29 export WG_HIDE_KEYS=never 29 export WG_HIDE_KEYS=never 30 NPROC=( /sys/devices/system/cpu/cpu+([0-9]) ); 30 NPROC=( /sys/devices/system/cpu/cpu+([0-9]) ); NPROC=${#NPROC[@]} 31 netns0="wg-test-$$-0" 31 netns0="wg-test-$$-0" 32 netns1="wg-test-$$-1" 32 netns1="wg-test-$$-1" 33 netns2="wg-test-$$-2" 33 netns2="wg-test-$$-2" 34 pretty() { echo -e "\x1b[32m\x1b[1m[+] ${1:+NS 34 pretty() { echo -e "\x1b[32m\x1b[1m[+] ${1:+NS$1: }${2}\x1b[0m" >&3; } 35 pp() { pretty "" "$*"; "$@"; } 35 pp() { pretty "" "$*"; "$@"; } 36 maybe_exec() { if [[ $BASHPID -eq $$ ]]; then 36 maybe_exec() { if [[ $BASHPID -eq $$ ]]; then "$@"; else exec "$@"; fi; } 37 n0() { pretty 0 "$*"; maybe_exec ip netns exec 37 n0() { pretty 0 "$*"; maybe_exec ip netns exec $netns0 "$@"; } 38 n1() { pretty 1 "$*"; maybe_exec ip netns exec 38 n1() { pretty 1 "$*"; maybe_exec ip netns exec $netns1 "$@"; } 39 n2() { pretty 2 "$*"; maybe_exec ip netns exec 39 n2() { pretty 2 "$*"; maybe_exec ip netns exec $netns2 "$@"; } 40 ip0() { pretty 0 "ip $*"; ip -n $netns0 "$@"; 40 ip0() { pretty 0 "ip $*"; ip -n $netns0 "$@"; } 41 ip1() { pretty 1 "ip $*"; ip -n $netns1 "$@"; 41 ip1() { pretty 1 "ip $*"; ip -n $netns1 "$@"; } 42 ip2() { pretty 2 "ip $*"; ip -n $netns2 "$@"; 42 ip2() { pretty 2 "ip $*"; ip -n $netns2 "$@"; } 43 sleep() { read -t "$1" -N 1 || true; } 43 sleep() { read -t "$1" -N 1 || true; } 44 waitiperf() { pretty "${1//*-}" "wait for iper 44 waitiperf() { pretty "${1//*-}" "wait for iperf:${3:-5201} pid $2"; while [[ $(ss -N "$1" -tlpH "sport = ${3:-5201}") != *\"iperf3\",pid=$2,fd=* ]]; do sleep 0.1; done; } 45 waitncatudp() { pretty "${1//*-}" "wait for ud 45 waitncatudp() { pretty "${1//*-}" "wait for udp:1111 pid $2"; while [[ $(ss -N "$1" -ulpH 'sport = 1111') != *\"ncat\",pid=$2,fd=* ]]; do sleep 0.1; done; } 46 waitiface() { pretty "${1//*-}" "wait for $2 t 46 waitiface() { 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;"; } 47 47 48 cleanup() { 48 cleanup() { 49 set +e 49 set +e 50 exec 2>/dev/null 50 exec 2>/dev/null 51 printf "$orig_message_cost" > /proc/sy 51 printf "$orig_message_cost" > /proc/sys/net/core/message_cost 52 ip0 link del dev wg0 52 ip0 link del dev wg0 53 ip0 link del dev wg1 53 ip0 link del dev wg1 54 ip1 link del dev wg0 54 ip1 link del dev wg0 55 ip1 link del dev wg1 55 ip1 link del dev wg1 56 ip2 link del dev wg0 56 ip2 link del dev wg0 57 ip2 link del dev wg1 57 ip2 link del dev wg1 58 local to_kill="$(ip netns pids $netns0 58 local to_kill="$(ip netns pids $netns0) $(ip netns pids $netns1) $(ip netns pids $netns2)" 59 [[ -n $to_kill ]] && kill $to_kill 59 [[ -n $to_kill ]] && kill $to_kill 60 pp ip netns del $netns1 60 pp ip netns del $netns1 61 pp ip netns del $netns2 61 pp ip netns del $netns2 62 pp ip netns del $netns0 62 pp ip netns del $netns0 63 exit 63 exit 64 } 64 } 65 65 66 orig_message_cost="$(< /proc/sys/net/core/mess 66 orig_message_cost="$(< /proc/sys/net/core/message_cost)" 67 trap cleanup EXIT 67 trap cleanup EXIT 68 printf 0 > /proc/sys/net/core/message_cost 68 printf 0 > /proc/sys/net/core/message_cost 69 69 70 ip netns del $netns0 2>/dev/null || true 70 ip netns del $netns0 2>/dev/null || true 71 ip netns del $netns1 2>/dev/null || true 71 ip netns del $netns1 2>/dev/null || true 72 ip netns del $netns2 2>/dev/null || true 72 ip netns del $netns2 2>/dev/null || true 73 pp ip netns add $netns0 73 pp ip netns add $netns0 74 pp ip netns add $netns1 74 pp ip netns add $netns1 75 pp ip netns add $netns2 75 pp ip netns add $netns2 76 ip0 link set up dev lo 76 ip0 link set up dev lo 77 77 78 ip0 link add dev wg0 type wireguard 78 ip0 link add dev wg0 type wireguard 79 ip0 link set wg0 netns $netns1 79 ip0 link set wg0 netns $netns1 80 ip0 link add dev wg0 type wireguard 80 ip0 link add dev wg0 type wireguard 81 ip0 link set wg0 netns $netns2 81 ip0 link set wg0 netns $netns2 82 key1="$(pp wg genkey)" 82 key1="$(pp wg genkey)" 83 key2="$(pp wg genkey)" 83 key2="$(pp wg genkey)" 84 key3="$(pp wg genkey)" 84 key3="$(pp wg genkey)" 85 key4="$(pp wg genkey)" 85 key4="$(pp wg genkey)" 86 pub1="$(pp wg pubkey <<<"$key1")" 86 pub1="$(pp wg pubkey <<<"$key1")" 87 pub2="$(pp wg pubkey <<<"$key2")" 87 pub2="$(pp wg pubkey <<<"$key2")" 88 pub3="$(pp wg pubkey <<<"$key3")" 88 pub3="$(pp wg pubkey <<<"$key3")" 89 pub4="$(pp wg pubkey <<<"$key4")" 89 pub4="$(pp wg pubkey <<<"$key4")" 90 psk="$(pp wg genpsk)" 90 psk="$(pp wg genpsk)" 91 [[ -n $key1 && -n $key2 && -n $psk ]] 91 [[ -n $key1 && -n $key2 && -n $psk ]] 92 92 93 configure_peers() { 93 configure_peers() { 94 ip1 addr add 192.168.241.1/24 dev wg0 94 ip1 addr add 192.168.241.1/24 dev wg0 95 ip1 addr add fd00::1/112 dev wg0 95 ip1 addr add fd00::1/112 dev wg0 96 96 97 ip2 addr add 192.168.241.2/24 dev wg0 97 ip2 addr add 192.168.241.2/24 dev wg0 98 ip2 addr add fd00::2/112 dev wg0 98 ip2 addr add fd00::2/112 dev wg0 99 99 100 n1 wg set wg0 \ 100 n1 wg set wg0 \ 101 private-key <(echo "$key1") \ 101 private-key <(echo "$key1") \ 102 listen-port 1 \ 102 listen-port 1 \ 103 peer "$pub2" \ 103 peer "$pub2" \ 104 preshared-key <(echo " 104 preshared-key <(echo "$psk") \ 105 allowed-ips 192.168.24 105 allowed-ips 192.168.241.2/32,fd00::2/128 106 n2 wg set wg0 \ 106 n2 wg set wg0 \ 107 private-key <(echo "$key2") \ 107 private-key <(echo "$key2") \ 108 listen-port 2 \ 108 listen-port 2 \ 109 peer "$pub1" \ 109 peer "$pub1" \ 110 preshared-key <(echo " 110 preshared-key <(echo "$psk") \ 111 allowed-ips 192.168.24 111 allowed-ips 192.168.241.1/32,fd00::1/128 112 112 113 ip1 link set up dev wg0 113 ip1 link set up dev wg0 114 ip2 link set up dev wg0 114 ip2 link set up dev wg0 115 } 115 } 116 configure_peers 116 configure_peers 117 117 118 tests() { 118 tests() { 119 # Ping over IPv4 119 # Ping over IPv4 120 n2 ping -c 10 -f -W 1 192.168.241.1 120 n2 ping -c 10 -f -W 1 192.168.241.1 121 n1 ping -c 10 -f -W 1 192.168.241.2 121 n1 ping -c 10 -f -W 1 192.168.241.2 122 122 123 # Ping over IPv6 123 # Ping over IPv6 124 n2 ping6 -c 10 -f -W 1 fd00::1 124 n2 ping6 -c 10 -f -W 1 fd00::1 125 n1 ping6 -c 10 -f -W 1 fd00::2 125 n1 ping6 -c 10 -f -W 1 fd00::2 126 126 127 # TCP over IPv4 127 # TCP over IPv4 128 n2 iperf3 -s -1 -B 192.168.241.2 & 128 n2 iperf3 -s -1 -B 192.168.241.2 & 129 waitiperf $netns2 $! 129 waitiperf $netns2 $! 130 n1 iperf3 -Z -t 3 -c 192.168.241.2 130 n1 iperf3 -Z -t 3 -c 192.168.241.2 131 131 132 # TCP over IPv6 132 # TCP over IPv6 133 n1 iperf3 -s -1 -B fd00::1 & 133 n1 iperf3 -s -1 -B fd00::1 & 134 waitiperf $netns1 $! 134 waitiperf $netns1 $! 135 n2 iperf3 -Z -t 3 -c fd00::1 135 n2 iperf3 -Z -t 3 -c fd00::1 136 136 137 # UDP over IPv4 137 # UDP over IPv4 138 n1 iperf3 -s -1 -B 192.168.241.1 & 138 n1 iperf3 -s -1 -B 192.168.241.1 & 139 waitiperf $netns1 $! 139 waitiperf $netns1 $! 140 n2 iperf3 -Z -t 3 -b 0 -u -c 192.168.2 140 n2 iperf3 -Z -t 3 -b 0 -u -c 192.168.241.1 141 141 142 # UDP over IPv6 142 # UDP over IPv6 143 n2 iperf3 -s -1 -B fd00::2 & 143 n2 iperf3 -s -1 -B fd00::2 & 144 waitiperf $netns2 $! 144 waitiperf $netns2 $! 145 n1 iperf3 -Z -t 3 -b 0 -u -c fd00::2 145 n1 iperf3 -Z -t 3 -b 0 -u -c fd00::2 146 146 147 # TCP over IPv4, in parallel 147 # TCP over IPv4, in parallel 148 local pids=( ) i 148 local pids=( ) i 149 for ((i=0; i < NPROC; ++i)) do 149 for ((i=0; i < NPROC; ++i)) do 150 n2 iperf3 -p $(( 5200 + i )) - 150 n2 iperf3 -p $(( 5200 + i )) -s -1 -B 192.168.241.2 & 151 pids+=( $! ); waitiperf $netns 151 pids+=( $! ); waitiperf $netns2 $! $(( 5200 + i )) 152 done 152 done 153 for ((i=0; i < NPROC; ++i)) do 153 for ((i=0; i < NPROC; ++i)) do 154 n1 iperf3 -Z -t 3 -p $(( 5200 154 n1 iperf3 -Z -t 3 -p $(( 5200 + i )) -c 192.168.241.2 & 155 done 155 done 156 wait "${pids[@]}" 156 wait "${pids[@]}" 157 } 157 } 158 158 159 [[ $(ip1 link show dev wg0) =~ mtu\ ([0-9]+) ] 159 [[ $(ip1 link show dev wg0) =~ mtu\ ([0-9]+) ]] && orig_mtu="${BASH_REMATCH[1]}" 160 big_mtu=$(( 34816 - 1500 + $orig_mtu )) 160 big_mtu=$(( 34816 - 1500 + $orig_mtu )) 161 161 162 # Test using IPv4 as outer transport 162 # Test using IPv4 as outer transport 163 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1: 163 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2 164 n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1: 164 n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1:1 165 # Before calling tests, we first make sure tha 165 # Before calling tests, we first make sure that the stats counters and timestamper are working 166 n2 ping -c 10 -f -W 1 192.168.241.1 166 n2 ping -c 10 -f -W 1 192.168.241.1 167 { read _; read _; read _; read rx_bytes _; rea 167 { read _; read _; read _; read rx_bytes _; read _; read tx_bytes _; } < <(ip2 -stats link show dev wg0) 168 (( rx_bytes == 1372 && (tx_bytes == 1428 || tx 168 (( rx_bytes == 1372 && (tx_bytes == 1428 || tx_bytes == 1460) )) 169 { read _; read _; read _; read rx_bytes _; rea 169 { read _; read _; read _; read rx_bytes _; read _; read tx_bytes _; } < <(ip1 -stats link show dev wg0) 170 (( tx_bytes == 1372 && (rx_bytes == 1428 || rx 170 (( tx_bytes == 1372 && (rx_bytes == 1428 || rx_bytes == 1460) )) 171 read _ rx_bytes tx_bytes < <(n2 wg show wg0 tr 171 read _ rx_bytes tx_bytes < <(n2 wg show wg0 transfer) 172 (( rx_bytes == 1372 && (tx_bytes == 1428 || tx 172 (( rx_bytes == 1372 && (tx_bytes == 1428 || tx_bytes == 1460) )) 173 read _ rx_bytes tx_bytes < <(n1 wg show wg0 tr 173 read _ rx_bytes tx_bytes < <(n1 wg show wg0 transfer) 174 (( tx_bytes == 1372 && (rx_bytes == 1428 || rx 174 (( tx_bytes == 1372 && (rx_bytes == 1428 || rx_bytes == 1460) )) 175 read _ timestamp < <(n1 wg show wg0 latest-han 175 read _ timestamp < <(n1 wg show wg0 latest-handshakes) 176 (( timestamp != 0 )) 176 (( timestamp != 0 )) 177 177 178 tests 178 tests 179 ip1 link set wg0 mtu $big_mtu 179 ip1 link set wg0 mtu $big_mtu 180 ip2 link set wg0 mtu $big_mtu 180 ip2 link set wg0 mtu $big_mtu 181 tests 181 tests 182 182 183 ip1 link set wg0 mtu $orig_mtu 183 ip1 link set wg0 mtu $orig_mtu 184 ip2 link set wg0 mtu $orig_mtu 184 ip2 link set wg0 mtu $orig_mtu 185 185 186 # Test using IPv6 as outer transport 186 # Test using IPv6 as outer transport 187 n1 wg set wg0 peer "$pub2" endpoint [::1]:2 187 n1 wg set wg0 peer "$pub2" endpoint [::1]:2 188 n2 wg set wg0 peer "$pub1" endpoint [::1]:1 188 n2 wg set wg0 peer "$pub1" endpoint [::1]:1 189 tests 189 tests 190 ip1 link set wg0 mtu $big_mtu 190 ip1 link set wg0 mtu $big_mtu 191 ip2 link set wg0 mtu $big_mtu 191 ip2 link set wg0 mtu $big_mtu 192 tests 192 tests 193 193 194 # Test that route MTUs work with the padding 194 # Test that route MTUs work with the padding 195 ip1 link set wg0 mtu 1300 195 ip1 link set wg0 mtu 1300 196 ip2 link set wg0 mtu 1300 196 ip2 link set wg0 mtu 1300 197 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1: 197 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2 198 n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1: 198 n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1:1 199 n0 iptables -A INPUT -m length --length 1360 - 199 n0 iptables -A INPUT -m length --length 1360 -j DROP 200 n1 ip route add 192.168.241.2/32 dev wg0 mtu 1 200 n1 ip route add 192.168.241.2/32 dev wg0 mtu 1299 201 n2 ip route add 192.168.241.1/32 dev wg0 mtu 1 201 n2 ip route add 192.168.241.1/32 dev wg0 mtu 1299 202 n2 ping -c 1 -W 1 -s 1269 192.168.241.1 202 n2 ping -c 1 -W 1 -s 1269 192.168.241.1 203 n2 ip route delete 192.168.241.1/32 dev wg0 mt 203 n2 ip route delete 192.168.241.1/32 dev wg0 mtu 1299 204 n1 ip route delete 192.168.241.2/32 dev wg0 mt 204 n1 ip route delete 192.168.241.2/32 dev wg0 mtu 1299 205 n0 iptables -F INPUT 205 n0 iptables -F INPUT 206 206 207 ip1 link set wg0 mtu $orig_mtu 207 ip1 link set wg0 mtu $orig_mtu 208 ip2 link set wg0 mtu $orig_mtu 208 ip2 link set wg0 mtu $orig_mtu 209 209 210 # Test using IPv4 that roaming works 210 # Test using IPv4 that roaming works 211 ip0 -4 addr del 127.0.0.1/8 dev lo 211 ip0 -4 addr del 127.0.0.1/8 dev lo 212 ip0 -4 addr add 127.212.121.99/8 dev lo 212 ip0 -4 addr add 127.212.121.99/8 dev lo 213 n1 wg set wg0 listen-port 9999 213 n1 wg set wg0 listen-port 9999 214 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1: 214 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2 215 n1 ping6 -W 1 -c 1 fd00::2 215 n1 ping6 -W 1 -c 1 fd00::2 216 [[ $(n2 wg show wg0 endpoints) == "$pub1 216 [[ $(n2 wg show wg0 endpoints) == "$pub1 127.212.121.99:9999" ]] 217 217 218 # Test using IPv6 that roaming works 218 # Test using IPv6 that roaming works 219 n1 wg set wg0 listen-port 9998 219 n1 wg set wg0 listen-port 9998 220 n1 wg set wg0 peer "$pub2" endpoint [::1]:2 220 n1 wg set wg0 peer "$pub2" endpoint [::1]:2 221 n1 ping -W 1 -c 1 192.168.241.2 221 n1 ping -W 1 -c 1 192.168.241.2 222 [[ $(n2 wg show wg0 endpoints) == "$pub1 222 [[ $(n2 wg show wg0 endpoints) == "$pub1 [::1]:9998" ]] 223 223 224 # Test that crypto-RP filter works 224 # Test that crypto-RP filter works 225 n1 wg set wg0 peer "$pub2" allowed-ips 192.168 225 n1 wg set wg0 peer "$pub2" allowed-ips 192.168.241.0/24 226 exec 4< <(n1 ncat -l -u -p 1111) 226 exec 4< <(n1 ncat -l -u -p 1111) 227 ncat_pid=$! 227 ncat_pid=$! 228 waitncatudp $netns1 $ncat_pid 228 waitncatudp $netns1 $ncat_pid 229 n2 ncat -u 192.168.241.1 1111 <<<"X" 229 n2 ncat -u 192.168.241.1 1111 <<<"X" 230 read -r -N 1 -t 1 out <&4 && [[ $out == "X" ]] 230 read -r -N 1 -t 1 out <&4 && [[ $out == "X" ]] 231 kill $ncat_pid 231 kill $ncat_pid 232 more_specific_key="$(pp wg genkey | pp wg pubk 232 more_specific_key="$(pp wg genkey | pp wg pubkey)" 233 n1 wg set wg0 peer "$more_specific_key" allowe 233 n1 wg set wg0 peer "$more_specific_key" allowed-ips 192.168.241.2/32 234 n2 wg set wg0 listen-port 9997 234 n2 wg set wg0 listen-port 9997 235 exec 4< <(n1 ncat -l -u -p 1111) 235 exec 4< <(n1 ncat -l -u -p 1111) 236 ncat_pid=$! 236 ncat_pid=$! 237 waitncatudp $netns1 $ncat_pid 237 waitncatudp $netns1 $ncat_pid 238 n2 ncat -u 192.168.241.1 1111 <<<"X" 238 n2 ncat -u 192.168.241.1 1111 <<<"X" 239 ! read -r -N 1 -t 1 out <&4 || false 239 ! read -r -N 1 -t 1 out <&4 || false 240 kill $ncat_pid 240 kill $ncat_pid 241 n1 wg set wg0 peer "$more_specific_key" remove 241 n1 wg set wg0 peer "$more_specific_key" remove 242 [[ $(n1 wg show wg0 endpoints) == "$pub2 242 [[ $(n1 wg show wg0 endpoints) == "$pub2 [::1]:9997" ]] 243 243 244 # Test that we can change private keys keys an 244 # Test that we can change private keys keys and immediately handshake 245 n1 wg set wg0 private-key <(echo "$key1") peer 245 n1 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 246 n2 wg set wg0 private-key <(echo "$key2") list 246 n2 wg set wg0 private-key <(echo "$key2") listen-port 2 peer "$pub1" preshared-key <(echo "$psk") allowed-ips 192.168.241.1/32 247 n1 ping -W 1 -c 1 192.168.241.2 247 n1 ping -W 1 -c 1 192.168.241.2 248 n1 wg set wg0 private-key <(echo "$key3") 248 n1 wg set wg0 private-key <(echo "$key3") 249 n2 wg set wg0 peer "$pub3" preshared-key <(ech 249 n2 wg set wg0 peer "$pub3" preshared-key <(echo "$psk") allowed-ips 192.168.241.1/32 peer "$pub1" remove 250 n1 ping -W 1 -c 1 192.168.241.2 250 n1 ping -W 1 -c 1 192.168.241.2 251 n2 wg set wg0 peer "$pub3" remove 251 n2 wg set wg0 peer "$pub3" remove 252 252 253 # Test that we can route wg through wg 253 # Test that we can route wg through wg 254 ip1 addr flush dev wg0 254 ip1 addr flush dev wg0 255 ip2 addr flush dev wg0 255 ip2 addr flush dev wg0 256 ip1 addr add fd00::5:1/112 dev wg0 256 ip1 addr add fd00::5:1/112 dev wg0 257 ip2 addr add fd00::5:2/112 dev wg0 257 ip2 addr add fd00::5:2/112 dev wg0 258 n1 wg set wg0 private-key <(echo "$key1") peer 258 n1 wg set wg0 private-key <(echo "$key1") peer "$pub2" preshared-key <(echo "$psk") allowed-ips fd00::5:2/128 endpoint 127.0.0.1:2 259 n2 wg set wg0 private-key <(echo "$key2") list 259 n2 wg set wg0 private-key <(echo "$key2") listen-port 2 peer "$pub1" preshared-key <(echo "$psk") allowed-ips fd00::5:1/128 endpoint 127.212.121.99:9998 260 ip1 link add wg1 type wireguard 260 ip1 link add wg1 type wireguard 261 ip2 link add wg1 type wireguard 261 ip2 link add wg1 type wireguard 262 ip1 addr add 192.168.241.1/24 dev wg1 262 ip1 addr add 192.168.241.1/24 dev wg1 263 ip1 addr add fd00::1/112 dev wg1 263 ip1 addr add fd00::1/112 dev wg1 264 ip2 addr add 192.168.241.2/24 dev wg1 264 ip2 addr add 192.168.241.2/24 dev wg1 265 ip2 addr add fd00::2/112 dev wg1 265 ip2 addr add fd00::2/112 dev wg1 266 ip1 link set mtu 1340 up dev wg1 266 ip1 link set mtu 1340 up dev wg1 267 ip2 link set mtu 1340 up dev wg1 267 ip2 link set mtu 1340 up dev wg1 268 n1 wg set wg1 listen-port 5 private-key <(echo 268 n1 wg set wg1 listen-port 5 private-key <(echo "$key3") peer "$pub4" allowed-ips 192.168.241.2/32,fd00::2/128 endpoint [fd00::5:2]:5 269 n2 wg set wg1 listen-port 5 private-key <(echo 269 n2 wg set wg1 listen-port 5 private-key <(echo "$key4") peer "$pub3" allowed-ips 192.168.241.1/32,fd00::1/128 endpoint [fd00::5:1]:5 270 tests 270 tests 271 # Try to set up a routing loop between the two 271 # Try to set up a routing loop between the two namespaces 272 ip1 link set netns $netns0 dev wg1 272 ip1 link set netns $netns0 dev wg1 273 ip0 addr add 192.168.241.1/24 dev wg1 273 ip0 addr add 192.168.241.1/24 dev wg1 274 ip0 link set up dev wg1 274 ip0 link set up dev wg1 275 n0 ping -W 1 -c 1 192.168.241.2 275 n0 ping -W 1 -c 1 192.168.241.2 276 n1 wg set wg0 peer "$pub2" endpoint 192.168.24 276 n1 wg set wg0 peer "$pub2" endpoint 192.168.241.2:7 277 ip2 link del wg0 277 ip2 link del wg0 278 ip2 link del wg1 278 ip2 link del wg1 279 read _ _ tx_bytes_before < <(n0 wg show wg1 tr 279 read _ _ tx_bytes_before < <(n0 wg show wg1 transfer) 280 ! n0 ping -W 1 -c 10 -f 192.168.241.2 || false 280 ! n0 ping -W 1 -c 10 -f 192.168.241.2 || false 281 sleep 1 281 sleep 1 282 read _ _ tx_bytes_after < <(n0 wg show wg1 tra 282 read _ _ tx_bytes_after < <(n0 wg show wg1 transfer) 283 if ! (( tx_bytes_after - tx_bytes_before < 700 283 if ! (( tx_bytes_after - tx_bytes_before < 70000 )); then 284 errstart=$'\x1b[37m\x1b[41m\x1b[1m' 284 errstart=$'\x1b[37m\x1b[41m\x1b[1m' 285 errend=$'\x1b[0m' 285 errend=$'\x1b[0m' 286 echo "${errstart} 286 echo "${errstart} ${errend}" 287 echo "${errstart} E 287 echo "${errstart} E R R O R ${errend}" 288 echo "${errstart} 288 echo "${errstart} ${errend}" 289 echo "${errstart} This architecture do 289 echo "${errstart} This architecture does not do the right thing ${errend}" 290 echo "${errstart} with cross-namespace 290 echo "${errstart} with cross-namespace routing loops. This test ${errend}" 291 echo "${errstart} has thus technically 291 echo "${errstart} has thus technically failed but, as this issue ${errend}" 292 echo "${errstart} is as yet unsolved, 292 echo "${errstart} is as yet unsolved, these tests will continue ${errend}" 293 echo "${errstart} onward. :( 293 echo "${errstart} onward. :( ${errend}" 294 echo "${errstart} 294 echo "${errstart} ${errend}" 295 fi 295 fi 296 296 297 ip0 link del wg1 297 ip0 link del wg1 298 ip1 link del wg0 298 ip1 link del wg0 299 299 300 # Test using NAT. We now change the topology t 300 # Test using NAT. We now change the topology to this: 301 # ┌───────────── 301 # ┌────────────────────────────────────────┐ ┌────────────────────────────────────────────────┐ ┌────────────────────────────────────────┐ 302 # │ $ns1 namespace 302 # │ $ns1 namespace │ │ $ns0 namespace │ │ $ns2 namespace │ 303 # │ 303 # │ │ │ │ │ │ 304 # │ ┌─────┐ ┌ 304 # │ ┌─────┐ ┌─────┐ │ │ ┌──────┐ ┌──────┐ │ │ ┌─────┐ ┌─────┐ │ 305 # │ │ wg0 │───────── 305 # │ │ wg0 │─────────────│vethc│───────────┼────┼────│vethrc│ │vethrs│──────────────┼─────┼──│veths│────────────│ wg0 │ │ 306 # │ ├─────┴────── 306 # │ ├─────┴──────────┐ ├─────┴──────────┐│ │ ├──────┴─────────┐ ├──────┴────────────┐ │ │ ├─────┴──────────┐ ├─────┴──────────┐ │ 307 # │ │192.168.241.1/24│ │192.168.1.10 307 # │ │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│ │ 308 # │ │fd00::1/24 │ │ 308 # │ │fd00::1/24 │ │ ││ │ │ │ │SNAT:192.168.1.0/24│ │ │ │ │ │fd00::2/24 │ │ 309 # │ └──────────── 309 # │ └────────────────┘ └────────────────┘│ │ └────────────────┘ └───────────────────┘ │ │ └────────────────┘ └────────────────┘ │ 310 # └───────────── 310 # └────────────────────────────────────────┘ └────────────────────────────────────────────────┘ └────────────────────────────────────────┘ 311 311 312 ip1 link add dev wg0 type wireguard 312 ip1 link add dev wg0 type wireguard 313 ip2 link add dev wg0 type wireguard 313 ip2 link add dev wg0 type wireguard 314 configure_peers 314 configure_peers 315 315 316 ip0 link add vethrc type veth peer name vethc 316 ip0 link add vethrc type veth peer name vethc 317 ip0 link add vethrs type veth peer name veths 317 ip0 link add vethrs type veth peer name veths 318 ip0 link set vethc netns $netns1 318 ip0 link set vethc netns $netns1 319 ip0 link set veths netns $netns2 319 ip0 link set veths netns $netns2 320 ip0 link set vethrc up 320 ip0 link set vethrc up 321 ip0 link set vethrs up 321 ip0 link set vethrs up 322 ip0 addr add 192.168.1.1/24 dev vethrc 322 ip0 addr add 192.168.1.1/24 dev vethrc 323 ip0 addr add 10.0.0.1/24 dev vethrs 323 ip0 addr add 10.0.0.1/24 dev vethrs 324 ip1 addr add 192.168.1.100/24 dev vethc 324 ip1 addr add 192.168.1.100/24 dev vethc 325 ip1 link set vethc up 325 ip1 link set vethc up 326 ip1 route add default via 192.168.1.1 326 ip1 route add default via 192.168.1.1 327 ip2 addr add 10.0.0.100/24 dev veths 327 ip2 addr add 10.0.0.100/24 dev veths 328 ip2 link set veths up 328 ip2 link set veths up 329 waitiface $netns0 vethrc 329 waitiface $netns0 vethrc 330 waitiface $netns0 vethrs 330 waitiface $netns0 vethrs 331 waitiface $netns1 vethc 331 waitiface $netns1 vethc 332 waitiface $netns2 veths 332 waitiface $netns2 veths 333 333 334 n0 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_f 334 n0 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_forward' 335 n0 bash -c 'printf 2 > /proc/sys/net/netfilter 335 n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout' 336 n0 bash -c 'printf 2 > /proc/sys/net/netfilter 336 n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream' 337 n0 iptables -t nat -A POSTROUTING -s 192.168.1 337 n0 iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 10.0.0.0/24 -j SNAT --to 10.0.0.1 338 338 339 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.100 339 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.100:2 persistent-keepalive 1 340 n1 ping -W 1 -c 1 192.168.241.2 340 n1 ping -W 1 -c 1 192.168.241.2 341 n2 ping -W 1 -c 1 192.168.241.1 341 n2 ping -W 1 -c 1 192.168.241.1 342 [[ $(n2 wg show wg0 endpoints) == "$pub1 342 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.1:1" ]] 343 # Demonstrate n2 can still send packets to n1, 343 # Demonstrate n2 can still send packets to n1, since persistent-keepalive will prevent connection tracking entry from expiring (to see entries: `n0 conntrack -L`). 344 pp sleep 3 344 pp sleep 3 345 n2 ping -W 1 -c 1 192.168.241.1 345 n2 ping -W 1 -c 1 192.168.241.1 346 n1 wg set wg0 peer "$pub2" persistent-keepaliv 346 n1 wg set wg0 peer "$pub2" persistent-keepalive 0 347 347 348 # Test that sk_bound_dev_if works 348 # Test that sk_bound_dev_if works 349 n1 ping -I wg0 -c 1 -W 1 192.168.241.2 349 n1 ping -I wg0 -c 1 -W 1 192.168.241.2 350 # What about when the mark changes and the pac 350 # What about when the mark changes and the packet must be rerouted? 351 n1 iptables -t mangle -I OUTPUT -j MARK --set- 351 n1 iptables -t mangle -I OUTPUT -j MARK --set-xmark 1 352 n1 ping -c 1 -W 1 192.168.241.2 # First the bo 352 n1 ping -c 1 -W 1 192.168.241.2 # First the boring case 353 n1 ping -I wg0 -c 1 -W 1 192.168.241.2 # Then 353 n1 ping -I wg0 -c 1 -W 1 192.168.241.2 # Then the sk_bound_dev_if case 354 n1 iptables -t mangle -D OUTPUT -j MARK --set- 354 n1 iptables -t mangle -D OUTPUT -j MARK --set-xmark 1 355 355 356 # Test that onion routing works, even when it 356 # Test that onion routing works, even when it loops 357 n1 wg set wg0 peer "$pub3" allowed-ips 192.168 357 n1 wg set wg0 peer "$pub3" allowed-ips 192.168.242.2/32 endpoint 192.168.241.2:5 358 ip1 addr add 192.168.242.1/24 dev wg0 358 ip1 addr add 192.168.242.1/24 dev wg0 359 ip2 link add wg1 type wireguard 359 ip2 link add wg1 type wireguard 360 ip2 addr add 192.168.242.2/24 dev wg1 360 ip2 addr add 192.168.242.2/24 dev wg1 361 n2 wg set wg1 private-key <(echo "$key3") list 361 n2 wg set wg1 private-key <(echo "$key3") listen-port 5 peer "$pub1" allowed-ips 192.168.242.1/32 362 ip2 link set wg1 up 362 ip2 link set wg1 up 363 n1 ping -W 1 -c 1 192.168.242.2 363 n1 ping -W 1 -c 1 192.168.242.2 364 ip2 link del wg1 364 ip2 link del wg1 365 n1 wg set wg0 peer "$pub3" endpoint 192.168.24 365 n1 wg set wg0 peer "$pub3" endpoint 192.168.242.2:5 366 ! n1 ping -W 1 -c 1 192.168.242.2 || false # S 366 ! n1 ping -W 1 -c 1 192.168.242.2 || false # Should not crash kernel 367 n1 wg set wg0 peer "$pub3" remove 367 n1 wg set wg0 peer "$pub3" remove 368 ip1 addr del 192.168.242.1/24 dev wg0 368 ip1 addr del 192.168.242.1/24 dev wg0 369 369 370 # Do a wg-quick(8)-style policy routing for th 370 # Do a wg-quick(8)-style policy routing for the default route, making sure vethc has a v6 address to tease out bugs. 371 ip1 -6 addr add fc00::9/96 dev vethc 371 ip1 -6 addr add fc00::9/96 dev vethc 372 ip1 -6 route add default via fc00::1 372 ip1 -6 route add default via fc00::1 373 ip2 -4 addr add 192.168.99.7/32 dev wg0 373 ip2 -4 addr add 192.168.99.7/32 dev wg0 374 ip2 -6 addr add abab::1111/128 dev wg0 374 ip2 -6 addr add abab::1111/128 dev wg0 375 n1 wg set wg0 fwmark 51820 peer "$pub2" allowe 375 n1 wg set wg0 fwmark 51820 peer "$pub2" allowed-ips 192.168.99.7,abab::1111 376 ip1 -6 route add default dev wg0 table 51820 376 ip1 -6 route add default dev wg0 table 51820 377 ip1 -6 rule add not fwmark 51820 table 51820 377 ip1 -6 rule add not fwmark 51820 table 51820 378 ip1 -6 rule add table main suppress_prefixleng 378 ip1 -6 rule add table main suppress_prefixlength 0 379 ip1 -4 route add default dev wg0 table 51820 379 ip1 -4 route add default dev wg0 table 51820 380 ip1 -4 rule add not fwmark 51820 table 51820 380 ip1 -4 rule add not fwmark 51820 table 51820 381 ip1 -4 rule add table main suppress_prefixleng 381 ip1 -4 rule add table main suppress_prefixlength 0 382 n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf 382 n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/vethc/rp_filter' 383 # Flood the pings instead of sending just one, 383 # Flood the pings instead of sending just one, to trigger routing table reference counting bugs. 384 n1 ping -W 1 -c 100 -f 192.168.99.7 384 n1 ping -W 1 -c 100 -f 192.168.99.7 385 n1 ping -W 1 -c 100 -f abab::1111 385 n1 ping -W 1 -c 100 -f abab::1111 386 386 387 # Have ns2 NAT into wg0 packets from ns0, but 387 # Have ns2 NAT into wg0 packets from ns0, but return an icmp error along the right route. 388 n2 iptables -t nat -A POSTROUTING -s 10.0.0.0/ 388 n2 iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -d 192.168.241.0/24 -j SNAT --to 192.168.241.2 389 n0 iptables -t filter -A INPUT \! -s 10.0.0.0/ 389 n0 iptables -t filter -A INPUT \! -s 10.0.0.0/24 -i vethrs -j DROP # Manual rpfilter just to be explicit. 390 n2 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_f 390 n2 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_forward' 391 ip0 -4 route add 192.168.241.1 via 10.0.0.100 391 ip0 -4 route add 192.168.241.1 via 10.0.0.100 392 n2 wg set wg0 peer "$pub1" remove 392 n2 wg set wg0 peer "$pub1" remove 393 [[ $(! n0 ping -W 1 -c 1 192.168.241.1 || fals 393 [[ $(! n0 ping -W 1 -c 1 192.168.241.1 || false) == *"From 10.0.0.100 icmp_seq=1 Destination Host Unreachable"* ]] 394 394 395 n0 iptables -t nat -F 395 n0 iptables -t nat -F 396 n0 iptables -t filter -F 396 n0 iptables -t filter -F 397 n2 iptables -t nat -F 397 n2 iptables -t nat -F 398 ip0 link del vethrc 398 ip0 link del vethrc 399 ip0 link del vethrs 399 ip0 link del vethrs 400 ip1 link del wg0 400 ip1 link del wg0 401 ip2 link del wg0 401 ip2 link del wg0 402 402 403 # Test that saddr routing is sticky but not to 403 # Test that saddr routing is sticky but not too sticky, changing to this topology: 404 # ┌───────────── 404 # ┌────────────────────────────────────────┐ ┌────────────────────────────────────────┐ 405 # │ $ns1 namespace 405 # │ $ns1 namespace │ │ $ns2 namespace │ 406 # │ 406 # │ │ │ │ 407 # │ ┌─────┐ ┌ 407 # │ ┌─────┐ ┌─────┐ │ │ ┌─────┐ ┌─────┐ │ 408 # │ │ wg0 │───────── 408 # │ │ wg0 │─────────────│veth1│───────────┼────┼──│veth2│────────────│ wg0 │ │ 409 # │ ├─────┴────── 409 # │ ├─────┴──────────┐ ├─────┴──────────┐│ │ ├─────┴──────────┐ ├─────┴──────────┐ │ 410 # │ │192.168.241.1/24│ │10.0.0.1/24 410 # │ │192.168.241.1/24│ │10.0.0.1/24 ││ │ │10.0.0.2/24 │ │192.168.241.2/24│ │ 411 # │ │fd00::1/24 │ │fd00:aa::1/9 411 # │ │fd00::1/24 │ │fd00:aa::1/96 ││ │ │fd00:aa::2/96 │ │fd00::2/24 │ │ 412 # │ └──────────── 412 # │ └────────────────┘ └────────────────┘│ │ └────────────────┘ └────────────────┘ │ 413 # └───────────── 413 # └────────────────────────────────────────┘ └────────────────────────────────────────┘ 414 414 415 ip1 link add dev wg0 type wireguard 415 ip1 link add dev wg0 type wireguard 416 ip2 link add dev wg0 type wireguard 416 ip2 link add dev wg0 type wireguard 417 configure_peers 417 configure_peers 418 ip1 link add veth1 type veth peer name veth2 418 ip1 link add veth1 type veth peer name veth2 419 ip1 link set veth2 netns $netns2 419 ip1 link set veth2 netns $netns2 420 n1 bash -c 'printf 0 > /proc/sys/net/ipv6/conf 420 n1 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/all/accept_dad' 421 n2 bash -c 'printf 0 > /proc/sys/net/ipv6/conf 421 n2 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/all/accept_dad' 422 n1 bash -c 'printf 0 > /proc/sys/net/ipv6/conf 422 n1 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/veth1/accept_dad' 423 n2 bash -c 'printf 0 > /proc/sys/net/ipv6/conf 423 n2 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/veth2/accept_dad' 424 n1 bash -c 'printf 1 > /proc/sys/net/ipv4/conf 424 n1 bash -c 'printf 1 > /proc/sys/net/ipv4/conf/veth1/promote_secondaries' 425 425 426 # First we check that we aren't overly sticky 426 # First we check that we aren't overly sticky and can fall over to new IPs when old ones are removed 427 ip1 addr add 10.0.0.1/24 dev veth1 427 ip1 addr add 10.0.0.1/24 dev veth1 428 ip1 addr add fd00:aa::1/96 dev veth1 428 ip1 addr add fd00:aa::1/96 dev veth1 429 ip2 addr add 10.0.0.2/24 dev veth2 429 ip2 addr add 10.0.0.2/24 dev veth2 430 ip2 addr add fd00:aa::2/96 dev veth2 430 ip2 addr add fd00:aa::2/96 dev veth2 431 ip1 link set veth1 up 431 ip1 link set veth1 up 432 ip2 link set veth2 up 432 ip2 link set veth2 up 433 waitiface $netns1 veth1 433 waitiface $netns1 veth1 434 waitiface $netns2 veth2 434 waitiface $netns2 veth2 435 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.2:2 435 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.2:2 436 n1 ping -W 1 -c 1 192.168.241.2 436 n1 ping -W 1 -c 1 192.168.241.2 437 ip1 addr add 10.0.0.10/24 dev veth1 437 ip1 addr add 10.0.0.10/24 dev veth1 438 ip1 addr del 10.0.0.1/24 dev veth1 438 ip1 addr del 10.0.0.1/24 dev veth1 439 n1 ping -W 1 -c 1 192.168.241.2 439 n1 ping -W 1 -c 1 192.168.241.2 440 n1 wg set wg0 peer "$pub2" endpoint [fd00:aa:: 440 n1 wg set wg0 peer "$pub2" endpoint [fd00:aa::2]:2 441 n1 ping -W 1 -c 1 192.168.241.2 441 n1 ping -W 1 -c 1 192.168.241.2 442 ip1 addr add fd00:aa::10/96 dev veth1 442 ip1 addr add fd00:aa::10/96 dev veth1 443 ip1 addr del fd00:aa::1/96 dev veth1 443 ip1 addr del fd00:aa::1/96 dev veth1 444 n1 ping -W 1 -c 1 192.168.241.2 444 n1 ping -W 1 -c 1 192.168.241.2 445 445 446 # Now we show that we can successfully do repl 446 # Now we show that we can successfully do reply to sender routing 447 ip1 link set veth1 down 447 ip1 link set veth1 down 448 ip2 link set veth2 down 448 ip2 link set veth2 down 449 ip1 addr flush dev veth1 449 ip1 addr flush dev veth1 450 ip2 addr flush dev veth2 450 ip2 addr flush dev veth2 451 ip1 addr add 10.0.0.1/24 dev veth1 451 ip1 addr add 10.0.0.1/24 dev veth1 452 ip1 addr add 10.0.0.2/24 dev veth1 452 ip1 addr add 10.0.0.2/24 dev veth1 453 ip1 addr add fd00:aa::1/96 dev veth1 453 ip1 addr add fd00:aa::1/96 dev veth1 454 ip1 addr add fd00:aa::2/96 dev veth1 454 ip1 addr add fd00:aa::2/96 dev veth1 455 ip2 addr add 10.0.0.3/24 dev veth2 455 ip2 addr add 10.0.0.3/24 dev veth2 456 ip2 addr add fd00:aa::3/96 dev veth2 456 ip2 addr add fd00:aa::3/96 dev veth2 457 ip1 link set veth1 up 457 ip1 link set veth1 up 458 ip2 link set veth2 up 458 ip2 link set veth2 up 459 waitiface $netns1 veth1 459 waitiface $netns1 veth1 460 waitiface $netns2 veth2 460 waitiface $netns2 veth2 461 n2 wg set wg0 peer "$pub1" endpoint 10.0.0.1:1 461 n2 wg set wg0 peer "$pub1" endpoint 10.0.0.1:1 462 n2 ping -W 1 -c 1 192.168.241.1 462 n2 ping -W 1 -c 1 192.168.241.1 463 [[ $(n2 wg show wg0 endpoints) == "$pub1 463 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.1:1" ]] 464 n2 wg set wg0 peer "$pub1" endpoint [fd00:aa:: 464 n2 wg set wg0 peer "$pub1" endpoint [fd00:aa::1]:1 465 n2 ping -W 1 -c 1 192.168.241.1 465 n2 ping -W 1 -c 1 192.168.241.1 466 [[ $(n2 wg show wg0 endpoints) == "$pub1 466 [[ $(n2 wg show wg0 endpoints) == "$pub1 [fd00:aa::1]:1" ]] 467 n2 wg set wg0 peer "$pub1" endpoint 10.0.0.2:1 467 n2 wg set wg0 peer "$pub1" endpoint 10.0.0.2:1 468 n2 ping -W 1 -c 1 192.168.241.1 468 n2 ping -W 1 -c 1 192.168.241.1 469 [[ $(n2 wg show wg0 endpoints) == "$pub1 469 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.2:1" ]] 470 n2 wg set wg0 peer "$pub1" endpoint [fd00:aa:: 470 n2 wg set wg0 peer "$pub1" endpoint [fd00:aa::2]:1 471 n2 ping -W 1 -c 1 192.168.241.1 471 n2 ping -W 1 -c 1 192.168.241.1 472 [[ $(n2 wg show wg0 endpoints) == "$pub1 472 [[ $(n2 wg show wg0 endpoints) == "$pub1 [fd00:aa::2]:1" ]] 473 473 474 # What happens if the inbound destination addr 474 # What happens if the inbound destination address belongs to a different interface as the default route? 475 ip1 link add dummy0 type dummy 475 ip1 link add dummy0 type dummy 476 ip1 addr add 10.50.0.1/24 dev dummy0 476 ip1 addr add 10.50.0.1/24 dev dummy0 477 ip1 link set dummy0 up 477 ip1 link set dummy0 up 478 ip2 route add 10.50.0.0/24 dev veth2 478 ip2 route add 10.50.0.0/24 dev veth2 479 n2 wg set wg0 peer "$pub1" endpoint 10.50.0.1: 479 n2 wg set wg0 peer "$pub1" endpoint 10.50.0.1:1 480 n2 ping -W 1 -c 1 192.168.241.1 480 n2 ping -W 1 -c 1 192.168.241.1 481 [[ $(n2 wg show wg0 endpoints) == "$pub1 481 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.50.0.1:1" ]] 482 482 483 ip1 link del dummy0 483 ip1 link del dummy0 484 ip1 addr flush dev veth1 484 ip1 addr flush dev veth1 485 ip2 addr flush dev veth2 485 ip2 addr flush dev veth2 486 ip1 route flush dev veth1 486 ip1 route flush dev veth1 487 ip2 route flush dev veth2 487 ip2 route flush dev veth2 488 488 489 # Now we see what happens if another interface 489 # Now we see what happens if another interface route takes precedence over an ongoing one 490 ip1 link add veth3 type veth peer name veth4 490 ip1 link add veth3 type veth peer name veth4 491 ip1 link set veth4 netns $netns2 491 ip1 link set veth4 netns $netns2 492 ip1 addr add 10.0.0.1/24 dev veth1 492 ip1 addr add 10.0.0.1/24 dev veth1 493 ip2 addr add 10.0.0.2/24 dev veth2 493 ip2 addr add 10.0.0.2/24 dev veth2 494 ip1 addr add 10.0.0.3/24 dev veth3 494 ip1 addr add 10.0.0.3/24 dev veth3 495 ip1 link set veth1 up 495 ip1 link set veth1 up 496 ip2 link set veth2 up 496 ip2 link set veth2 up 497 ip1 link set veth3 up 497 ip1 link set veth3 up 498 ip2 link set veth4 up 498 ip2 link set veth4 up 499 waitiface $netns1 veth1 499 waitiface $netns1 veth1 500 waitiface $netns2 veth2 500 waitiface $netns2 veth2 501 waitiface $netns1 veth3 501 waitiface $netns1 veth3 502 waitiface $netns2 veth4 502 waitiface $netns2 veth4 503 ip1 route flush dev veth1 503 ip1 route flush dev veth1 504 ip1 route flush dev veth3 504 ip1 route flush dev veth3 505 ip1 route add 10.0.0.0/24 dev veth1 src 10.0.0 505 ip1 route add 10.0.0.0/24 dev veth1 src 10.0.0.1 metric 2 506 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.2:2 506 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.2:2 507 n1 ping -W 1 -c 1 192.168.241.2 507 n1 ping -W 1 -c 1 192.168.241.2 508 [[ $(n2 wg show wg0 endpoints) == "$pub1 508 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.1:1" ]] 509 ip1 route add 10.0.0.0/24 dev veth3 src 10.0.0 509 ip1 route add 10.0.0.0/24 dev veth3 src 10.0.0.3 metric 1 510 n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf 510 n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/veth1/rp_filter' 511 n2 bash -c 'printf 0 > /proc/sys/net/ipv4/conf 511 n2 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/veth4/rp_filter' 512 n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf 512 n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/all/rp_filter' 513 n2 bash -c 'printf 0 > /proc/sys/net/ipv4/conf 513 n2 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/all/rp_filter' 514 n1 ping -W 1 -c 1 192.168.241.2 514 n1 ping -W 1 -c 1 192.168.241.2 515 [[ $(n2 wg show wg0 endpoints) == "$pub1 515 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.3:1" ]] 516 516 517 ip1 link del dev veth3 517 ip1 link del dev veth3 518 ip1 link del dev wg0 518 ip1 link del dev wg0 519 ip2 link del dev wg0 519 ip2 link del dev wg0 520 520 521 # Make sure persistent keep alives are sent wh 521 # Make sure persistent keep alives are sent when an adapter comes up 522 ip1 link add dev wg0 type wireguard 522 ip1 link add dev wg0 type wireguard 523 n1 wg set wg0 private-key <(echo "$key1") peer 523 n1 wg set wg0 private-key <(echo "$key1") peer "$pub2" endpoint 10.0.0.1:1 persistent-keepalive 1 524 read _ _ tx_bytes < <(n1 wg show wg0 transfer) 524 read _ _ tx_bytes < <(n1 wg show wg0 transfer) 525 [[ $tx_bytes -eq 0 ]] 525 [[ $tx_bytes -eq 0 ]] 526 ip1 link set dev wg0 up 526 ip1 link set dev wg0 up 527 read _ _ tx_bytes < <(n1 wg show wg0 transfer) 527 read _ _ tx_bytes < <(n1 wg show wg0 transfer) 528 [[ $tx_bytes -gt 0 ]] 528 [[ $tx_bytes -gt 0 ]] 529 ip1 link del dev wg0 529 ip1 link del dev wg0 530 # This should also happen even if the private 530 # This should also happen even if the private key is set later 531 ip1 link add dev wg0 type wireguard 531 ip1 link add dev wg0 type wireguard 532 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.1:1 532 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.1:1 persistent-keepalive 1 533 read _ _ tx_bytes < <(n1 wg show wg0 transfer) 533 read _ _ tx_bytes < <(n1 wg show wg0 transfer) 534 [[ $tx_bytes -eq 0 ]] 534 [[ $tx_bytes -eq 0 ]] 535 ip1 link set dev wg0 up 535 ip1 link set dev wg0 up 536 read _ _ tx_bytes < <(n1 wg show wg0 transfer) 536 read _ _ tx_bytes < <(n1 wg show wg0 transfer) 537 [[ $tx_bytes -eq 0 ]] 537 [[ $tx_bytes -eq 0 ]] 538 n1 wg set wg0 private-key <(echo "$key1") 538 n1 wg set wg0 private-key <(echo "$key1") 539 read _ _ tx_bytes < <(n1 wg show wg0 transfer) 539 read _ _ tx_bytes < <(n1 wg show wg0 transfer) 540 [[ $tx_bytes -gt 0 ]] 540 [[ $tx_bytes -gt 0 ]] 541 ip1 link del dev veth1 541 ip1 link del dev veth1 542 ip1 link del dev wg0 542 ip1 link del dev wg0 543 543 544 # We test that Netlink/IPC is working properly 544 # We test that Netlink/IPC is working properly by doing things that usually cause split responses 545 ip0 link add dev wg0 type wireguard 545 ip0 link add dev wg0 type wireguard 546 config=( "[Interface]" "PrivateKey=$(wg genkey 546 config=( "[Interface]" "PrivateKey=$(wg genkey)" "[Peer]" "PublicKey=$(wg genkey)" ) 547 for a in {1..255}; do 547 for a in {1..255}; do 548 for b in {0..255}; do 548 for b in {0..255}; do 549 config+=( "AllowedIPs=$a.$b.0. 549 config+=( "AllowedIPs=$a.$b.0.0/16,$a::$b/128" ) 550 done 550 done 551 done 551 done 552 n0 wg setconf wg0 <(printf '%s\n' "${config[@] 552 n0 wg setconf wg0 <(printf '%s\n' "${config[@]}") 553 i=0 553 i=0 554 for ip in $(n0 wg show wg0 allowed-ips); do 554 for ip in $(n0 wg show wg0 allowed-ips); do 555 ((++i)) 555 ((++i)) 556 done 556 done 557 ((i == 255*256*2+1)) 557 ((i == 255*256*2+1)) 558 ip0 link del wg0 558 ip0 link del wg0 559 ip0 link add dev wg0 type wireguard 559 ip0 link add dev wg0 type wireguard 560 config=( "[Interface]" "PrivateKey=$(wg genkey 560 config=( "[Interface]" "PrivateKey=$(wg genkey)" ) 561 for a in {1..40}; do 561 for a in {1..40}; do 562 config+=( "[Peer]" "PublicKey=$(wg gen 562 config+=( "[Peer]" "PublicKey=$(wg genkey)" ) 563 for b in {1..52}; do 563 for b in {1..52}; do 564 config+=( "AllowedIPs=$a.$b.0. 564 config+=( "AllowedIPs=$a.$b.0.0/16" ) 565 done 565 done 566 done 566 done 567 n0 wg setconf wg0 <(printf '%s\n' "${config[@] 567 n0 wg setconf wg0 <(printf '%s\n' "${config[@]}") 568 i=0 568 i=0 569 while read -r line; do 569 while read -r line; do 570 j=0 570 j=0 571 for ip in $line; do 571 for ip in $line; do 572 ((++j)) 572 ((++j)) 573 done 573 done 574 ((j == 53)) 574 ((j == 53)) 575 ((++i)) 575 ((++i)) 576 done < <(n0 wg show wg0 allowed-ips) 576 done < <(n0 wg show wg0 allowed-ips) 577 ((i == 40)) 577 ((i == 40)) 578 ip0 link del wg0 578 ip0 link del wg0 579 ip0 link add wg0 type wireguard 579 ip0 link add wg0 type wireguard 580 config=( ) 580 config=( ) 581 for i in {1..29}; do 581 for i in {1..29}; do 582 config+=( "[Peer]" "PublicKey=$(wg gen 582 config+=( "[Peer]" "PublicKey=$(wg genkey)" ) 583 done 583 done 584 config+=( "[Peer]" "PublicKey=$(wg genkey)" "A 584 config+=( "[Peer]" "PublicKey=$(wg genkey)" "AllowedIPs=255.2.3.4/32,abcd::255/128" ) 585 n0 wg setconf wg0 <(printf '%s\n' "${config[@] 585 n0 wg setconf wg0 <(printf '%s\n' "${config[@]}") 586 n0 wg showconf wg0 > /dev/null 586 n0 wg showconf wg0 > /dev/null 587 ip0 link del wg0 587 ip0 link del wg0 588 588 589 allowedips=( ) 589 allowedips=( ) 590 for i in {1..197}; do 590 for i in {1..197}; do 591 allowedips+=( abcd::$i ) 591 allowedips+=( abcd::$i ) 592 done 592 done 593 saved_ifs="$IFS" 593 saved_ifs="$IFS" 594 IFS=, 594 IFS=, 595 allowedips="${allowedips[*]}" 595 allowedips="${allowedips[*]}" 596 IFS="$saved_ifs" 596 IFS="$saved_ifs" 597 ip0 link add wg0 type wireguard 597 ip0 link add wg0 type wireguard 598 n0 wg set wg0 peer "$pub1" 598 n0 wg set wg0 peer "$pub1" 599 n0 wg set wg0 peer "$pub2" allowed-ips "$allow 599 n0 wg set wg0 peer "$pub2" allowed-ips "$allowedips" 600 { 600 { 601 read -r pub allowedips 601 read -r pub allowedips 602 [[ $pub == "$pub1" && $allowedips == " 602 [[ $pub == "$pub1" && $allowedips == "(none)" ]] 603 read -r pub allowedips 603 read -r pub allowedips 604 [[ $pub == "$pub2" ]] 604 [[ $pub == "$pub2" ]] 605 i=0 605 i=0 606 for _ in $allowedips; do 606 for _ in $allowedips; do 607 ((++i)) 607 ((++i)) 608 done 608 done 609 ((i == 197)) 609 ((i == 197)) 610 } < <(n0 wg show wg0 allowed-ips) 610 } < <(n0 wg show wg0 allowed-ips) 611 ip0 link del wg0 611 ip0 link del wg0 612 612 613 ! n0 wg show doesnotexist || false 613 ! n0 wg show doesnotexist || false 614 614 615 ip0 link add wg0 type wireguard 615 ip0 link add wg0 type wireguard 616 n0 wg set wg0 private-key <(echo "$key1") peer 616 n0 wg set wg0 private-key <(echo "$key1") peer "$pub2" preshared-key <(echo "$psk") 617 [[ $(n0 wg show wg0 private-key) == "$key1" ]] 617 [[ $(n0 wg show wg0 private-key) == "$key1" ]] 618 [[ $(n0 wg show wg0 preshared-keys) == "$pub2 618 [[ $(n0 wg show wg0 preshared-keys) == "$pub2 $psk" ]] 619 n0 wg set wg0 private-key /dev/null peer "$pub 619 n0 wg set wg0 private-key /dev/null peer "$pub2" preshared-key /dev/null 620 [[ $(n0 wg show wg0 private-key) == "(none)" ] 620 [[ $(n0 wg show wg0 private-key) == "(none)" ]] 621 [[ $(n0 wg show wg0 preshared-keys) == "$pub2 621 [[ $(n0 wg show wg0 preshared-keys) == "$pub2 (none)" ]] 622 n0 wg set wg0 peer "$pub2" 622 n0 wg set wg0 peer "$pub2" 623 n0 wg set wg0 private-key <(echo "$key2") 623 n0 wg set wg0 private-key <(echo "$key2") 624 [[ $(n0 wg show wg0 public-key) == "$pub2" ]] 624 [[ $(n0 wg show wg0 public-key) == "$pub2" ]] 625 [[ -z $(n0 wg show wg0 peers) ]] 625 [[ -z $(n0 wg show wg0 peers) ]] 626 n0 wg set wg0 peer "$pub2" 626 n0 wg set wg0 peer "$pub2" 627 [[ -z $(n0 wg show wg0 peers) ]] 627 [[ -z $(n0 wg show wg0 peers) ]] 628 n0 wg set wg0 private-key <(echo "$key1") 628 n0 wg set wg0 private-key <(echo "$key1") 629 n0 wg set wg0 peer "$pub2" 629 n0 wg set wg0 peer "$pub2" 630 [[ $(n0 wg show wg0 peers) == "$pub2" ]] 630 [[ $(n0 wg show wg0 peers) == "$pub2" ]] 631 n0 wg set wg0 private-key <(echo "/${key1:1}") 631 n0 wg set wg0 private-key <(echo "/${key1:1}") 632 [[ $(n0 wg show wg0 private-key) == "+${key1:1 632 [[ $(n0 wg show wg0 private-key) == "+${key1:1}" ]] 633 n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0 633 n0 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 634 n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0 634 n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0 635 n0 wg set wg0 peer "$pub2" allowed-ips ::/0,17 635 n0 wg set wg0 peer "$pub2" allowed-ips ::/0,1700::/111,5000::/4,e000::/37,9000::/75 636 n0 wg set wg0 peer "$pub2" allowed-ips ::/0 636 n0 wg set wg0 peer "$pub2" allowed-ips ::/0 637 n0 wg set wg0 peer "$pub2" remove 637 n0 wg set wg0 peer "$pub2" remove 638 for low_order_point in AAAAAAAAAAAAAAAAAAAAAAA 638 for low_order_point in AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 4Ot6fDtBuK4WVuP68Z/EatoJjeucMrH9hmIFFl9JuAA= X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEVc= 7P///////////////////////////////////////38= 7f///////////////////////////////////////38= 7v///////////////////////////////////////38=; do 639 n0 wg set wg0 peer "$low_order_point" 639 n0 wg set wg0 peer "$low_order_point" persistent-keepalive 1 endpoint 127.0.0.1:1111 640 done 640 done 641 [[ -n $(n0 wg show wg0 peers) ]] 641 [[ -n $(n0 wg show wg0 peers) ]] 642 exec 4< <(n0 ncat -l -u -p 1111) 642 exec 4< <(n0 ncat -l -u -p 1111) 643 ncat_pid=$! 643 ncat_pid=$! 644 waitncatudp $netns0 $ncat_pid 644 waitncatudp $netns0 $ncat_pid 645 ip0 link set wg0 up 645 ip0 link set wg0 up 646 ! read -r -n 1 -t 2 <&4 || false 646 ! read -r -n 1 -t 2 <&4 || false 647 kill $ncat_pid 647 kill $ncat_pid 648 ip0 link del wg0 648 ip0 link del wg0 649 649 650 # Ensure that dst_cache references don't outli 650 # Ensure that dst_cache references don't outlive netns lifetime 651 ip1 link add dev wg0 type wireguard 651 ip1 link add dev wg0 type wireguard 652 ip2 link add dev wg0 type wireguard 652 ip2 link add dev wg0 type wireguard 653 configure_peers 653 configure_peers 654 ip1 link add veth1 type veth peer name veth2 654 ip1 link add veth1 type veth peer name veth2 655 ip1 link set veth2 netns $netns2 655 ip1 link set veth2 netns $netns2 656 ip1 addr add fd00:aa::1/64 dev veth1 656 ip1 addr add fd00:aa::1/64 dev veth1 657 ip2 addr add fd00:aa::2/64 dev veth2 657 ip2 addr add fd00:aa::2/64 dev veth2 658 ip1 link set veth1 up 658 ip1 link set veth1 up 659 ip2 link set veth2 up 659 ip2 link set veth2 up 660 waitiface $netns1 veth1 660 waitiface $netns1 veth1 661 waitiface $netns2 veth2 661 waitiface $netns2 veth2 662 ip1 -6 route add default dev veth1 via fd00:aa 662 ip1 -6 route add default dev veth1 via fd00:aa::2 663 ip2 -6 route add default dev veth2 via fd00:aa 663 ip2 -6 route add default dev veth2 via fd00:aa::1 664 n1 wg set wg0 peer "$pub2" endpoint [fd00:aa:: 664 n1 wg set wg0 peer "$pub2" endpoint [fd00:aa::2]:2 665 n2 wg set wg0 peer "$pub1" endpoint [fd00:aa:: 665 n2 wg set wg0 peer "$pub1" endpoint [fd00:aa::1]:1 666 n1 ping6 -c 1 fd00::2 666 n1 ping6 -c 1 fd00::2 667 pp ip netns delete $netns1 667 pp ip netns delete $netns1 668 pp ip netns delete $netns2 668 pp ip netns delete $netns2 669 pp ip netns add $netns1 669 pp ip netns add $netns1 670 pp ip netns add $netns2 670 pp ip netns add $netns2 671 671 672 # Ensure there aren't circular reference loops 672 # Ensure there aren't circular reference loops 673 ip1 link add wg1 type wireguard 673 ip1 link add wg1 type wireguard 674 ip2 link add wg2 type wireguard 674 ip2 link add wg2 type wireguard 675 ip1 link set wg1 netns $netns2 675 ip1 link set wg1 netns $netns2 676 ip2 link set wg2 netns $netns1 676 ip2 link set wg2 netns $netns1 677 pp ip netns delete $netns1 677 pp ip netns delete $netns1 678 pp ip netns delete $netns2 678 pp ip netns delete $netns2 679 pp ip netns add $netns1 679 pp ip netns add $netns1 680 pp ip netns add $netns2 680 pp ip netns add $netns2 681 681 682 sleep 2 # Wait for cleanup and grace periods 682 sleep 2 # Wait for cleanup and grace periods 683 declare -A objects 683 declare -A objects 684 while read -t 0.1 -r line 2>/dev/null || [[ $? 684 while read -t 0.1 -r line 2>/dev/null || [[ $? -ne 142 ]]; do 685 [[ $line =~ .*(wg[0-9]+:\ [A-Z][a-z]+\ 685 [[ $line =~ .*(wg[0-9]+:\ [A-Z][a-z]+\ ?[0-9]*)\ .*(created|destroyed).* ]] || continue 686 objects["${BASH_REMATCH[1]}"]+="${BASH 686 objects["${BASH_REMATCH[1]}"]+="${BASH_REMATCH[2]}" 687 done < /dev/kmsg 687 done < /dev/kmsg 688 alldeleted=1 688 alldeleted=1 689 for object in "${!objects[@]}"; do 689 for object in "${!objects[@]}"; do 690 if [[ ${objects["$object"]} != *create 690 if [[ ${objects["$object"]} != *createddestroyed && ${objects["$object"]} != *createdcreateddestroyeddestroyed ]]; then 691 echo "Error: $object: merely $ 691 echo "Error: $object: merely ${objects["$object"]}" >&3 692 alldeleted=0 692 alldeleted=0 693 fi 693 fi 694 done 694 done 695 [[ $alldeleted -eq 1 ]] 695 [[ $alldeleted -eq 1 ]] 696 pretty "" "Objects that were created were also 696 pretty "" "Objects that were created were also destroyed."
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.