How to setup WireGuard on your Ubuntu 20.04 server

What is WireGuard?

WireGuard is an simple yet fast and modern VPN that utilizes state-of-art cryptography while aiming to be faster, simpler and more useful than IPsec. You can use this tutorial as a guide to help you with the installation and configuration of your WireGuard server and Client.

Step 1: Installing WireGuard

$ sudo apt update
$ sudo apt install wireguard

Step 2: Generating the private key

$ wg genkey | sudo tee /etc/wireguard/private.key

Generating the public key

$ sudo cat /etc/wireguard/private.key | wg pubkey | sudo tee /etc/wireguard/public.key

Step 3: Choosing IPv4 and (or) IPv6 Addresses

You will need to choose a IP range. In this example we will be using the 192.168.0.0 - 192.168.255.255 range.

Step 4: Creating the WireGuard Server Configuration File

Open the following file with your text editor of choice. In this example we will use nano.

$ sudo nano /etc/wireguard/wg0.conf

Write the following.

[Interface]
PrivateKey = serves_generated_private_key
Address = 192.168.1.1/24
ListenPort = 51820
SaveConfig = true

Save the file.

Step 5: Adjusting the server network configuration. To configure forwarding we need to add a line to the /etc/sysctl.conf file.

$ sudo nano /etc/sysctl.conf

Add the following to the bottom of the file.

net.ipv4.ip_forward=1

If you are using IPv6 you can add the following to the bottom of the file.

net.ipv6.conf.all.forwarding=1

To read and load the new values of your current terminal session run the following command.

$ sudo sysctl -p

Output:

net.ipv4.ip.forward = 1

or

net.ipv6.conf.all.forwarding = 1

Depending on your choice of configuration.

Step 6: Configuring the servers firewall.

We need to find our public network interface of the server. We can do that by running the following command.

$ ip route list default

Output

default via XXX.XXX.XXX.XXX dev eth0 onlink

Where eth0 is the interface of our public network

We are going to add this interface to the ip table rule.

Open the config file.

$ sudo nano /etc/wireguard/wg0.conf

At the bottom of the file. Add the following:

PostUp = ufw route allow in on wg0 out on eth0
PostUp = iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
PostUp = ip6tables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
PreDown = ufw route delete allow in on wg0 out on eth0
PreDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
PreDown = ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

Depending on your IP choices you can remove the IPv4 or IPv6 rule.

The PostUp rules will run when the server start the virtual VPN tunnel. The PostDown rules will run when the server stops the virtual VPN tunnel.

The last part of the firewall configuration is to allow the traffic to and from the WireGuard UPD port. The port that we will need to open is 51820. If you have chosen another port make sure to use that one in the following command.

$ sudo ufw allow 51280/udp

After adding the rules we need to disable and re-enable UFW. Now it can load all the changes we made.

$ sudo ufw disable
$ sudo ufw enable

You can check if all the rules where correctly applied by executing the following command.

$ sudo ufw status

Output

To                         Action      From
--                         ------      ----
51820/udp                  ALLOW       Anywhere
OpenSSH                    ALLOW       Anywhere
51820/udp (v6)             ALLOW       Anywhere (v6)
OpenSSH (v6)               ALLOW       Anywhere (v6)

Step 7: Starting the WireGuard Server.

We can enable the WireGuard service to startup at boot.

$ sudo systemctl enable wg-quick@wg0.service

Lets start the service.

$ sudo systemctl start wg-quick@wg0.service

Make sure that the service is active an running. You can check this by running the following command.

$ sudo systemctl status wg-quick@wg0.service

Step 8: Configuring the WireGuard Client on MacOS and Windows 10 In this example we are using the Mac Os client

For MacOS you can download the application from the App Store. Just search for WireGuard. After you downloaded the application you can start it up.

In the left corner of your screen you will see a + sign. Click on it and choose the option Add Empty Tunnel.

enter image description here

You will see that it has generated a public and a private key for your client system. However, we still need to add some rules to the file. Add the following lines to your file.

[Interface]
PrivateKey = YOUR_CLIENTS_PRIVATE_KEY
Address = 192.168.1.10/24
DNS = 8.8.8.8, 8.8.4.4

[Peer]
PublicKey = YOUR_SERVERS_PUBLIC_KEY
AllowedIPs = 0.0.0.0/0
Endpoint = YOUR_SERVERS_WAN_IP:51820

It should looke something like this.

enter image description here

Give the file a name and click save. You might get a message saying "WireGuard" Would like to Add VPN Configurations Make sure to press Allow.

enter image description here

Now back to the server. Run the following command to let the server now who the client is.

$ sudo wg set wg0 peer YOUR_CLIENTS_PUBLIC_KEY allowed-ips 192.168.1.10

Now activate the tunnel on your client device and test the connection. You can test the connection by pinging from your server to your client and back.