== Setting up a WireGuard client with NetworkManager (using _nmcli_) For reasons beyond the scope of this entry, I've been building a VPN server that will support [[WireGuard https://www.wireguard.com/]] (along with OpenVPN and L2TP). A server needs a client, so I spent part of today setting up [[my work laptop DellXPS13FedoraReview]] as a WireGuard client in a 'VPN' configuration, under NetworkManager because that's what my laptop uses. I was hoping to do this through the Cinnamon GUIs for NetworkManager, but unfortunately while NetworkManager itself has supported WireGuard for some time, this support hasn't propagated into GUIs such as the GNOME Control Center ([[cf https://gitlab.gnome.org/GNOME/gnome-control-center/-/issues/982]]) or the NetworkManager applet that Cinnamon uses. I'm already quite familiar with WireGuard in general, so I found that the easiest way to start was to set up a basic WireGuard configuration file for the connection in _/etc/wireguard/wg0.conf_, including both the main configuration (with the laptop's key and my local port) and a _[Peer]_ section for the server. Since I'm using WireGuard here in a VPN configuration, instead of to reach just some internal IPs, I set [[_AllowedIPs_ WireGuardAllowedIPs]] to 0.0.0.0/0. After writing _wg0.conf_, I then imported it into NetworkManager: .pn prewrap on > nmcli connection import type wireguard file /etc/wireguard/wg0.conf (For what can go in the configuration file, start with [[_wg(8)_ https://man7.org/linux/man-pages/man8/wg.8.html]] and [[_wg-quick(8)_ https://man7.org/linux/man-pages/man8/wg-quick.8.html]]. I suspect that NetworkManager doesn't support some of the more advanced keys. I stuck to the basics. The import process definitely ignores the various script settings supported by [[_wg-quick(8)_]]. Currently, see _``nm_vpn_wireguard_import()''_ in [[nm-vpn-helpers.c https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/main/src/libnmc-base/nm-vpn-helpers.c]].) Imported connections are apparently set to auto-connect, which isn't what I wanted, plus there were some other things to adjust (following the guide of Thomas Haller's [[WireGuard in NetworkManager https://blogs.gnome.org/thaller/2019/03/15/wireguard-in-networkmanager/]]): > nmcli con modify wg0 \ > autoconnect no \ > ipv4.method manual \ > ipv4.address 172.29.50.10/24 \ > ipv4.dns <...> At this point you might be tempted to set _ipv4.gateway_, and indeed that's what I did the first time around. It turns out that this is a mistake, because these days NetworkManager will do the right thing based on the 'accept everything' _AllowedIPs_ I set, right down to setting up policy based routing with a fwmark so that encrypted traffic to the WireGuard VPN server doesn't try to go over WireGuard. If you set _ipv4.gateway_ as well, you wind up with two default routes and then your encrypted WireGuard traffic may try to go over your WireGuard connection again, which doesn't work. (See the description of '_ip4-auto-default-route_ in [[the WireGuard configuration properties https://developer.gnome.org/NetworkManager/stable/settings-wireguard.html]]. The full index of available NetworkManager settings in various sections is currently [[here https://developer.gnome.org/NetworkManager/stable/ref-settings.html]]; the ones most useful to me are probably [[_connection.*_ https://developer.gnome.org/NetworkManager/stable/settings-connection.html]] and [[_ipv4.*_ https://developer.gnome.org/NetworkManager/stable/settings-ipv4.html]].) Getting DNS to work correctly requires a little extra step, or at least did for me. While the _wg0_ connection is active, I want all of my DNS queries to go to our internal resolving DNS server and also to have a search path of our university subdomain. This apparently requires explicitly including '_~_' in the NetworkManager DNS search path: > nmcli con modify wg0 \ > ipv4.dns-search "cs.toronto.edu,~" This comes from [[Fedora bug #1895518 https://bugzilla.redhat.com/show_bug.cgi?id=1895518]], which also has some useful [[_resolvectl_ https://man7.org/linux/man-pages/man1/resolvectl.1.html]] options. You (I) can see a lot of settings for the WireGuard setup with '_nmcli connection show wg0_', including active ones, but this seems to omit NetworkManager's view of the WireGuard peers. To see that, I needed to look directly at the configuration file that NetworkManager wrote, in _/etc/NetworkManager/system-connections/wg0.nmconnection_. I'm someday going to need to edit this directly to modify the WireGuard VPN server's endpoint from my test machine to the production machine. (The NetworkManager RFE for configuring WireGuard peers in _nmcli_ is [[issue #358 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/358]].) With no GUI support for WireGuard connections, I have to bring this WireGuard VPN up and down with '_nmcli con up wg0_' and '_nmcli con down wg0_'. Once I have the new VPN server in production, I'll be writing little scripts to do this for me. Hopefully this will be improved some day, so that the NetworkManager applet allows you to activate and deactivate WireGuard connections and shows you that one is active. If I wanted a limited VPN that only sent traffic to our internal networks over my WireGuard link, I would configure the server's _AllowedIPs_ to the list of networks and then I believe that NetworkManager would automatically set up routes for them. However, I don't know how to make this work (in NetworkManager) if the WireGuard VPN server itself was on one of the subnets I wanted to reach over WireGuard. For my laptop, routing all traffic over WireGuard to work is no worse than using our OpenVPN or L2TP VPN servers, which also do the same thing by default. (On my home desktop, I use [[hand built fwmark-based policy rules WireGuardEarlyNotes]] to deal with my WireGuard endpoint being on a subnet I want to normally reach over WireGuard. NetworkManager will build the equivalents for me when I'm routing 0.0.0.0/0 over the WireGuard link, but I believe not in other situations.) (For information, I primarily relied on Thomas Haller's [[WireGuard in NetworkManager https://blogs.gnome.org/thaller/2019/03/15/wireguard-in-networkmanager/]], supplemented with [[a Fedora Magazine article https://fedoramagazine.org/configure-wireguard-vpns-with-networkmanager/]] and [[this article https://www.xmodulo.com/wireguard-vpn-network-manager-gui.html]].)