Set up a modern point-to-point VPN with WireGuard

WireGuard logo

WireGuard is a new, simple, secure and fast way to set up a point-to-point VPN between two machines. Cryptography naturally adds an overhead to the communication, so it is important its implementation is as fast as possible. WireGuard works as a Kernel module to provide faster performance compared to more popular solutions such as OpenVPN.

Good things to know about WireGuard before you start

WireGuard:

  • hasn’t been audited yet.
  • is still in its early stages and it is subject to change.
  • uses state-of-the-art cryptography.
  • uses asymmetric key cryptography just like SSL.
  • doesn’t have (yet) many options; as such it is dead-simple to configure.
  • used to run on Linux only but it now runs on many other platforms.
  • is faster than OpenVPN and other userland solutions because it runs inside the kernel.
  • isn’t yet merged into mainline… it uses DKMS for the time being.

Let’s start: Installation

Important
I take absolutely NO responsibility of what you do with your machine; use this tutorial as a guide and remember you can possibly cause data loss if you touch things carelessly.

This guide will show you how to install WireGuard on Ubuntu and CentOS, once installed the commands are the same for every platform.

Before starting you need to make sure you have the kernel headers for your current kernel:

UbuntuCentOS

Now that you installed the kernel headers you can proceed with the installation of the module. If you encounter problems from here on, make sure you have the right headers for your current kernel.

UbuntuCentOS

Generating a public/private key pair

In order to work, WireGuard requires a public/private key pair. You should repeat this step on each machine you want to connect.

Terminal

Adding a new interface

Now we will add a WireGuard interface. These interfaces are just like any other physical interface, except all the traffic sent through the interface will be encrypted. Each machine should have a WireGuard interface and should be assigned a unique private IP address. The IP address used for this purpose isn’t the same as the private IP address you already have.

Terminal

Replace 172.16.0.1/24 with your desired IP address:

Setting up peers

For reference, we will use the following table to clarify the process of setting up peers.

Machine namePublic IPWG IPPortPublic KeyPrivate Key
Host 1203.0.113.15/24172.16.0.1/2451820Key1Secret1
Host 2203.0.113.172/24172.16.0.2/2447890Host2Secret2
Host 3203.0.113.30/24172.16.0.3/2471200Wire3Secret3

In this step we will set up the connection between the machines. Now pay attention: the following steps must be repeated for each machine you want to connect.

Terminal

Replace PEER_PUBLIC_KEY with the one you want to connect to (not the one on the machine you are on). Then replace PEER_WG_INTERFACE with a matching rule that allows the communication from the other endpoint (e.g. /24 or /32 if you want only one IP allowed). Then replace PEER_IP:PEER_PORT with the public IP and port of the other machine you’re connecting.

For example: if we wanted to connect Host1 to Host 3 we would do:

  • On Host 1:
  • On Host 3:

Once done you might need to open the aprropriate ports through the firewall. You can follow these guides:

Flipping the switch

At this point everything should work, it is just a matter of enabling the interface (on each machine):

Terminal
You can now verify the network stack by pinging the interface address from the same machine. If you get a response you can now try pining the other associated machines, everything should work. If it doesn’t you probably have misconfigured the peer section, I suggest you to rev.

You can now review the configuration by using the following command:

Terminal

Storing permanent configuration

If everything worked find you can now store your configuration in a configuration file! Without this step you will need to repeat the procedure every time you reboot the machine, and that’s not very useful. Fortunately it is just a simple command:

Terminal

By default the IP configuration is handle on the interface itself and not by WireGuard. This means every time you will bring up the interface using the configuration file the interface won’t have an IP address. This is an undesired behavior if you want to reboot and have your VPN up and running. In order to make it work you must add the highlighted line with the proper IP address (for each machine):

Terminal

Following the previous example. Open with your favorite text editor the file located at /etc/wireguard/wg0.conf and add the following line:

Starting WireGuard at boot

In order to start the interface at boot time, WireGuard comes with a handy systemd unit called wg-quick, so you can simply do:

Terminal

Following the previous example. Open with your favorite text editor the file located at /etc/wireguard/wg0.conf and add the following line:

Managing interfaces with wg-quick

In addition to the systemd unit, wg-quick is also a useful command to manage the state of an interface.

Conclusion

You now know how to install and configure WireGuard to create your own VPN. The software is under active development so it might not quite be ready for production, and above all it hasn’t been audited. But that’s sure to change in the future.

WireGuard has a lot of potential and it is still in the early stages. A Windows client is not yet available, but with its low footprint (about 4000 lines) and performance it could become a widely used software in routers. On top of that the installation procedure is simple compared to other VPN solutions like OpenVPN.

Image courtesy of mark | marksei

The following two tabs change content below.
The IT guy with a little boredom look in his eyes, fond of computers since forever he now works as a freelancer in the IT and shares his experiences through this blog.

You may also like...