WireGuard with NetworkManager

Since NetworkManager added support for managing WireGuard interfaces, I have been using it on my laptop to provide a simple point-and-click interface for connecting to my home VPN while away. Unfortunately, it has some quirky behavior. For example, when I put my computer to sleep, the WLAN interface disconnects, but the WireGuard interface does not. This causes a bunch of network problems when I wake the computer. To work around this, I put this script in /usr/lib/systemd/system-sleep/:


nmcli -t connection show --active \
    | awk -F: '$3=="wireguard"{print $2}' \
    | xargs -r -n1 nmcli connection down

This script takes down any active any WireGuard connections before the system goes to sleep.

I believe this problem stems from the fact that I want to route all traffic over the VPN as long as it is connected. To accomplish this, I configured the WireGuard connection to define the default gateway. Unfortunately, NetworkManager does not seem to handle this very well, and it ends up configuring the routing table to route the WireGuard traffic over the WireGuard tunnel. I imagine if I can figure out how to get this working correctly, I will not need the system-sleep script.

UPDATE: While writing this post, I decided to try again to figure out why routing all traffic over the WireGuard interface wasn't working. Lo and behold, I found some information about this specific problem in the NetworkManager Blog: Routing All Your Traffic. I was able to fix the issue by changing a few of the connection settings:

nmcli connection modify Pyrocufflink \
    ipv4.gateway '' \
    wireguard.peer-routes yes \
    wireguard.ip4-auto-default-route yes

This disables setting an explicit default gateway and enables receiving routes from the WireGuard peer. NetworkManager puts these routes into a different routing table and correctly configures all traffic except WireGuard itself to be routed over the WireGuard tunnel.