Odd behaviour with wireguard on windows when using subnets in AllowedIPs
Theodor Mittermair
tmittermair at cvl.tuwien.ac.at
Tue May 23 13:00:09 UTC 2023
Hi!
I already asked about this on https://web.libera.chat/#wireguard and was told to post to the mailing list.
tl;dr: under windows when using multiple subnets different from /0 or /32, they are treated as networks with broadcast adresses, makeing certain addresses not be tunneled as expected.
long story:
Preface (i changed details to avoid privacy conflicts, but to the best of my knowledge, that should not change the results):
Under my administration is a public /24 network, lets call it 1.2.3.0/24.
There is a wireguard server, assume it's address is 1.2.3.66.
In the network are some ssh servers which are not publicly reachable from outside the network, as well as a http(s) server on 1.2.3.79 which is generally reachable from everywhere.
It is the goal to tunnel only necessary addresses to the wireguard server, such that a client can access the internal ssh servers, but it is expected that the generally available http(s) server continues to be reachable.
To archieve this, I have client configurations that generally look like this:
==== ==== ==== ====
[Interface]
PrivateKey=clientprivkey
Address=10.20.0.4/32
[Peer]
PublicKey=serverpubkey
AllowedIPs=1.2.3.0/26
AllowedIPs=1.2.3.64/31
AllowedIPs=1.2.3.67/32
AllowedIPs=1.2.3.72/29
AllowedIPs=1.2.3.80/28
AllowedIPs=1.2.3.96/27
AllowedIPs=1.2.3.128/25
Endpoint=1.2.3.66:51820
PersistentKeepalive=15
==== ==== ==== ====
Reason for the ugly list of AllowedIPs of course is, if i just wrote "AllowedIPs=1.2.3.0/24" that would attempt to tunnel all traffic including the tunnel traffic that should go to the wireguard server through the tunnel.
While i hoped that this might work by the same magic that makes "AllowedIPs=0.0.0.0/0" work, experiments showed that a single "AllowedIPs=1.2.3.0/24" does not work on linux.
These configurations successfully connect to the wireguard server on both windows and linux and provide atleast _some_ functionality.
On linux, this config seems to work as i desire.
On windows, i can reach atleast one of the ssh internal ssh servers that would not be accessible without the tunneling, but, the http(s) server on .79 is not reachable anymore.
If i attempt to enter the webservers url or it's ip address in chrome on windows, i get an error "ERR_ADDRESS_INVALID" as long as the wireguard tunnel is active.
For debugging purposes i replaced "AllowedIPs=1.2.3.72/29" with "AllowedIPs=1.2.3.79/32" (ignoring the lost hosts for a moment), which makes it work (read as: i can access the http service on .79 as expected).
Out of curiosity, i tried to replace all AllowedIPs with a single "AllowedIPs=1.2.3.0/24" on windows (which was not functional under linux) and suprisingly that worked (means: ssh and http works as expected).
Further online reading brought up the "Table=off" option in the "[Interface]" section. When used with the sample configuration above, it makes it work on windows as well (though i have no reasonable explanation).
The same config with "Table=off" does not work at all on linux (understandable, since the routes to the subnets just aren't added anymore at all).
What at one point dawned on me, is that .79 is the last address of the .72/29 block, i.e. it's broadcast address.
That would also kind of explain the error my browser showed me in a way (since it's not really a thing to connect to a broadcast address over http i think).
The theory is somewhat verified by obtaining the same result when attempting to connect to other "broadcast" addresses (e.g.: 1.2.3.127) while the wireguard tunnel is active.
Conclusion:
I am now somewhat stuck with two variations (AllowedIPs netlist vs net/24 & Table=auto vs Table=off), which both make the config work on windows OR linux, but never fully functionally on both at the same time.
Because i would like to distribute a number of client configurations to unknown-OS-users, it would be strongly preferred to have one config that works regardless of client OS.
I _could_ just list each addresses in the /24 as a /32 and be done, but thats really awfull (and makes the config parser that does the pretty colors on windows hang for quite some seconds).
Am i missing something or did i find somewhat of a bug?
best regards
Theodor Mittermair
More information about the WireGuard
mailing list