How to Set Up WireGuard VPN on Ubuntu 20.04

WireGuard is an open-source and security-focused virtual private network designed for simplicity and ease of use. It supports different operating systems including, Linux, macOS, Windows, BSD and Android. It is a simple and general purpose VPN that can be easily deployed on small devices to high-end servers. It is a point to point VPN server instead client-server model. It uses a public key exchange mechanism to authenticate client.

If you are looking for a lightweight and fast VPN then the WireGuard VPN is the best choice for you. In this tutorial, we will show you how to install the WireGuard VPN server and client on Ubuntu 20.04.

Prerequisites

  • Two server running Ubuntu 20.04 server.
  • A root password is configured on both server.

Getting Started

First, it is recommended to update your system packages to the latest version. You can update them with the following command:

apt-get update -y

Once all the packages are updated, you will need to install the Iptables in your system. You can install it with the following command:

apt-get install iptables -y

Once the installation is finished, you can proceed to the next step.

Install WireGuard VPN Server

By default, the WireGuard package is available in the Ubuntu 20.04 default repository. You can install it by running the following command:

apt-get install wireguard -y

Once the WireGuard package has been installed, you can proceed to the next step.

Configure WireGuard Server

WireGuard works by exchanging public keys between each device in the WireGuard network. So you will need to create a public and private key in the server.

WireGuard provides the wg and wg-quick command-line utility to create a key and manage the interfaces.

You can create both public and private key using the following command:

wg genkey | tee /etc/wireguard/privatekey | wg pubkey | tee /etc/wireguard/publickey

Once both keys are created, you can check them with the following command:

ls /etc/wireguard

You should see the following output:

privatekey  publickey

You can display the content of the private key with the following command:

cat /etc/wireguard/privatekey

You should see the following output:

4M1l65NIaoR2+fQ6xVnIdwj6iVjsSPDkEMuzVnbFh3A=

You can display the content of the public key with the following command:

cat /etc/wireguard/publickey

You should see the following output:

00Jsbppv/gVMy6oHMfFZ+T/eEFBAWVbiZo33HjQBSU4=

Next, you will need to create a network interface for WireGuard. You can create it with the following command:

nano /etc/wireguard/wg0.conf

Add the following lines:

[Interface]
Address = 10.0.0.1/24
SaveConfig = true
ListenPort = 51820
PrivateKey = server-private-key
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

Save and close the file when you are finished.

Where:

  • Address : A private IP address for wg0 interface.
  • ListenPort : Specify the listening port of WireGuard.
  • PrivateKey : A privatekey stored in the file /etc/wireguard/privatekey.
  • PostUp : Specify the command that allows traffic to leave the server and give the VPN clients access to the Internet. Also replace the eth0 with your network interface name.

Next, set proper permission to the privatekey and wg0 file.

chmod 600 /etc/wireguard/{privatekey,wg0.conf}

Next, enable the wg0 interface by running the following command:

wg-quick up wg0

You should get the following output:

[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.0.0.1/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

You can also start the WireGuard service using systemd as shown below:

systemctl start [email protected]

Next, enable the WireGuard service to start at system reboot with the following command:

systemctl enable [email protected]

Next, verify the status of the WireGuard service with the following command:

systemctl status [email protected]

You should get the following output:

? [email protected] - WireGuard via wg-quick(8) for wg0
     Loaded: loaded (/lib/systemd/system/[email protected]; disabled; vendor preset: enabled)
     Active: active (exited) since Thu 2020-12-10 11:42:14 UTC; 7s ago
       Docs: man:wg-quick(8)
             man:wg(8)
             https://www.wireguard.com/
             https://www.wireguard.com/quickstart/
             https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8
             https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8
    Process: 2173 ExecStart=/usr/bin/wg-quick up wg0 (code=exited, status=0/SUCCESS)
   Main PID: 2173 (code=exited, status=0/SUCCESS)

Dec 10 11:42:14 ubuntu2004 systemd[1]: Starting WireGuard via wg-quick(8) for wg0...
Dec 10 11:42:14 ubuntu2004 wg-quick[2173]: [#] ip link add wg0 type wireguard
Dec 10 11:42:14 ubuntu2004 wg-quick[2173]: [#] wg setconf wg0 /dev/fd/63
Dec 10 11:42:14 ubuntu2004 wg-quick[2173]: [#] ip -4 address add 10.0.0.1/24 dev wg0
Dec 10 11:42:14 ubuntu2004 wg-quick[2173]: [#] ip link set mtu 1420 up dev wg0
Dec 10 11:42:14 ubuntu2004 wg-quick[2173]: [#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Dec 10 11:42:14 ubuntu2004 systemd[1]: Finished WireGuard via wg-quick(8) for wg0.

You can also check the status of the wg0 interface with the following command:

wg show wg0

You should get the following output:

interface: wg0
  public key: 00Jsbppv/gVMy6oHMfFZ+T/eEFBAWVbiZo33HjQBSU4=
  private key: (hidden)
  listening port: 51820

You can get the IP address status of wg0 interface with the following command:

ip a show wg0

You should get the following output:

13: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 10.0.0.1/24 scope global wg0
       valid_lft forever preferred_lft forever

Once you are finished, you can proceed to the next step.

Enable IP Forwarding

Next, you will need to enable the IP forwarding in your server to route packets between VPN clients and the Internet. You can enable it by editing the file /etc/sysctl.conf:

nano /etc/sysctl.conf

Change the following line:

net.ipv4.ip_forward=1

Save and close the file then run the following command to apply the configuration changes:

sysctl -p

Once you are finished, you can proceed to the next step.

Install and Configure WireGuard Client

First, you will need to install the WireGuard package on the client machine. You can install it with the following command:

apt-get install wireguard -y

After installing WireGuard package, create a privatekey and publickey with the following command:

wg genkey | tee /etc/wireguard/privatekey | wg pubkey | tee /etc/wireguard/publickey

Once both keys are created, you will need to create a new configuration file.

You can create it with the following command:

nano /etc/wireguard/wg0.conf

Add the following lines:

[Interface]
PrivateKey = client-private-key
Address = 10.0.0.2/24

[Peer]
PublicKey = server-public-key
Endpoint = server-ip-address:51820
AllowedIPs = 0.0.0.0/0

Save and close the file when you are finished.

Where:

  • Address : A private IP address for wg0 interface.
  • PrivateKey : Specify the private key on the client machine.
  • PublicKey : Specify the public key on the server machine.
  • Endpoint : Specify the IP address of server.
  • AllowedIPs : Specify the list of allowd IP address.

Next, you will need to add the client public key and IP address on the server machine.

On the server machine, run the following command to add both:

wg set wg0 peer client-public-key allowed-ips 10.0.0.2

Next, you will need to bring up the wg0 interface on the client machine.

On the client machine, run the following command to bring up the interface:

wg-quick up wg0

You should get the following output:

[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.0.0.2/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] wg set wg0 fwmark 51820

At this point, your client machine is connected to the WireGuard VPN server. You can check the connection status with the following command:

wg

You should get the following output:

interface: wg0
  public key: 3FXBDpAO4Vado1tDjLtVQt+JnOCa+W2piLeFYQ8KyB4=
  private key: (hidden)
  listening port: 38830
  fwmark: 0xca6c

peer: 00Jsbppv/gVMy6oHMfFZ+T/eEFBAWVbiZo33HjQBSU4=
  endpoint: 69.87.216.36:51820
  allowed ips: 0.0.0.0/0
  latest handshake: 41 seconds ago
  transfer: 5.27 KiB received, 12.97 KiB sent

Conclusion

Congratulations! you have successfully installed and configured the WireGuard VPN server and client on Ubuntu 20.04 server. Now, the traffic from your client machine should be routed through your server machine. You can now surf the internet anonymously and keep your data private.

Share this page:

Suggested articles

3 Comment(s)

Add comment

Comments

By: curiousadmin at: 2020-12-20 20:25:41

Thank you for the how-to. Could you or anyone from the readers provide any configuration tips on non-NAT setup? I would like to have a setup where the traffic towards the Internet is not routed via 10.0.0.1 but via local gateway but all the traffic in the 10.0.0.0/24 network is still routed via the VPN. Ie. making it very large/far reaching LAN network.

By: ustoopia at: 2020-12-25 23:11:45

Great tutorial. Perhaps you could add that in the settings for peers that using 0.0.0.0 will route all traffic over the VPN but there are options to not have this happen by using for example 10.0.0.2 as peer address. [Peer] PublicKey = server-public-key Endpoint = server-ip-address:51820 AllowedIPs = 0.0.0.0/0

By: Victor at: 2021-01-27 18:07:12

Great tutorial thank you