== The WireGuard VPN challenge of provisioning clients I mentioned in [[yesterday's entry ../linux/NetworkManagerWireGuardClient]] that at [[work https://support.cs.toronto.edu/]] I'm building a VPN server that will support [[WireGuard https://www.wireguard.com/]]. I'm quite happy with WireGuard in general and I think it has some important attractive features (such as [[the lack of 'sessions' ../tech/WireGuardNoUserSessions]]), 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 https://support.cs.toronto.edu/]] 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 0.0.0.0/0. 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 ../linux/NetworkManagerWireGuardClient]].) 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.)