How to set up a wireguard VPN in minutes with dsnet

May 2020 - 5 min read

TL;DR: Check out dsnet for an easy way to manage a wireguard VPN.

Background

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:

  1. A private VPN where I can network my machines with friends machines for gaming, file sharing, self-hosting etc
  2. 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.
  3. 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:

  1. 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.
  2. A way to add peers as fast as possible. Manually generating private/public/shared keys, manually allocating an IP and manually updating the main wg-quick server configuration file got tedious quickly.
  3. For the security model to be strong

dsnet

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.

How to set up a VPN with dsnet

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 (replace v0.6 with the latest version):

sudo wget https://github.com/naggie/dsnet/releases/download/v0.6/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 https://github.com/naggie/dsnet/#configuration-overview.

Once you’re happy, the wireguard interface needs to be brought up with the up 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 add 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:

dsnet add command and generated config. Note the questions are echoed to stderr such that redirecting the output to a file will omit the questions.
dsnet add command and generated config. Note the questions are echoed to stderr such that redirecting the output to a file will omit the questions.

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 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.


Thanks for reading! If you have comments or like this article, please post or upvote it on Hacker news, Twitter, Hackaday, Lobste.rs, Reddit and/or LinkedIn.

Please email me with any corrections or feedback.