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