I'm trying to get a "simple" VPN working between two Linux boxes using Wireguard. Unfortunately, existing tutorials I've found weren't that helpful, because they usually A) only set up IPv4 and B) usually use IP masquerading ...
Config of machine A:
[Interface]
Address = 192.168.10.2/24
ListenPort = 51820
[Peer]
AllowedIPs = 192.168.10.0/24, 172.16.0.0/24, fdbb:bbbb:bbbb::/48, 2001:db8:bbbb:0000::/64
Endpoint = [2001:db8:bbbb:0000:1234:56ff:fe78:90ab]:51820
PersistentKeepalive = 20
Config of machine B:
[Interface]
Address = 192.168.10.1/24
ListenPort = 51820
[Peer]
AllowedIPs = 192.168.10.2/32, 10.0.0.0/16, fdaa:aaaa:aaaa::/48, 2001:db8:aaaa:0000::/64
Endpoint = [2001:db8:aaaa:0000:ba09:87ff:fe65:4321]:51820
PersistentKeepalive = 20
(Leaving out the keys because the tunnel itself is passing traffic so I know these are correct).
So, simple config, in theory. Machine A has no local firewall (only a typical consumer router with its built-in firewall, with UDP/51820 opened), machine B has ip(6)tables but only for all the Docker rules, and the default policies are set to Accept.
Both machines have net.ipv4.ip_forward=1
and net.ipv6.conf.all.forwarding=2
.
That config didn't work, because Wireguard apparently tries to route **its own wireguard traffic** through the tunnel itself because the Endpoint IPv6 is included in the AllowedIPs network. Why would that not be excluded by default...
I tried to get around that by adding a fixed route to send traffic for that endpoint through the normal interface, not wg0:
PostUp = /usr/sbin/ip -6 route add 2001:db8:aaaa:0000:ba09:87ff:fe65:4321/128 via fe80::1 dev enp1s0
PreDown = /usr/sbin/ip -6 route del 2001:db8:aaaa:0000:ba09:87ff:fe65:4321/128 via fe80::1 dev enp1s0
With that setup (on both sides), the peers can ping eachother A) through the WG peer addresses (192.168.10.X), B) through their local IPv4 (10.0.X.X or 172.16.X.X), and C) through their ULA addresses.
However, I still have two issues with my tunnel:
A) Because I had to add that IPv6 route to the endpoint, that means traffic to the other peer's public IPv6 address does not go through the WG tunnel but travels directly over the internet. The peers cannot ping eachother using their public GUA IPv6 addresses. I would need something like that IP route I added using the PostUp parameter, but for that to only apply to the tunnel itself, not for traffic going through the tunnel. Like an IPv6 route where I can say "route UDP/51820 over this route (directly to the internet), but other traffic to that same IP over that route (wg0)".
B) I can't get everything to work from other machines in my network (over IPv4). On another machine on network A, I added a static route to the other network's IPv4: 172.16.0.0/24 via 10.0.1.25 dev enp7s0 metric 100
.
When I now do a traceroute, the 1st hop is the wireguard machine (10.0.1.25), and the 2nd hop is the WG peer's address of the remote machine (192.168.10.1) (so it does go through the tunnel!), but after that, boom, that's it. No third hop with the actual destination (even though the other side's default gateway does have a static route to route 10.0.0.0/8 to that side's wireguard machine. I do not want to do IP masquerading which is the "solution" I found multiple times using Google. I want the other machines on the other network see exactly where the requests are coming from - a machine on the other side of the tunnel.
Over IPv6, using the ULAs, everything is fine. Added an IPv6 route on the gateway to route the other side's ULAs to the wireguard machine, and done. I just need to find a solution for the GUAs, probably with radvd on the wireguard machine announcing a route to that network.
TL;DR: Wireguard connection between two peers works, but A) how do I send non-Wireguard traffic to the wireguard endpoint IP over the tunnel as well, and B) why does IPv6 ULA routing work and IPv4 routing doesn't even though they're set up the same.
Asked by Florian Bach
(263 rep)
May 1, 2023, 08:14 AM
Last activity: Jun 27, 2025, 03:08 AM
Last activity: Jun 27, 2025, 03:08 AM