How to set up a wireguard VPN in minutes with dsnet
TL;DR: Check out dsnet for an easy way to manage a wireguard VPN.
Wireguard is a relatively new VPN tunnel. It is now in the linux 5.6 kernel – it is therefore probably going to become the VPN solution of choice; replacing the antiquated and cumbersome IPsec and OpenVPN.
There are lots of articles about the advantages of Wireguard and how to set it up, but most of them involve a lot of manual configuration file manipulation – manipulation that can get a bit tedious when dealing with dozens of clients.
Over the years I’ve used OpenVPN, Tinc, IPsec and even a Sonicwall SSLVPN. The first three were reliable, but required a lot of configuration and were less-than-ideal for various reasons. The latter was just terrible in every way.
My use cases
Whilst wireguard is capable of a fully peer-to-peer network topology (and in fact, arbitrary topologies) I am currently only interested in the traditional star topology. I have 3 use cases:
- A private VPN where I can network my machines with friends machines for gaming, file sharing, self-hosting etc
- A replacement for the Sonicwall SSLVPN appliance at work, to allow IP restricted access, prevent MITM attacks on remotely working employees, and allow connection to office PCs and servers.
- Connection to my home network devices and services. My services are mostly already behind a HTTPS reverse proxy, using the VPN as well adds another layer of security when configured correctly.
I had a look at what was available but wasn’t happy with the security models of the various web UIs available on github; they had various problems such as requiring running as root, storing the private keys for peers permanently on the server, complexity etc. I won’t name them.
I eventually settled on Wireguard (using wq-quick on the server) but ended up
searching for a way to automate the (fairly low-level) configuration as it
proved a bit tedious to set up
wg-quick manually for every peer. In
particular, I needed:
- A way to record a name and description against each peer. I couldn’t keep track of what public key corresponds to which peer without recording it separately.
- A way to add peers as fast as possible. Manually generating
private/public/shared keys, manually allocating an IP and manually updating
wg-quickserver configuration file got tedious quickly.
- For the security model to be strong
I created dsnet to solve those 3 problems. It’s a simple configuration tool that uses the wgctrl-go bindings to configure a wireguard interface for a star-type network topology – peer to peer was not a requirement for me at this time.
The first thing you need to do, of course, is install wireguard – the official website has installation information for most platforms here: https://www.wireguard.com/install/.
The next thing is to get the dsnet binary for your platform an install it. I’m assuming amd64 linux:
sudo wget https://github.com/naggie/dsnet/releases/download/v0.1/dsnet-linux-amd64 -O /usr/local/bin/dsnet
Alternatively you could compile it yourself after installing the latest go with
go build cmd/dsnet in the repository.
Next it needs to be marked executable.
sudo chmod +x /usr/local/bin/dsnet
dsnet needs a configuration file to function. In here keys and network
information is stored as well as peer bindings. dsnet will generate a
configuration automatically with the
init command; the generated file can be
customised but is usable immediately as-is!
sudo dsnet init
Take a look at
/etc/dsnetconfig.json and edit it if desired. For a rundown of
what each field is, see
Once you’re happy, the wireguard interface needs to be brought up with the
command which will also
sync peers if you have any.
sudo dsnet up
Your wireguard server is now running, configured on its own randomly-generated
subnet. Next you’ll need to add some peers; this can be done with the
command. The add command will generate the keys and add the peer to the
wireguard server. It emits a wg-quick configuration file, which is compatible
with all GUI wireguard clients and the
wg-quick command itself.
sudo dsnet add banana > dsnet-banana.conf
Here’s the add command in action:
The client peers and the server can now talk to each other via the assigned IP
address. By default, only traffic pertaining to the VPN peers is routed via the
VPN. To route the entire internet,
0.0.0.0/0 needs to be added to the
Networks list in the dsnet config file before a
sync after enabling kernel
IP forwarding and the appropriate masquerading (NAT) iptables rules. Check out
this Arch linux wiki
article for a good
guide, applicable to any distribution.
For further information about running a wireguard dsnet server, see https://github.com/naggie/dsnet/.
Sending configuration to clients
Given the configuration files contain the shared and private keys, the configuration files are very sensitive. For this reason, I use ffsend which is a cli client for Firefox send, a reasonably secure file sending system which is effectively client-less – the recipient just needs a web browser or ffsend. Make sure you use a password and send it over a separate link.