Goodbye OpenVPN, hello Wireguard

Published 2020-06-06 on Yaroslav's weblog. Last edited 2021-03-28

I had been using OpenVPN for quite some time for my internet privacy purposes. However, I recently decided to switch to Wireguard. I am going to layout the reason why I chose to do it, and how I setup the Wireguard VPN for my purposes. I had been meaning to write about this for some time. Unfortunately, I have been quite busy finishing my last year of university.

I had heard about this new VPN thing-y called Wireguard last year and how it is supposed to be so much better than other VPN technologies such as IPsec and OpenVPN. It sounded nice to me and all, but it still wasn't considered stable back then, and I really didn't feel like switching when I had a setup that "just works™".

But then, something happened. My then hosting provider decided to cancel their VPS hosting plans, so I had to migrate everything that I had on my VPS to a new hosting provider, which included this site and my VPN. Also by this time, the stable release of Wireguard had been release, and the kernel module added to upstream. When I was in the process of migrating to my new VPS, I actually started to setup OpenVPN first, but some things had changed since the last time I had setup OpenVPN, and I didn't really want to deal with OpenVPN at this point. That's when I remembered about Wireguard. Good timing, if I do say so myself.

I have been using Wireguard for over a month now, and I have to say, I am really happy with it. It really is better than OpenVPN. The main advantages that Wireguard has over OpenVPN for me are the following:

  • It is so much easier to setup. No need to mess around with certificates.
  • Adding new clients or peers is also much easier and straightforward.
  • Latency and speed are slightly better than OpenVPN, especially latency. It might not be such a big difference, but I no longer feel the need to turn off my VPN when videoconferencing.
  • It brings up the network interface(s) much faster than OpenVPN.
  • It consumes less resources.
  • I had to disconnect and manually reconnect OpenVPN every time I resumed my computer from sleep or when I changed networks. With Wireguard, not anymore. It has a built-in roaming feature, so it doesn't matter if I suspend my computer, after waking up it "keeps" the connection for me, the same when I, for example, disconnect from WiFi and connect to ethernet, etc.

If these advantages haven't convinced you yet, I don't know what will.

Set up instructions

There are some things that are worth keeping in mind while setting up Wireguard. One of them is that unlike other VPN protocols, like OpenVPN, there is no server and client per se. There are just peers. Of course, that doesn't mean that you cannot use Wireguard like you would use OpenVPN, quite the contrary. It just means there is more flexibility and that you need to configure the peer that you're going to use as a server, such that it tunnels all the internet traffic it receives from the other peers and reroutes it.

Before setting up Wireguard, you'll need to install it on each peer. Check out this link on how to install Wireguard on your system: https://www.wireguard.com/install/

Server configuration

Before setting up Wireguard, you might want to setup a firewall such as ufw. After installing Wireguard and setting up your firewall, it's time to create a new profile for your connection.

First, as root, change to the /etc/wireguard/ directory.

You'll need to create a private key, and from that private key you should get the public key for your clients.

Generating a private key is as simple as this:

wg genkey

Then you'll need to create the profile, for that create file wg0.conf with the following contents:

[Interface]
Address = 10.0.0.1/24
Address = fd86:ea04:1115::1/64
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE
ListenPort = 51820
PrivateKey = <server private key>

You should put the private key that you generated before in the wg0.conf file in the "PrivateKey" field.

Now is a good time to get the public key. It would be convenient to have it saved in a file so that you can easily retrieve in the future when you need to add new peers:

echo "<server private key>" | wg pubkey > wg0.pubkey

If you already have setup a firewall on your server, don't forget to allow connections on the port being used by Wireguard. For example, for ufw you would run the following:

ufw allow 51820/udp

Now you can bring up your Wireguard tunnel by using this command:

wg-quick up wg0

You can make sure that it's running by entering:

wg show

However, if you want to bring up your Wireguard VPN tunnel every time your server restarts, you might prefer to manage your connection with systemd. First we have to bring down the tunnel we just brought up:

wg-quick down wg0

And now we can enable and start our respective systemd service:

systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0

Since in this configuration we want to be able to forward all of the peers' traffic through the VPS, we need to enable packet forwarding in the kernel by adding or uncommenting the following lines to /etc/sysctl.conf, or creating a new file in /etc/sysctl.d/ with these lines:

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

After adding them, to immediately load the config we run

sysctl --system

Client configuration

The configuration for the client side of things is pretty similar to the server side of things, since after all, to Wireguard there is no server or client.

You can save your Wireguard profile in the same directory as in the server, i.e. /etc/wireguard/. However, I prefer to keep it inside my home directory (e.g. ~/docs/wireguard), since I want to manage my VPN connection on my client machine by using NetworkManager. The client profile should look something like this:

[Interface]
Address = 10.0.0.2/24
PrivateKey = <client private key>
ListenPort = 51820
DNS = 1.1.1.1

[Peer]
PublicKey = <server public key>
AllowedIPs = 0.0.0.0/0
Endpoint = <server IP>:51820

Back on the server, append an entry for your client device to the end of the wg.conf file:

[Peer]
PublicKey = <client public key>
AllowedIPs = 10.0.0.2/32

Now you have to restart the service on the server, for example:

systemctl restart wg-quick@wg0

After that you can connect your client machine to the server using the Wireguard tunnel. You can use the wg-quick up wg0 command, but as I mentioned before, I want to manage the VPN with NetworkManager. For that you'll first need to import the profile into NetworkManager:

nmcli connection import type wireguard file $PROFILE_LOCATION

After importing the profile you can bring up the tunnel by issuing the following command (note: the connection will be called "wg0" if the filename of your profile was "wg0.conf"):

nmcli connection up wg0

You can bring it down by issuing the following command:

nmcli connection down wg0

I should say that by default NetworkManager will connect to the VPN each that you reboot. If you want to change this or any other setting check man nmcli and man nm-settings.

Setting it up on your phone or other devices

If you want to connect to your VPN server from other devices, you just have to basically make a new profile the same way you did in the previous section. Just keep in mind that you need to generate a new private/public key pair for each new profile, and that each peer (including your server) such have a different IP address assigned.

If you have an Android phone, after making the profile for your phone and adding the appropriate entry in your server's config file, you can then copy that file to your phone and import it in the Wireguard app. Or even better, you can make a QR code of the profile file, and then import that file using the QR code function of the Wireguard app.

To generate a QR code of the profile app you can use the command line program qrencode, like so:

qrencode -t ansiutf8 -r $PROFILE_LOCATION

After that a QR code should appear on your terminal window. It should look similar to this:

QR code example

Final words

In this post I described how to setup a Wireguard VPN in which one of the peers works as the server, redirecting all internet traffic from all of the other peers through itself. While this is the configuration that most suits my needs, and probably also of most people that see a VPN as a privacy tool first and foremost, there are other possible configurations of Wireguard.

You should take a look at the official Wireguard site.

© 2018—2024 Yaroslav de la Peña Smirnov.