Set up a modern point-to-point VPN with WireGuard
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
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:
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.
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.
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.
Setting up peers
For reference, we will use the following table to clarify the process of setting up peers.
Machine name | Public IP | WG IP | Port | Public Key | Private Key |
---|---|---|---|---|---|
Host 1 | 203.0.113.15/24 | 172.16.0.1/24 | 51820 | Key1 | Secret1 |
Host 2 | 203.0.113.172/24 | 172.16.0.2/24 | 47890 | Host2 | Secret2 |
Host 3 | 203.0.113.30/24 | 172.16.0.3/24 | 71200 | Wire3 | Secret3 |
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.
For example: if we wanted to connect Host1 to Host 3 we would do:
- On Host 1:
$ sudo wg set wg0 peer Wire3 allowed-ips 172.16.0.0/24 endpoint 203.0.113.30:71200
- On Host 3:
$ sudo wg set wg0 peer Key1 allowed-ips 172.16.0.0/24 endpoint 203.0.113.15:51820
Once done you might need to open the aprropriate ports through the firewall. You can follow these guides:
- How to manage Ubuntu Firewall (like a boss)
- How to manage firewallD (on CentOS 7 and all the other distro)
Flipping the switch
At this point everything should work, it is just a matter of enabling the interface (on each machine):
You can now review the configuration by using the following command:
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:
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):
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:
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.
$ sudo wg-quick wg0 up # Enables the interface by using the config file /etc/wireguard/wg0.conf $ sudo wg-quick wg0 down # Removes the interface $ sudo wg-quick wg0 save # Saves the current settings to /etc/wireguard/wg0.conf
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.
- 2020 A year in review for Marksei.com - 30 December 2020
- Red Hat pulls the kill switch on CentOS - 16 December 2020
- OpenZFS 2.0 released: unified ZFS for Linux and BSD - 9 December 2020
When I try this command on Ubuntu 18.04 I get an error:
sudo ip link dev wg0 172.16.0.1/24
Command “dev” is unknown, try “ip link help”.
Sorry there was a typo, it should be ip link add dev … Fixed.
Hi, this should be sudo ip addr add dev wg0 172.16.0.1/24
You’re right, typo in the typo, I must be getting older.