2 # SPDX-License-Identifier: GPL-2.0
4 # Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
6 # This script tests the below topology:
8 # ┌─────────────────────┐ ┌──────────────────────────────────┐ ┌─────────────────────┐
9 # │ $ns1 namespace │ │ $ns0 namespace │ │ $ns2 namespace │
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 # └──────────────────────────────────┘
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.
28 export WG_HIDE_KEYS
=never
32 pretty
() { echo -e "\x1b[32m\x1b[1m[+] ${1:+NS$1: }${2}\x1b[0m" >&3; }
33 pp() { pretty "" "$
*"; "$@
"; }
34 maybe_exec() { if [[ $BASHPID -eq $$ ]]; then "$@
"; else exec "$@
"; fi; }
35 n0() { pretty 0 "$
*"; maybe_exec ip netns exec $netns0 "$@
"; }
36 n1() { pretty 1 "$
*"; maybe_exec ip netns exec $netns1 "$@
"; }
37 n2() { pretty 2 "$
*"; maybe_exec ip netns exec $netns2 "$@
"; }
38 ip0() { pretty 0 "ip $
*"; ip -n $netns0 "$@
"; }
39 ip1() { pretty 1 "ip $
*"; ip -n $netns1 "$@
"; }
40 ip2() { pretty 2 "ip $
*"; ip -n $netns2 "$@
"; }
41 sleep() { read -t "$1" -N 1 || true; }
42 waitiperf() { pretty "${1//*-}" "wait for iperf
:5201 pid
$2"; while [[ $(ss -N "$1" -tlpH 'sport = 5201') != *\"iperf3\",pid=$2,fd=* ]]; do sleep 0.1; done; }
43 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; }
44 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;"; }
49 printf "$orig_message_cost" > /proc/sys/net/core/message_cost
56 local to_kill="$
(ip netns pids
$netns0) $
(ip netns pids
$netns1) $
(ip netns pids
$netns2)"
57 [[ -n $to_kill ]] && kill $to_kill
58 pp ip netns del $netns1
59 pp ip netns del $netns2
60 pp ip netns del $netns0
64 orig_message_cost="$
(< /proc
/sys
/net
/core
/message_cost
)"
66 printf 0 > /proc/sys/net/core/message_cost
68 ip netns del $netns0 2>/dev/null || true
69 ip netns del $netns1 2>/dev/null || true
70 ip netns del $netns2 2>/dev/null || true
71 pp ip netns add $netns0
72 pp ip netns add $netns1
73 pp ip netns add $netns2
74 ip0 link set up dev lo
76 ip0 link add dev wg0 type wireguard
77 ip0 link set wg0 netns $netns1
78 ip0 link add dev wg0 type wireguard
79 ip0 link set wg0 netns $netns2
80 key1="$
(pp wg genkey
)"
81 key2="$
(pp wg genkey
)"
82 key3="$
(pp wg genkey
)"
83 key4="$
(pp wg genkey
)"
84 pub1="$
(pp wg pubkey
<<<"$key1")"
85 pub2="$
(pp wg pubkey
<<<"$key2")"
86 pub3="$
(pp wg pubkey
<<<"$key3")"
87 pub4="$
(pp wg pubkey
<<<"$key4")"
89 [[ -n $key1 && -n $key2 && -n $psk ]]
92 ip1 addr add 192.168.241.1/24 dev wg0
93 ip1 addr add fd00::1/112 dev wg0
95 ip2 addr add 192.168.241.2/24 dev wg0
96 ip2 addr add fd00::2/112 dev wg0
99 private-key <(echo "$key1") \
102 preshared-key <(echo "$psk") \
103 allowed-ips 192.168.241.2/32,fd00::2/128
105 private-key <(echo "$key2") \
108 preshared-key <(echo "$psk") \
109 allowed-ips 192.168.241.1/32,fd00::1/128
111 ip1 link set up dev wg0
112 ip2 link set up dev wg0
118 n2 ping -c 10 -f -W 1 192.168.241.1
119 n1 ping -c 10 -f -W 1 192.168.241.2
122 n2 ping6 -c 10 -f -W 1 fd00::1
123 n1 ping6 -c 10 -f -W 1 fd00::2
126 n2 iperf3 -s -1 -B 192.168.241.2 &
128 n1 iperf3 -Z -t 3 -c 192.168.241.2
131 n1 iperf3 -s -1 -B fd00::1 &
133 n2 iperf3 -Z -t 3 -c fd00::1
136 n1 iperf3 -s -1 -B 192.168.241.1 &
138 n2 iperf3 -Z -t 3 -b 0 -u -c 192.168.241.1
141 n2 iperf3 -s -1 -B fd00::2 &
143 n1 iperf3 -Z -t 3 -b 0 -u -c fd00::2
146 [[ $(ip1 link show dev wg0) =~ mtu\ ([0-9]+) ]] && orig_mtu="${BASH_REMATCH[1]}"
147 big_mtu=$(( 34816 - 1500 + $orig_mtu ))
149 # Test using IPv4 as outer transport
150 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2
151 n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1:1
152 # Before calling tests, we first make sure that the stats counters and timestamper are working
153 n2 ping -c 10 -f -W 1 192.168.241.1
154 { read _; read _; read _; read rx_bytes _; read _; read tx_bytes _; } < <(ip2 -stats link show dev wg0)
155 (( rx_bytes == 1372 && (tx_bytes == 1428 || tx_bytes == 1460) ))
156 { read _; read _; read _; read rx_bytes _; read _; read tx_bytes _; } < <(ip1 -stats link show dev wg0)
157 (( tx_bytes == 1372 && (rx_bytes == 1428 || rx_bytes == 1460) ))
158 read _ rx_bytes tx_bytes < <(n2 wg show wg0 transfer)
159 (( rx_bytes == 1372 && (tx_bytes == 1428 || tx_bytes == 1460) ))
160 read _ rx_bytes tx_bytes < <(n1 wg show wg0 transfer)
161 (( tx_bytes == 1372 && (rx_bytes == 1428 || rx_bytes == 1460) ))
162 read _ timestamp < <(n1 wg show wg0 latest-handshakes)
166 ip1 link set wg0 mtu $big_mtu
167 ip2 link set wg0 mtu $big_mtu
170 ip1 link set wg0 mtu $orig_mtu
171 ip2 link set wg0 mtu $orig_mtu
173 # Test using IPv6 as outer transport
174 n1 wg set wg0 peer "$pub2" endpoint [::1]:2
175 n2 wg set wg0 peer "$pub1" endpoint [::1]:1
177 ip1 link set wg0 mtu $big_mtu
178 ip2 link set wg0 mtu $big_mtu
181 # Test that route MTUs work with the padding
182 ip1 link set wg0 mtu 1300
183 ip2 link set wg0 mtu 1300
184 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2
185 n2 wg set wg0 peer "$pub1" endpoint 127.0.0.1:1
186 n0 iptables -A INPUT -m length --length 1360 -j DROP
187 n1 ip route add 192.168.241.2/32 dev wg0 mtu 1299
188 n2 ip route add 192.168.241.1/32 dev wg0 mtu 1299
189 n2 ping -c 1 -W 1 -s 1269 192.168.241.1
190 n2 ip route delete 192.168.241.1/32 dev wg0 mtu 1299
191 n1 ip route delete 192.168.241.2/32 dev wg0 mtu 1299
194 ip1 link set wg0 mtu $orig_mtu
195 ip2 link set wg0 mtu $orig_mtu
197 # Test using IPv4 that roaming works
198 ip0 -4 addr del 127.0.0.1/8 dev lo
199 ip0 -4 addr add 127.212.121.99/8 dev lo
200 n1 wg set wg0 listen-port 9999
201 n1 wg set wg0 peer "$pub2" endpoint 127.0.0.1:2
202 n1 ping6 -W 1 -c 1 fd00::2
203 [[ $(n2 wg show wg0 endpoints) == "$pub1 127.212.121.99:9999" ]]
205 # Test using IPv6 that roaming works
206 n1 wg set wg0 listen-port 9998
207 n1 wg set wg0 peer "$pub2" endpoint [::1]:2
208 n1 ping -W 1 -c 1 192.168.241.2
209 [[ $(n2 wg show wg0 endpoints) == "$pub1 [::1]:9998" ]]
211 # Test that crypto-RP filter works
212 n1 wg set wg0 peer "$pub2" allowed-ips 192.168.241.0/24
213 exec 4< <(n1 ncat -l -u -p 1111)
215 waitncatudp $netns1 $ncat_pid
216 n2 ncat -u 192.168.241.1 1111 <<<"X"
217 read -r -N 1 -t 1 out <&4 && [[ $out == "X
" ]]
219 more_specific_key="$
(pp wg genkey | pp wg pubkey
)"
220 n1 wg set wg0 peer "$more_specific_key" allowed-ips 192.168.241.2/32
221 n2 wg set wg0 listen-port 9997
222 exec 4< <(n1 ncat -l -u -p 1111)
224 waitncatudp $netns1 $ncat_pid
225 n2 ncat -u 192.168.241.1 1111 <<<"X"
226 ! read -r -N 1 -t 1 out <&4 || false
228 n1 wg set wg0 peer "$more_specific_key" remove
229 [[ $(n1 wg show wg0 endpoints) == "$pub2 [::1]:9997" ]]
231 # Test that we can change private keys keys and immediately handshake
232 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
233 n2 wg set wg0 private-key <(echo "$key2") listen-port 2 peer "$pub1" preshared-key <(echo "$psk") allowed-ips 192.168.241.1/32
234 n1 ping -W 1 -c 1 192.168.241.2
235 n1 wg set wg0 private-key <(echo "$key3")
236 n2 wg set wg0 peer "$pub3" preshared-key <(echo "$psk") allowed-ips 192.168.241.1/32 peer "$pub1" remove
237 n1 ping -W 1 -c 1 192.168.241.2
238 n2 wg set wg0 peer "$pub3" remove
240 # Test that we can route wg through wg
241 ip1 addr flush dev wg0
242 ip2 addr flush dev wg0
243 ip1 addr add fd00::5:1/112 dev wg0
244 ip2 addr add fd00::5:2/112 dev wg0
245 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
246 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
247 ip1 link add wg1 type wireguard
248 ip2 link add wg1 type wireguard
249 ip1 addr add 192.168.241.1/24 dev wg1
250 ip1 addr add fd00::1/112 dev wg1
251 ip2 addr add 192.168.241.2/24 dev wg1
252 ip2 addr add fd00::2/112 dev wg1
253 ip1 link set mtu 1340 up dev wg1
254 ip2 link set mtu 1340 up dev wg1
255 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
256 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
258 # Try to set up a routing loop between the two namespaces
259 ip1 link set netns $netns0 dev wg1
260 ip0 addr add 192.168.241.1/24 dev wg1
261 ip0 link set up dev wg1
262 n0 ping -W 1 -c 1 192.168.241.2
263 n1 wg set wg0 peer "$pub2" endpoint 192.168.241.2:7
266 ! n0 ping -W 1 -c 10 -f 192.168.241.2 || false # Should not crash kernel
271 # Test using NAT. We now change the topology to this:
272 # ┌────────────────────────────────────────┐ ┌────────────────────────────────────────────────┐ ┌────────────────────────────────────────┐
273 # │ $ns1 namespace │ │ $ns0 namespace │ │ $ns2 namespace │
275 # │ ┌─────┐ ┌─────┐ │ │ ┌──────┐ ┌──────┐ │ │ ┌─────┐ ┌─────┐ │
276 # │ │ wg0 │─────────────│vethc│───────────┼────┼────│vethrc│ │vethrs│──────────────┼─────┼──│veths│────────────│ wg0 │ │
277 # │ ├─────┴──────────┐ ├─────┴──────────┐│ │ ├──────┴─────────┐ ├──────┴────────────┐ │ │ ├─────┴──────────┐ ├─────┴──────────┐ │
278 # │ │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│ │
279 # │ │fd00::1/24 │ │ ││ │ │ │ │SNAT:192.168.1.0/24│ │ │ │ │ │fd00::2/24 │ │
280 # │ └────────────────┘ └────────────────┘│ │ └────────────────┘ └───────────────────┘ │ │ └────────────────┘ └────────────────┘ │
281 # └────────────────────────────────────────┘ └────────────────────────────────────────────────┘ └────────────────────────────────────────┘
283 ip1 link add dev wg0 type wireguard
284 ip2 link add dev wg0 type wireguard
287 ip0 link add vethrc type veth peer name vethc
288 ip0 link add vethrs type veth peer name veths
289 ip0 link set vethc netns $netns1
290 ip0 link set veths netns $netns2
291 ip0 link set vethrc up
292 ip0 link set vethrs up
293 ip0 addr add 192.168.1.1/24 dev vethrc
294 ip0 addr add 10.0.0.1/24 dev vethrs
295 ip1 addr add 192.168.1.100/24 dev vethc
296 ip1 link set vethc up
297 ip1 route add default via 192.168.1.1
298 ip2 addr add 10.0.0.100/24 dev veths
299 ip2 link set veths up
300 waitiface $netns0 vethrc
301 waitiface $netns0 vethrs
302 waitiface $netns1 vethc
303 waitiface $netns2 veths
305 n0 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_forward'
306 n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout'
307 n0 bash -c 'printf 2 > /proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream'
308 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
310 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.100:2 persistent-keepalive 1
311 n1 ping -W 1 -c 1 192.168.241.2
312 n2 ping -W 1 -c 1 192.168.241.1
313 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.1:1" ]]
314 # Demonstrate n2 can still send packets to n1, since persistent-keepalive will prevent connection tracking entry from expiring (to see entries: `n0 conntrack -L`).
316 n2 ping -W 1 -c 1 192.168.241.1
317 n1 wg set wg0 peer "$pub2" persistent-keepalive 0
319 # Test that sk_bound_dev_if works
320 n1 ping -I wg0 -c 1 -W 1 192.168.241.2
321 # What about when the mark changes and the packet must be rerouted?
322 n1 iptables -t mangle -I OUTPUT -j MARK --set-xmark 1
323 n1 ping -c 1 -W 1 192.168.241.2 # First the boring case
324 n1 ping -I wg0 -c 1 -W 1 192.168.241.2 # Then the sk_bound_dev_if case
325 n1 iptables -t mangle -D OUTPUT -j MARK --set-xmark 1
327 # Test that onion routing works, even when it loops
328 n1 wg set wg0 peer "$pub3" allowed-ips 192.168.242.2/32 endpoint 192.168.241.2:5
329 ip1 addr add 192.168.242.1/24 dev wg0
330 ip2 link add wg1 type wireguard
331 ip2 addr add 192.168.242.2/24 dev wg1
332 n2 wg set wg1 private-key <(echo "$key3") listen-port 5 peer "$pub1" allowed-ips 192.168.242.1/32
334 n1 ping -W 1 -c 1 192.168.242.2
336 n1 wg set wg0 peer "$pub3" endpoint 192.168.242.2:5
337 ! n1 ping -W 1 -c 1 192.168.242.2 || false # Should not crash kernel
338 n1 wg set wg0 peer "$pub3" remove
339 ip1 addr del 192.168.242.1/24 dev wg0
341 # Do a wg-quick(8)-style policy routing for the default route, making sure vethc has a v6 address to tease out bugs.
342 ip1 -6 addr add fc00::9/96 dev vethc
343 ip1 -6 route add default via fc00::1
344 ip2 -4 addr add 192.168.99.7/32 dev wg0
345 ip2 -6 addr add abab::1111/128 dev wg0
346 n1 wg set wg0 fwmark 51820 peer "$pub2" allowed-ips 192.168.99.7,abab::1111
347 ip1 -6 route add default dev wg0 table 51820
348 ip1 -6 rule add not fwmark 51820 table 51820
349 ip1 -6 rule add table main suppress_prefixlength 0
350 ip1 -4 route add default dev wg0 table 51820
351 ip1 -4 rule add not fwmark 51820 table 51820
352 ip1 -4 rule add table main suppress_prefixlength 0
353 # Flood the pings instead of sending just one, to trigger routing table reference counting bugs.
354 n1 ping -W 1 -c 100 -f 192.168.99.7
355 n1 ping -W 1 -c 100 -f abab::1111
357 # Have ns2 NAT into wg0 packets from ns0, but return an icmp error along the right route.
358 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
359 n0 iptables -t filter -A INPUT \! -s 10.0.0.0/24 -i vethrs -j DROP # Manual rpfilter just to be explicit.
360 n2 bash -c 'printf 1 > /proc/sys/net/ipv4/ip_forward'
361 ip0 -4 route add 192.168.241.1 via 10.0.0.100
362 n2 wg set wg0 peer "$pub1" remove
363 [[ $(! n0 ping -W 1 -c 1 192.168.241.1 || false) == *"From
10.0.0.100 icmp_seq
=1 Destination Host Unreachable
"* ]]
365 n0 iptables -t nat -F
366 n0 iptables -t filter -F
367 n2 iptables -t nat -F
373 # Test that saddr routing is sticky but not too sticky, changing to this topology:
374 # ┌────────────────────────────────────────┐ ┌────────────────────────────────────────┐
375 # │ $ns1 namespace │ │ $ns2 namespace │
377 # │ ┌─────┐ ┌─────┐ │ │ ┌─────┐ ┌─────┐ │
378 # │ │ wg0 │─────────────│veth1│───────────┼────┼──│veth2│────────────│ wg0 │ │
379 # │ ├─────┴──────────┐ ├─────┴──────────┐│ │ ├─────┴──────────┐ ├─────┴──────────┐ │
380 # │ │192.168.241.1/24│ │10.0.0.1/24 ││ │ │10.0.0.2/24 │ │192.168.241.2/24│ │
381 # │ │fd00::1/24 │ │fd00:aa::1/96 ││ │ │fd00:aa::2/96 │ │fd00::2/24 │ │
382 # │ └────────────────┘ └────────────────┘│ │ └────────────────┘ └────────────────┘ │
383 # └────────────────────────────────────────┘ └────────────────────────────────────────┘
385 ip1 link add dev wg0 type wireguard
386 ip2 link add dev wg0 type wireguard
388 ip1 link add veth1 type veth peer name veth2
389 ip1 link set veth2 netns $netns2
390 n1 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/all/accept_dad'
391 n2 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/all/accept_dad'
392 n1 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/veth1/accept_dad'
393 n2 bash -c 'printf 0 > /proc/sys/net/ipv6/conf/veth2/accept_dad'
394 n1 bash -c 'printf 1 > /proc/sys/net/ipv4/conf/veth1/promote_secondaries'
396 # First we check that we aren't overly sticky and can fall over to new IPs when old ones are removed
397 ip1 addr add 10.0.0.1/24 dev veth1
398 ip1 addr add fd00:aa::1/96 dev veth1
399 ip2 addr add 10.0.0.2/24 dev veth2
400 ip2 addr add fd00:aa::2/96 dev veth2
401 ip1 link set veth1 up
402 ip2 link set veth2 up
403 waitiface $netns1 veth1
404 waitiface $netns2 veth2
405 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.2:2
406 n1 ping -W 1 -c 1 192.168.241.2
407 ip1 addr add 10.0.0.10/24 dev veth1
408 ip1 addr del 10.0.0.1/24 dev veth1
409 n1 ping -W 1 -c 1 192.168.241.2
410 n1 wg set wg0 peer "$pub2" endpoint [fd00:aa::2]:2
411 n1 ping -W 1 -c 1 192.168.241.2
412 ip1 addr add fd00:aa::10/96 dev veth1
413 ip1 addr del fd00:aa::1/96 dev veth1
414 n1 ping -W 1 -c 1 192.168.241.2
416 # Now we show that we can successfully do reply to sender routing
417 ip1 link set veth1 down
418 ip2 link set veth2 down
419 ip1 addr flush dev veth1
420 ip2 addr flush dev veth2
421 ip1 addr add 10.0.0.1/24 dev veth1
422 ip1 addr add 10.0.0.2/24 dev veth1
423 ip1 addr add fd00:aa::1/96 dev veth1
424 ip1 addr add fd00:aa::2/96 dev veth1
425 ip2 addr add 10.0.0.3/24 dev veth2
426 ip2 addr add fd00:aa::3/96 dev veth2
427 ip1 link set veth1 up
428 ip2 link set veth2 up
429 waitiface $netns1 veth1
430 waitiface $netns2 veth2
431 n2 wg set wg0 peer "$pub1" endpoint 10.0.0.1:1
432 n2 ping -W 1 -c 1 192.168.241.1
433 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.1:1" ]]
434 n2 wg set wg0 peer "$pub1" endpoint [fd00:aa::1]:1
435 n2 ping -W 1 -c 1 192.168.241.1
436 [[ $(n2 wg show wg0 endpoints) == "$pub1 [fd00
:aa
::1]:1" ]]
437 n2 wg set wg0 peer "$pub1" endpoint 10.0.0.2:1
438 n2 ping -W 1 -c 1 192.168.241.1
439 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.2:1" ]]
440 n2 wg set wg0 peer "$pub1" endpoint [fd00:aa::2]:1
441 n2 ping -W 1 -c 1 192.168.241.1
442 [[ $(n2 wg show wg0 endpoints) == "$pub1 [fd00
:aa
::2]:1" ]]
444 # What happens if the inbound destination address belongs to a different interface as the default route?
445 ip1 link add dummy0 type dummy
446 ip1 addr add 10.50.0.1/24 dev dummy0
447 ip1 link set dummy0 up
448 ip2 route add 10.50.0.0/24 dev veth2
449 n2 wg set wg0 peer "$pub1" endpoint 10.50.0.1:1
450 n2 ping -W 1 -c 1 192.168.241.1
451 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.50.0.1:1" ]]
454 ip1 addr flush dev veth1
455 ip2 addr flush dev veth2
456 ip1 route flush dev veth1
457 ip2 route flush dev veth2
459 # Now we see what happens if another interface route takes precedence over an ongoing one
460 ip1 link add veth3 type veth peer name veth4
461 ip1 link set veth4 netns $netns2
462 ip1 addr add 10.0.0.1/24 dev veth1
463 ip2 addr add 10.0.0.2/24 dev veth2
464 ip1 addr add 10.0.0.3/24 dev veth3
465 ip1 link set veth1 up
466 ip2 link set veth2 up
467 ip1 link set veth3 up
468 ip2 link set veth4 up
469 waitiface $netns1 veth1
470 waitiface $netns2 veth2
471 waitiface $netns1 veth3
472 waitiface $netns2 veth4
473 ip1 route flush dev veth1
474 ip1 route flush dev veth3
475 ip1 route add 10.0.0.0/24 dev veth1 src 10.0.0.1 metric 2
476 n1 wg set wg0 peer "$pub2" endpoint 10.0.0.2:2
477 n1 ping -W 1 -c 1 192.168.241.2
478 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.1:1" ]]
479 ip1 route add 10.0.0.0/24 dev veth3 src 10.0.0.3 metric 1
480 n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/veth1/rp_filter'
481 n2 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/veth4/rp_filter'
482 n1 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/all/rp_filter'
483 n2 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/all/rp_filter'
484 n1 ping -W 1 -c 1 192.168.241.2
485 [[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.3:1" ]]
492 # We test that Netlink/IPC is working properly by doing things that usually cause split responses
493 ip0 link add dev wg0 type wireguard
494 config=( "[Interface
]" "PrivateKey
=$
(wg genkey
)" "[Peer
]" "PublicKey
=$
(wg genkey
)" )
495 for a in {1..255}; do
496 for b in {0..255}; do
497 config+=( "AllowedIPs
=$a.
$b.0.0/16,$a::$b/128" )
500 n0 wg setconf wg0 <(printf '%s\n' "${config[@]}")
502 for ip in $(n0 wg show wg0 allowed-ips); do
507 ip0 link add dev wg0 type wireguard
508 config=( "[Interface
]" "PrivateKey
=$
(wg genkey
)" )
510 config+=( "[Peer
]" "PublicKey
=$
(wg genkey
)" )
512 config+=( "AllowedIPs
=$a.
$b.0.0/16" )
515 n0 wg setconf wg0 <(printf '%s\n' "${config[@]}")
517 while read -r line; do
524 done < <(n0 wg show wg0 allowed-ips)
527 ip0 link add wg0 type wireguard
530 config+=( "[Peer
]" "PublicKey
=$
(wg genkey
)" )
532 config+=( "[Peer
]" "PublicKey
=$
(wg genkey
)" "AllowedIPs
=255.2.3.4/32,abcd
::255/128" )
533 n0 wg setconf wg0 <(printf '%s\n' "${config[@]}")
534 n0 wg showconf wg0 > /dev/null
538 for i in {1..197}; do
539 allowedips+=( abcd::$i )
543 allowedips="${allowedips[*]}"
545 ip0 link add wg0 type wireguard
546 n0 wg set wg0 peer "$pub1"
547 n0 wg set wg0 peer "$pub2" allowed-ips "$allowedips"
549 read -r pub allowedips
550 [[ $pub == "$pub1" && $allowedips == "(none
)" ]]
551 read -r pub allowedips
552 [[ $pub == "$pub2" ]]
554 for _ in $allowedips; do
558 } < <(n0 wg show wg0 allowed-ips)
561 ! n0 wg show doesnotexist || false
563 ip0 link add wg0 type wireguard
564 n0 wg set wg0 private-key <(echo "$key1") peer "$pub2" preshared-key <(echo "$psk")
565 [[ $(n0 wg show wg0 private-key) == "$key1" ]]
566 [[ $(n0 wg show wg0 preshared-keys) == "$pub2 $psk" ]]
567 n0 wg set wg0 private-key /dev/null peer "$pub2" preshared-key /dev/null
568 [[ $(n0 wg show wg0 private-key) == "(none
)" ]]
569 [[ $(n0 wg show wg0 preshared-keys) == "$pub2 (none
)" ]]
570 n0 wg set wg0 peer "$pub2"
571 n0 wg set wg0 private-key <(echo "$key2")
572 [[ $(n0 wg show wg0 public-key) == "$pub2" ]]
573 [[ -z $(n0 wg show wg0 peers) ]]
574 n0 wg set wg0 peer "$pub2"
575 [[ -z $(n0 wg show wg0 peers) ]]
576 n0 wg set wg0 private-key <(echo "$key1")
577 n0 wg set wg0 peer "$pub2"
578 [[ $(n0 wg show wg0 peers) == "$pub2" ]]
579 n0 wg set wg0 private-key <(echo "/${key1:1}")
580 [[ $(n0 wg show wg0 private-key) == "+${key1:1}" ]]
581 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
582 n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0
583 n0 wg set wg0 peer "$pub2" allowed-ips ::/0,1700::/111,5000::/4,e000::/37,9000::/75
584 n0 wg set wg0 peer "$pub2" allowed-ips ::/0
585 n0 wg set wg0 peer "$pub2" remove
586 for low_order_point in AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 4Ot6fDtBuK4WVuP68Z/EatoJjeucMrH9hmIFFl9JuAA= X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEVc= 7P///////////////////////////////////////38= 7f///////////////////////////////////////38= 7v///////////////////////////////////////38=; do
587 n0 wg set wg0 peer "$low_order_point" persistent-keepalive 1 endpoint 127.0.0.1:1111
589 [[ -n $(n0 wg show wg0 peers) ]]
590 exec 4< <(n0 ncat -l -u -p 1111)
592 waitncatudp $netns0 $ncat_pid
594 ! read -r -n 1 -t 2 <&4 || false
598 # Ensure there aren't circular reference loops
599 ip1 link add wg1 type wireguard
600 ip2 link add wg2 type wireguard
601 ip1 link set wg1 netns $netns2
602 ip2 link set wg2 netns $netns1
603 pp ip netns delete $netns1
604 pp ip netns delete $netns2
605 pp ip netns add $netns1
606 pp ip netns add $netns2
608 sleep 2 # Wait for cleanup and grace periods
610 while read -t 0.1 -r line 2>/dev/null || [[ $? -ne 142 ]]; do
611 [[ $line =~ .*(wg[0-9]+:\ [A-Z][a-z]+\ ?[0-9]*)\ .*(created|destroyed).* ]] || continue
612 objects["${BASH_REMATCH[1]}"]+="${BASH_REMATCH[2]}"
615 for object in "${!objects[@]}"; do
616 if [[ ${objects["$object"]} != *createddestroyed ]]; then
617 echo "Error
: $object: merely
${objects["$object"]}" >&3
621 [[ $alldeleted -eq 1 ]]
622 pretty "" "Objects that were created were also destroyed.
"