Edit 3: Tested with wg-quick on Arch, same issue re-occurs. So, let’s say we have a peer on 192.168.1.1/24 with internal (wireguard) IP of 10.0.0.1/24, but we also want to route through it to rest of 192.168.1.0/24.
Instead of nice AllowedIPs = 10.0.0.0/24,192.168.1.0/24, it would have to be:
AllowedIPs = 10.0.0.0/24, 192.168.1.1/32, 192.168.1.2/31, 192.168.1.4/30, 192.168.1.8/29, 192.168.1.16/28, 192.168.1.32/27, 192.168.1.64/26, 192.168.1.128/25
Or there’s something else going wrong. I only tried on Arch. Welp, as I said, it’s not a thing that occurs with WG Tunnel on Android.

Edit 2: Hypothesis confirmed. Excluding the endpoint from AllowedIPs in NetworkManager solves the issue. However, this isn’t a problem with 0.0.0.0/0, nor with WG Tunnel app on Android. I’ll have to check with wg-quick. That seems most official.
Summary: NetworkManager tries to route traffic to WG peer over the same WG interface, and its /32 has to be excluded.

Edit: I noticed one thing, I’ll try excluding the peer endpoint from AllowedIPs. It seems weird if it tries to connect to it over the interface between the 2 peers, which is of course impossible, but maybe? However, it is not matched by 0.0.0.0/0. Welp, time to experiment.

So, for 2 years I thought that NetworkManager Wireguard implementation is simply broken.
When I used a list of address ranges, like I should be (and am) able to do with Wireguard, I couldn’t get any traffic through, however 0.0.0.0/0,::/0 would work.

Today I discovered something… interesting. It actually works… with a smaller list of AllowedIPs. Although even a larger list still ends up being shown by ip r.
So I went to AllowedIPs calculator as usual, created a desired list, pasted it in, and started removing IP ranges until I could ping a remote peer.

Problem solved? Well, no. I hoped it would be the limitation in number of routes, but it (also) seems to depend on route size.

Examples:
This is too much:
0.0.0.0/5,8.0.0.0/7,11.0.0.0/8,12.0.0.0/6,16.0.0.0/4,32.0.0.0/3,64.0.0.0/2,128.0.0.0/3,160.0.0.0/5,168.0.0.0/6,172.0.0.0/12,172.32.0.0/11,172.64.0.0/10,172.128.0.0/9,10.147.0.0/24
Removing one of the routes, 172.128.0.0/9 makes it work.
0.0.0.0/5,8.0.0.0/7,11.0.0.0/8,12.0.0.0/6,16.0.0.0/4,32.0.0.0/3,64.0.0.0/2,128.0.0.0/3,160.0.0.0/5,168.0.0.0/6,172.0.0.0/12,172.32.0.0/11,172.64.0.0/10,10.147.0.0/24

Time for mystery start. Keeping the same number of routes, but decreasing the size of one of them (second last) also makes it work:
0.0.0.0/5,8.0.0.0/7,11.0.0.0/8,12.0.0.0/6,16.0.0.0/4,32.0.0.0/3,64.0.0.0/2,128.0.0.0/3,160.0.0.0/5,168.0.0.0/6,172.0.0.0/12,172.32.0.0/11,172.64.0.0/10,172.128.0.0/10,10.147.0.0/24

Naturally, I tried breaking up 172.128.0.0/9 into 172.128.0.0/10 and 172.192.0.0/10, which breaks it again.

So, it seems to depend on both number and size of the routes. After all, larger ones alone worked.

  • ken@discuss.tchncs.de
    link
    fedilink
    arrow-up
    6
    ·
    edit-2
    2 days ago

    Maybe you already figured this out but I think it’s a common gotcha:

    Wireguard AllowedIPs means just that: IP addresses that are allowed to be routed over the tunnel.

    There is nothing that says that you need to have 1-to-1 mapping between that and actual routes. Most of the time it’s what you want but there are situations where you want it different. Some people have a wider subnet for AllowedIPs but only add certain routes specifically.

    wg-quick additionally adds corresponding ip routes as a convenience. systemd-networkd did at some point but don’t anymore. I’m not sure what NetworkManager’s Wireguard plugin is even supposed to be doing there these days. Most of the time what looks broken is actually a result of unclear documentation and a mismatch in assumptions between dev and user.

    It’s an understandable source of confusion and the tools don’t always help when they try to.