WireGuard® is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPsec, while avoiding the massive headache. It intends to be considerably more performant than OpenVPN. WireGuard is designed as a general purpose VPN for running on embedded interfaces and super computers alike, fit for many different circumstances.

www.wireguard.com

Installing Wireguard

Installing Wireguard is fairly simple. Just run the following commands to add the PPA and then install wireguard

sudo add-apt-repository ppa:wireguard/wireguard
sudo apt install wireguard

The main WireGuard configuration directory can be found at /etc/wireguard. This will be where we are creating the config files. For the purpose of this install I will be generating all the certificates and storing them in a folder called keys.

Wireguard won’t be able to do much if we don’t allow packet forwarding through sysctl so run the followig to enable it:

sysctl -w net.ipv4.ip_forward=1

Configuring the Server

First off, we need to make a new directory to keep all of our keys

mkdir ~/keys
cd keys

Now to create our first key.

umaks 077
wg genkey | tee server-private | wg pubkey > server-public

This will have generated two files in the keys directory. One called server-public and the other being server-private. Next we will need to create the configuration file for the server.

[Interface]
Address = 10.0.0.10/24
SaveConfig = true
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens18 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens18 -j MASQUERADE
ListenPort = 51820
PrivateKey = <paste server-private here>

At this point we can start the server with the following command:

sudo wg-quick up wg0

If you now run ifconfig you should see a new wg0 interface with the address you specified in the config file (10.0.0.10) You can also run sudo wg to see the interface:

interface: wg0
  public key: <your server-public here>
  private key: (hidden)
  listening port: 51820

Lastly, we want WireGuard to start when we boot the server so enable the startup script like so:

sudo systemctl enable wg-quick@wg0

Creating Clients

Linux

When configuring a WireGuard client the setup is very similar to the server except that the client has less configuration options as all it is required to do is connect to the WireGuard server on our host. We can generate two more certificates for our Linux client on the server:

cd ~/keys
umaks 077
wg genkey | tee linux-private | wg pubkey > linux-public

First the server config (/etc/wireguard/wg0.conf). Below the initial config we need to add a peer.

[Peer]
PublicKey = <your linux-public here>
AllowedIPs = 10.0.0.20/32

Next the client configuration. WireGuard must also be installed on the Linxu machine as detailed above. Edit the /etc/wireguard/wg0.conf and place the following content in it:

[Interface]
Address = 10.0.0.20/24
DNS = 1.1.1.1
SaveConfig = true
ListenPort = 42019
FwMark = 0xca6c
PrivateKey = aIpfPhQFoFsJwkHl68YyXipQKoEhVK6bXVYNXB9gLnc=

Android

Setting up Wireguard on the Android app is pretty straightforward. It is similar to creating the config file taht we used on the linux client, with the exception of a GUI instead of the terminal.

First up, generate a pair of keys for the phone.

cd ~/keys
umaks 077
wg genkey | tee phone-private | wg pubkey > phone-public

You should be presented with a screen that looks a little bit like this when opening the app: Android Wireguard Interface

Fill in the following details:

FieldValue
NameWhatever you want
Private Key< phone-private >
Addresses10.0.0.30/24
DNS Servers1.1.1.1

This will tell the Wireguard client to use the address 10.0.0.30 so that when it is connected to the server this is the address it will receive. Next up there needs to be a peerfor the client to connect to. This is our server.

FieldValue
Public Key< server-public >
AllowedIPs0.0.0.0/0
EndpointIP Address of the server

The server configuration is identical to setting up another peer. Just change the values.

[Peer]
PublicKey = < phone-public>
AllowedIPs = 10.0.0.30/32

That’s all the configuration required. So go ahead and test the connection.

Configuration Explained

For me this is where most of the online tutorials failed. They didn’t explain what the config file above was actually doing, line by line. So here it is:

Server Configuration

Address = 10.0.0.10/24

  • The address and subnet of the WireGuard server. The address is 10.0.0.10
  • The server is able to talk to all the client within the range 10.0.0.1 to 10.0.0.255

SaveConfig = true

  • Saves the current configuration of Wireguard to the file when the server is stopped and started. Ths is useful when editing the server with commands on the fly as when stopped the server will update it’s configuration.
  • Be wary though as changes will overwrite the contents of the file. If you edit the config file, then restart the server, the file edits will be lost

PostUp = ...

  • When the server is started, these commands are run to edit the iptables of the host.
  • It creates a ‘bridge’ between the two networks so that clients connecting to the 10.0.0.0/24 network can reach the network on interface ens18.
  • The ens18 network can access the internet, therefore, the clients connecting are also able tot access the wider internet through this network.

PostDown = ...

  • This removes the iptables rules created when the server starts.

ListenPort = 51820

  • The port which WireGuard will listen on

PrivateKey = <server-private

  • The private key of the server