The WireGuard VPN challenge of provisioning clients

July 16, 2021

I mentioned in yesterday's entry that at work I'm building a VPN server that will support WireGuard. I'm quite happy with WireGuard in general and I think it has some important attractive features (such as the lack of 'sessions'), but we won't be offering WireGuard for general use. I would like to, but every time I even consider the idea, I run headlong into the problem of provisioning, specifically of provisioning WireGuard clients in some way that ordinary people can successfully set them up.

Right now, to set up a WireGuard client you need the server's name and port (which every VPN needs), the server's public key, the IP the server expects you to have inside the WireGuard connection (its AllowedIPs setting for you), and a private key that the server has the public key for. We also need you to set your DNS server(s) to correctly point to us, and for general VPN usage you have to set your AllowedIPs to This is a lot more things for you to set up than other VPN servers need, partly because other VPN servers will push your internal IP, the DNS servers to use, and often other information to you. Much of this is also sensitive to typos or, in the case of keys, must be cut and pasted to start with (no one is typing a base64 WireGuard key). If you get your client IP wrong, for example, things just quietly don't work (the server will discard your traffic).

The client keypair is an especially touchy problem. The ideal would be to securely generate it on the client and upload the public key. In practice this is asking a lot of people to do more or less by hand, so in a realistic setup we would probably want to generate your client keypair on the server and then somehow give you access to the private key for you to configure along side the server's public key. Given this, possibly the most generally usable way of provisioning WireGuard client connections would be to generate the wg.conf that a client would use with the normal WireGuard command line tools, then provide it to people and hope that any WireGuard client will be able to import it.

(The official WireGuard client for iOS and Android will apparently do this, including decoding the configuration from a QR code. I believe the official Windows client does as well. On Unix, you can use the wg.conf directly or import it into NetworkManager.)

An additional complication is that you need a separate WireGuard configuration on each device that you want to use WireGuard on at the same time. So we wouldn't have to just provision one WireGuard setup per person, we're looking at one for your laptop, one for your phone, one for your tablet, and so on. This also complicates naming them and keeping track of them (for people and for us), and likely would tempt people into reusing configurations across devices, which leads to fun problems if both devices are in use at the same time.

I don't blame the WireGuard project for this state of affairs. Provisioning is both a hard problem and a high level concern that is sort of out of scope for a project that's deliberately low level and simple. I'm honestly impressed (and happy) that there are official WireGuard clients on as many platforms as there are. I do wish there was some officially supported way to push configuration information to clients, although I understand why there isn't.

(Tailscale is not a solution for us for various reasons, including price. I do admire them for solving the provisioning problem, though.)

Comments on this page:

By Alex at 2021-07-17 08:09:15:

Maybe something like Subspace?

There are a couple of other tools to manage Wireguard client configurations too. Dont't have any recommendations though, as I've never actually used any of them myself.

There are a couple of interesting alternatives to tailscale:

And probably more that I can't remember or don't know about.

Written on 16 July 2021.
« Setting up a WireGuard client with NetworkManager (using nmcli)
The minimum for syslog configurations should be to log (nearly) everything »

Page tools: View Source, View Normal, Add Comment.
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Fri Jul 16 23:56:07 2021
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.