Wireguard is a modern VPN protocol allowing secure and confidential communication between a network of peers. Wireguard is based on the concept of private-public key cryptography and a number of other modern cryptographic algorithms. Have a look at the wireguard white paper for more details.
Since Linux kernel version 5.6 (late March 2020) wireguard is an integral part of the Linux kernel. That means Linux distributions using a kernel >= 5.6 do not need to install any additional packages in order to support wireguard.
However, many Linux distributions of 2020 use an older Linxu kernel. In this case wireguard can be installed using the respective package manager.
Official client software for Windows and Android also exists, which is very neat from a cross platform perspective.
In the remainder of this post I will assume Ubuntu 18.04 is used (same for Ubuntu 20.04).
On Ubuntu or other Debian-based Linux distributions wireguard is most easily installed using apt:
sudo apt install wireguard
After installation of the wireguard package has completed the command line tools
wg-quick become available. Running them generally require root privileges.
$> wg --help Usage: wg <cmd> [<args>] Available subcommands: show: Shows the current configuration and device information showconf: Shows the current configuration of a given WireGuard interface, for use with
set: Change the current configuration, add peers, remove peers, or change peers
setconf: Applies a configuration file to a WireGuard interface addconf: Appends a configuration file to a WireGuard interface syncconf: Synchronizes a configuration file to a WireGuard interface
genkey: Generates a new private key and writes it to stdout genpsk: Generates a new preshared key and writes it to stdout pubkey: Reads a private key from stdin and writes a public key to stdout
You may pass--help' to any of these subcommands to view usage.
It may additionally be necessary to also install the Linux headers for your system:
$> sudo apt install linux-headers-$(uname -r)
On Linux kernels < 5.6 the following package is also required:
$> sudo apt install wireguard-dkms
The initial configuration of wireguard consists of two steps: generating a key pair for each peer (device) and setting up a configuration file.
A new private key for wireguard can be generated by the following command, preferably run from within
/etc/wireguard for safety:
(optional) $> cd /etc/wireguard $> wg genkey > peer1-private.key
Using the private key a public key can be generated very similarly:
$> wg pubkey < peer1-private.key > peer1-public.key
Or doing both in a single command:
$> wg genkey | tee > peer1-private.key | wg pubkey > peer1-public.key
The two files
peer1-private.key and peer1-
public.key now contain a pair of cryptographic keys for the the device
The same has to be repeated for every other device which is to take part in the communication protected by wireguard.
So on another device
peer2 a separate key pair will be generated:
peer2:$> wg genkey | tee > peer2-private.key | wg pubkey > peer2-public.key
Next a new configuration file for the wireguard interface is required. The configuration files for wireguard are located in
/etc/wireguard. A configuration file has the same name as its respective wireguard interface followed by the
.conf extension. So for a wireguard interface which is named
wg0 the configuration file will be
Let’s create a new configuration file for device
peer1 and step through it for some explanation.
$> sudo cat /etc/wireguard/wg0.conf [Interface] PrivateKey = cOk8kLJj8E/CwwoR2N8YB057aZCxD6V0KX8oj9TTg2I= Address = 10.10.10.1/24 [Peer] PublicKey = YFd92senCfTK05JhOue2rcwn+9s6ibCFEF4WWBzvfHM= AllowedIPs = 10.10.10.2/32 Endpoint = 18.104.22.168:5789
The first block defines our local interface
wg0, the private key (
peer1-private.key) for it and the IP address (and subnet) of this interface. Note that for this simple setup a separate subnet should be used, so avoid any collision with the IP address ranges already in use on your local network!
The next block defines a peer by listing it’s public key (
peer2-public.key), the IP address the peer uses in the wireguard subnet and the so called
[Endpoint] IP address. The endpoint is the public IP address and port on which the peer can be reached over the internet.
[Peer] block must be added for every additional peer we want to communicate with.
On the second peer device (
peer2) the same steps as above must be repeated. A key pair must be generated and new configuration file must be created. Of course the configuration file on
peer2 must use peer2’s private key in the
[Interface] block and
peer1‘s public key and IP address in the
[Peer] block. The configuration file on
peer2 should look like the following:
peer2:$> sudo cat /etc/wireguard/wg0.conf [Interface] PrivateKey = cOk8kLJj8E/CwwoR2N8YB057aZCxD6V0KX8oj9TTg2I= Address = 10.10.10.2/24 [Peer] PublicKey = gP3aW0CUGqWLx5QrpuZKdWGh9VPntMDN5jwDtSUaUU4= AllowedIPs = 10.10.10.1/32
In case a peer is located at a different site behind a firewall it may be feasible to add the persistent keepalive option to the configuration file. This makes sure that keepalive packets are send to the wireguard endpoint in regular intervals if no data packets have been sent for a while.
The keepalive packets ensure that a connection through the firewall will remain open. Otherwise the firewall may close the port which was used for communications between the peer and the endpoint, after no traffic was seen going through that port for some time. If that happens, a new connection can only be initiated by the peer, but the endpoint will not be able to reach the peer behind the firewall anymore.
PersistentKeepalive = 25
Setting up a secure communication channel with wireguard is simple yet efficient. The main work is probably shuffling the public keys around when more than two peers are present. The simple setup that was shown above allows secure communication between known peer devices.
More advanced settings like configuring iptables for DNS routing may be shown in another article. That’s it for now.