You are not logged in.

#1 2026-09-15 05:57:20

Beemo
Member
Registered: 2024-12-20
Posts: 201

[SOLVED] 2 WireGuard interfaces with AllowedIPs=0.0.0.0/0?

I'm trying to set up 2 WireGuard interfaces that will serve as gateways. One for default IPv6 gateway (as I don't have native IPv6 and due to its low latency), one for qBittorrent as the quota on the other one is not large enough for this purpose.

My configs:

# 30-wg-vps2.netdev
[NetDev]
Description=WireGuard tunnel to VPS2
Name=wg-vps2
Kind=wireguard

[WireGuard]
PrivateKey=(client priv key)
ListenPort=51820

[WireGuardPeer]
PublicKey=(vps2 pub key)
AllowedIPs=0.0.0.0/0, ::/0
Endpoint=(vps2 endpoint IP4):51820
PersistentKeepalive=120
# 31-wg-vps2.network
[Match]
Name=wg-vps2
Type=wireguard

[Link]
RequiredForOnline=routable

[Network]
Description=WireGuard VPS2 tunnel: IP4 + IP6, IPv6 default gateway
Address=10.0.1.11/24
Address=a:b:c:d::11/80
Gateway=::
# 40-wg-vps1.netdev
[NetDev]
Description=WireGuard tunnel to VPS1
Name=wg-vps1
Kind=wireguard

[WireGuard]
PrivateKey=(client priv key)
ListenPort=51821

[WireGuardPeer]
PublicKey=(vps1 pub key)
AllowedIPs=0.0.0.0/0, ::/0
Endpoint=(vps1 endpoint IP4):51820
# PersistentKeepalive=120
# 41-wg-vps1.network
[Match]
Name=wg-vps1
Type=wireguard

[Link]
RequiredForOnline=routable

[Network]
Description=WireGuard VPS2 tunnel: IP4 + IP6
Address=10.0.0.11/24
Address=1:2:3:4::5:6/128

[Route]
Gateway=::
Metric=4096
IPv6Preference=low

Routes:

$ ip route show
default via 10.21.120.1 dev bridge-0 proto dhcp src 10.21.120.44 metric 1024
10.0.0.0/24 dev wg-vps1 proto kernel scope link src 10.0.0.11
10.0.1.0/24 dev wg-vps2 proto kernel scope link src 10.0.1.11
10.21.120.0/23 dev bridge-0 proto kernel scope link src 10.21.120.44 metric 1024
10.21.120.1 dev bridge-0 proto dhcp scope link src 10.21.120.44 metric 1024

$ ip -6 route show
1:2:3:4::5:6 dev wg-vps1 proto kernel metric 256 pref medium
a:b:c:d::/80 dev wg-vps2 proto kernel metric 256 pref medium
fe80::/64 dev bridge-0 proto kernel metric 256 pref medium
default dev wg-vps2 proto static metric 1024 pref medium
default dev wg-vps1 proto static metric 4096 pref low

Two problems I ran into:

When one interface works the other doesn't. Packet dump ("sudo tcpdump port 51820") shows that the handshake attempt traffic is getting sent out my Ethernet interface, but the VPS doesn't see it at all (not even on Ethernet). Somehow, changing the port in the config will make it work, but also break the other interface with the same problem. From a comment by zx2c4 I'm guessing it's due to the overlapping "AllowedIPs=0.0.0.0/0, ::/0". But if the kernel got confused about the destination due to AllowedIP cryptokey routing, I shouldn't see the packet getting sent to the right destination (yet server seeing nothing).

While setting them up, at some point both worked, but kernel refuses to bind IPv6 unless there is a route to the destination on the specific interface, hence the unnecessary [Route] in my config. But IPv4 does not have this restriction. Before that section was added:

$ ping -c 3 -6 -I wg-vps1 one.one.one.one
ping: setsockopt(SO_BINDTODEVICE) wg-vps2: Operation not permitted
$ ping -c 3 -6 -I wg-vps2 one.one.one.one
PING one.one.one.one (2606:4700:4700::1111) from a:b:c:d::11 wg-vps2: 56 data bytes

$ sudo ip -6 route del default dev wg-vps2 proto static metric 1024 pref medium
$ sudo ip -6 route add default dev wg-vps1 proto static metric 1024 pref medium

$ ping -c 3 -6 -I wg-vps1 one.one.one.one
PING one.one.one.one (2606:4700:4700::1001) from 1:2:3:4::5:6 wg-vps1: 56 data bytes
$ ping -c 3 -6 -I wg-vps2 one.one.one.one
ping: setsockopt(SO_BINDTODEVICE) wg-vps2: Operation not permitted

$ ping -c 3 -4 -I wg-vps1 one.one.one.one
PING one.one.one.one (1.0.0.1) from 10.0.0.11 wg-vps1: 56(84) bytes of data.
$ ping -c 3 -4 -I wg-vps2 one.one.one.one
PING one.one.one.one (1.0.0.1) from 10.0.1.11 wg-vps2: 56(84) bytes of data.

So is it possible to have 2 WireGuard interfaces with both "AllowedIPs=0.0.0.0/0, ::/0"? Is this some kind of kernel bug or WireGuard module limitation? Is there a better way to have 2 WireGuard split tunneling for my situation?

Last edited by Beemo (2026-09-16 13:19:05)

Offline

#2 2026-09-15 06:25:46

-thc
Member
Registered: 2017-03-15
Posts: 1,215

Re: [SOLVED] 2 WireGuard interfaces with AllowedIPs=0.0.0.0/0?

WireGuard establishes "0.0.0.0/0, ::/0" routing via rule-based routing.

Take a look at

ip rule

and if a VPN is active look into the special routing table for all packets without the fwmark (in my case 52078)

ip route list table 52078

Since those rules use a fixed "fwmark" value (in my case "0xcb6e") to decide whether to route it through the WireGuard interface or the main routing table the second VPN will always overwrite the rule-based routing of the first one.

Offline

#3 2026-09-15 06:32:32

Beemo
Member
Registered: 2024-12-20
Posts: 201

Re: [SOLVED] 2 WireGuard interfaces with AllowedIPs=0.0.0.0/0?

$ ip rule
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default
$ ip -6 rule
0:      from all lookup local
32766:  from all lookup main

I'm using systemd-networkd, it seems to not add special stuff like wg-quick or NetworkManager does...

Offline

#4 2026-09-15 07:00:55

-thc
Member
Registered: 2017-03-15
Posts: 1,215

Re: [SOLVED] 2 WireGuard interfaces with AllowedIPs=0.0.0.0/0?

That's news to me - thanks. I didn't expect that.

Which should mean that all routing decisions are made via the main routing table.

Do you have two different key sets for the VPNs?

Offline

#5 2026-09-15 07:02:37

Beemo
Member
Registered: 2024-12-20
Posts: 201

Re: [SOLVED] 2 WireGuard interfaces with AllowedIPs=0.0.0.0/0?

Yes, kind of. The client reuses its key set for the 2 WireGuard interfaces but the VPSes have their different key sets. (I'll update the post to make it clearer)

Last edited by Beemo (2026-09-15 07:04:51)

Offline

#6 2026-09-15 07:04:47

-thc
Member
Registered: 2017-03-15
Posts: 1,215

Re: [SOLVED] 2 WireGuard interfaces with AllowedIPs=0.0.0.0/0?

IMHO that shouldn't work. Try two different key sets for both VPNs on the client side.

Last edited by -thc (2026-09-15 07:05:05)

Offline

#7 2026-09-15 07:12:33

Beemo
Member
Registered: 2024-12-20
Posts: 201

Re: [SOLVED] 2 WireGuard interfaces with AllowedIPs=0.0.0.0/0?

Omg it seems to work! Testing it a bit more now...

EDIT: Works, I got IPv4 + IPv6 connectivity on both interfaces. The extra default route is still needed for IPv6 but I can live with it (with a higher metric it probably won't get used).
Thanks!

Last edited by Beemo (2026-09-15 07:18:49)

Offline

#8 2026-09-15 10:26:04

Beemo
Member
Registered: 2024-12-20
Posts: 201

Re: [SOLVED] 2 WireGuard interfaces with AllowedIPs=0.0.0.0/0?

Welp... it blew up again after some time of use.
The packet dump I was talking about in my OP:
Client:

$ networkctl
IDX LINK        TYPE      OPERATIONAL SETUP
  5 wg-vps2     wireguard routable    configured
  6 wg-vps1     wireguard routable    configured
$ sudo networkctl down 6

$ sudo tcpdump port 51820 and dst vps2.tld
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on enp0s31f6, link-type EN10MB (Ethernet), snapshot length 262144 bytes
19:48:20.635258 IP (client hostname).51820 > (vps2 IP4).51820: UDP, length 148
19:48:25.755252 IP (client hostname).51820 > (vps2 IP4).51820: UDP, length 148
19:48:30.875253 IP (client hostname).51820 > (vps2 IP4).51820: UDP, length 148

VPS2:

$ sudo tcpdump port 51820
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens3, link-type EN10MB (Ethernet), snapshot length 262144 bytes
09:43:54.352995 IP (vps2 hostname).51820 > (ISP NAT gateway).51820: UDP, length 148
09:43:59.732527 IP (vps2 hostname).51820 > (ISP NAT gateway).51820: UDP, length 148
09:44:04.852517 IP (vps2 hostname).51820 > (ISP NAT gateway).51820: UDP, length 148

VPS1, in case traffic was mis-delivered to VPS1:

$ sudo tcpdump port 51820
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on ens3, link-type EN10MB (Ethernet), snapshot length 262144 bytes
09:50:17.489116 IP (vps1 hostname).51820 > (ISP NAT gateway).51821: UDP, length 148
09:50:22.540160 IP (vps1 hostname).51820 > (ISP NAT gateway).51821: UDP, length 148
09:50:27.993102 IP (vps1 hostname).51820 > (ISP NAT gateway).51821: UDP, length 148

Same entries repeating infinitely for all 3. Basically they were trying to talk to each other but neither side was receiving. (Not seeing VPS1 is normal as I turned it off on the client)

Looking at the NAT, it gave me an idea: Instead of assuming it's some kind of bug in the kernel and I'm seeing ghost packets, it's far more likely that the packets are being sent, but the NAT in the middle is utterly broken -- maybe somehow it doesn't like having 2 destinations with the same port? (Source port I can understand, why is dst port its business...)

I changed the listening port on VPS2, and so far it's working.
But as we've found out, any changes will cause it work for a while, so I'm waiting a day before I draw any conclusions...

Last edited by Beemo (2026-09-15 10:31:02)

Offline

#9 2026-09-15 12:49:38

-thc
Member
Registered: 2017-03-15
Posts: 1,215

Re: [SOLVED] 2 WireGuard interfaces with AllowedIPs=0.0.0.0/0?

In theory the NAT connection table entry should be unique when only one parameter differs (source port) - but that's dependent on the actual NAT implementation of the NAT device.

Offline

#10 2026-09-16 13:17:54

Beemo
Member
Registered: 2024-12-20
Posts: 201

Re: [SOLVED] 2 WireGuard interfaces with AllowedIPs=0.0.0.0/0?

Alright, it's still working today, marking this as solved.

p.s. The firewall / NAT might be Palo Alto, but outdated / poorly maintained (seeing how it doesn't have IPv6).

Offline

#11 2026-09-25 16:11:13

Beemo
Member
Registered: 2024-12-20
Posts: 201

Re: [SOLVED] 2 WireGuard interfaces with AllowedIPs=0.0.0.0/0?

Found another solution:

PersistentKeepalive=30

The firewall is Palo Alto, which has DPI flow classification ("App-ID").
I can't see what's going on in there, but apparently it kills long-lived connections (known from experience) and then actively blocks WireGuard's attempt to establish a new connection (handshake initiation packets, packet dump) (when the port is the same), all the while allowing other traffic on the port through (e.g. nc).
60s doesn't work, 30s works.

Last edited by Beemo (2026-09-25 16:15:16)

Offline

Board footer

Powered by FluxBB