Route all traffic through Wireguard interface

I want to route all my traffic through a Wireguard VPN. So far, following the Wireguard page on the wiki, I’ve set up a wg0 interface successully. Running wg confirms the I have a connection, but how do I route all my traffic (except LAN) through it?

1 Like

Hi, the wiki already mentions that right ? allowedIPs = [ "0.0.0.0/0" ]; in the client.

With allowedIPs = [ "0.0.0.0/0" ]; I’m unable to connect to anything.

Oh right, I think you’ll need to fiddle around with ip-route to replace the default route.
See https://www.wireguard.com/netns/.

I’ll have to look into that. But also, using wg-quick with a suitable config in /etc/wireguard yields the same problem. Is wg-quick not supported on NixOS?

You can also use wg-quick from wireguard-tools. Redirecting the gateway is not supported in our nixos module.

OpenVPN has a funny way of rerouting all traffic:

$ ip route
0.0.0.0/1 via 10.8.0.5 dev tun1 
128.0.0.0/1 via 10.8.0.5 dev tun1
[...]

Using /1 instead of /0 ensure that it takes precedence over the default /0 route.
Be careful to add add a reachable dns in the VPN and that it is the one configured on your machine.

For completeness, here is my full ip route (configured by networkmanager and openvpn)

0.0.0.0/1 via 10.8.0.5 dev tun1 
default via 192.168.1.1 dev wlp2s0 proto dhcp metric 600 
10.8.0.1 via 10.8.0.5 dev tun1 
10.8.0.5 dev tun1 proto kernel scope link src 10.8.0.6 
10.8.1.1 via 10.8.1.9 dev tun0 
10.8.1.9 dev tun0 proto kernel scope link src 10.8.1.10 
10.66.0.0/24 via 10.8.1.9 dev tun0 
my.own.vpn.ip via 192.168.1.1 dev wlp2s0 
128.0.0.0/1 via 10.8.0.5 dev tun1 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown 
192.168.1.0/24 dev wlp2s0 proto kernel scope link src 192.168.1.2 metric 600 

Wireguard uses routing policies with ip rule, which is less hacky then the openvpn approach as it does not require a route for the VPN traffic via the local gateway.

I’m wondering, is it currently possible to implement the namespace solution? with the current networking modules?
It boils down to having the wg0 interface in the default network namespace, the physical ifs like wlan0 in another network namespace and then the utilities that need access to the real network must be executed like ip netns exec physical dhcpcd eth0.
I never tried but I intend to try soon :slight_smile:

1 Like

That would be awesome. I knew we could do it with containers but I didn’t realize we could do it without them.

I have exactly the same problem as you, guys, it seems that I cannot properly route all traffic.

Some notes:

  • If I try to route only the related IPs, then I can ping the gateway, e.g.
% cat /etc/wireguard/temp.conf
[Interface]
Address = 10.0.0.6/24
PrivateKey = xxx

[Peer]
PublicKey = xxx
AllowedIPs = 10.0.0.0/24
Endpoint = xxx
% sudo wg-quick up temp
[#] ip link add temp type wireguard
[#] wg setconf temp /dev/fd/63
[#] ip address add 10.0.0.6/24 dev temp
[#] ip link set mtu 1420 dev temp
[#] ip link set temp up
% ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=1.06 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.635 ms
% ip route
default via 192.168.1.1 dev enp0s25 proto dhcp src 192.168.1.127 metric 512 
default dev enp0s25 proto static scope link metric 2048 
10.0.0.0/24 dev temp proto kernel scope link src 10.0.0.6
<omit the rest>
  • If I try to route everything:
% cat /etc/wireguard/temp.conf
[Interface]
Address = 10.0.0.6/24
PrivateKey = xxx

[Peer]
PublicKey = xxx
AllowedIPs = 0.0.0.0/0
Endpoint = xxx
% wg-quick up temp
[#] ip link add temp type wireguard
[#] wg setconf temp /dev/fd/63
[#] ip address add 10.0.0.6/24 dev temp
[#] ip link set mtu 1420 dev temp
[#] ip link set temp up
[#] wg set temp fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev temp table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
% ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
^C
--- 10.0.0.1 ping statistics ---
7 packets transmitted, 0 received, 100% packet loss, time 181ms
% ip route
default via 192.168.1.1 dev enp0s25 proto dhcp src 192.168.1.127 metric 512 
default dev enp0s25 proto static scope link metric 2048 
10.0.0.0/24 dev temp proto kernel scope link src 10.0.0.6
<omit the rest>
% ip -4 route list table 51820
default dev temp scope link

Not sure if I type the right command, since manually adding the route, it complains as existing:

% sudo ip -4 route add 0.0.0.0/0 dev temp table 51820
RTNETLINK answers: File exists

I’m a bit lost with how I would debug this on my system. A first step would be to have wg-quick to actually work, which isn’t the case here. Does it work for anyone with AllowedIPs = 0.0.0.0/0? Is this a NixOS/nixpkgs bug?

1 Like

It looks like @anderspapitto is working on this :heart_eyes: : https://github.com/NixOS/nixpkgs/issues/52411

1 Like

yeah I have a working setup based on the namespace approach, described here https://reflexivereflection.com/posts/2018-12-18-wireguard-vpn-with-network-namespace-on-nixos.html

5 Likes

I think I am hitting the same problem today, when trying to connect from my NixOS laptop to https://github.com/trailofbits/algo VPN on the server.

If I start the wg connection, I can’t connect to anything (pinging 8.8.8.8 does not work) and I don’t see peer connection from the server either. When disconnect wg interface (via network manager), I actually see a handshake on the server (presumably, because something in the ip route configuration changes temporary during shutdown), but then the connection goes down.

Is https://reflexivereflection.com/posts/2018-12-18-wireguard-vpn-with-network-namespace-on-nixos.html still the best way to fix this? I am not an expert in Linux networking, so that post looks rather intimidating to me :slight_smile: