I wanted to give Wireguard a try as a VPN solution so I spent a few minutes setting up a server on Hetzner and giving it a go. Long story short, it worked well and was straightforward but technical to set up and configure.

First thing was to set up a server on Hetzner. For this, I used the hcloud cli tool. hcloud makes it really easy to set up servers and other stuff from the command line which IMHO is a just easier than clicking-and-clucking through a web GUI. Anyway, I set up a small Ubuntu 20.04 system with the following:

$ hcloud server create --name wgvpn --image ubuntu-20.04 --type cx11 --ssh-key id_hetzner

id_hetzner is an SSH key that I’ve created on my laptop and registered with Hetzner so I can create servers that use that key for authentication.

After the server was up, I logged into it using my private key and got to work. I pieced together the following steps to do the configuration from the Wireguard documentation and a few things I found here and there on the interwebs.

Per my usual practice, the first thing I did was update the system:

# apt update && apt upgrade

Before we get started, it’s a good idea to set up a firewall. We’ll need a couple of ports to work with so let’s define those and get the firewall running:

# ufw allow 51820/udp
# ufw allow 22/tcp
# ufw enable

Seeing that no reboot was required, I went ahead with the installation of Wireguard, creation of the configuration directories and generation of the keys:

# apt install wireguard
# mkdir -p /etc/wireguard/keys; wg genkey | sudo tee /etc/wireguard/keys/server.key | wg pubkey | sudo tee /etc/wireguard/keys/server.key.pub

Once you’ve got the keys set up, you need to collect some information to create the configuration. You will need the default interface, your private server key and the IP address that you want to use.

If you don’t know the default interface (on Hetzner, it is eth0), you can get it with:

# ip -o -4 route show to default | awk '{print $5}'

The private key can be retrieved with:

# cat /etc/wireguard/keys/server.key

I picked 10.0.0.1/24 as my server address. You can use any internal IP range.

Armed with that, use a text editor (vim in my case) to create the config file:

# vim /etc/wireguard/wg0.conf

The wg0.conf file should look like:

[Interface] 
Address = 10.0.0.1/24 
ListenPort = 51820 
PrivateKey = YOUR_PRIVATE_KEY
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE 
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE 
SaveConfig = true

This configuration basically sets up your server interface and sets up the iptables so traffic gets routed properly to it’s destination.

After you get that configuration in, you are ready to fire it up:

# wg-quick up wg0 
[#] ip link add wg0 type wireguard 
[#] wg setconf wg0 /dev/fd/63 
[#] ip -4 address add 10.0.0.1/24 dev wg0 
[#] ip link set mtu 1420 up dev wg0 
[#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

If that’s all working, let’s set it up as a service in systemd:

# systemctl enable wg-quick@wg0

To be useful as general purpose VPN, we want to edit the /etc/sysctl.conf to allow for packet forwarding. Open the configuration file and uncomment the line that says net.ipv4ip_forward=1. Run sysctl to reload the conf file and enable packet forwarding.

Lastly, get the public key so you can use it to configure the client. You can do that with:

# wg show wg0 public-key

Now, we move on to the client configuration. I’m running Linux Mint 19.3 on my laptop, so I needed to install a couple of things first:

$ sudo apt install wireguard
$ sudo apt install resolvconf

Next, I set up the configuration for the VPN connection:

$ sudo -i
# cd /etc/wireguard
# umask 077
# wg genkey > private-key
# wg pubkey > public-key < private-key

That gets our private and public keys all set up on the client. Now, create the /etc/wireguard/wg0.conf file to contain the following:

 [Interface]
 Address = 10.0.0.2/24
 PrivateKey = YOUR_CLIENT_PRIVATE_KEY
 
 [Peer]
 PublicKey = YOUR_SERVER_PUBLIC_KEY
 AllowedIPs = 0.0.0.0/0
 Endpoint = YOUR_SERVER_IP_ADDRESS:51820

The last configuration step you need to do is register the client on the server. Go back to the server and do the following:

# wg set wg0 peer YOUR_CLIENT_PUBLIC_KEY allowed-ips 0.0.0.0/24

On the client, you can run:

$ sudo wg-quick up wg0

To make sure it’s working, open a web browser on the client and find your ip address. My laptop is now in Nurenberg, Germany or at least the Internet thinks it is.