Reading Time: 9 minutes

A Fast, Modern and Secure VPN Tunnel

Objective

In this tutorial we will learn what Wireguard is, what it is used for, how to install and configure it, and lastly, how to use it to it wisely. 

What is Wireguard? 

Wireguard is an open-source, dependable, advanced, VPN tunneling software you can install and use right now to create a secure, point-to-point connection to a server.

Note:
Update: The creators of Ubuntu 20.04 have decided to include a custom kernel in the newest version of Ubuntu which includes functionality for the WireGuard VPN service. WireGuard is now a part of the Universe repository so a third-party repository is no longer needed to install wireguard! You can add this software by using the following command: “apt-get install wireguard-dkms -y”

Prerequisites 

  • You should be logged in as a user with sudo privileges, or as the root user to install the Wireguard software on your system.
  • The Wireguard software is being installed on an Ubuntu 18.04 server.

Server Installation 

First, we will add the ppa:wireguard/wireguard repository. 

  root@host:~# add-apt-repository ppa:wireguard/wireguard  WireGuard is a novel VPN that runs inside the Linux Kernel. This is the Ubuntu packaging for WireGuard. More info may be found at its website, listed below.
 More info: https://www.wireguard.com/ Packages: wireguard wireguard-tools wireguard-dkms
 Install with: $ apt install wireguard  More info: https://launchpad.net/~wireguard/+archive/ubuntu/wireguard
 Press [ENTER] to continue or Ctrl-c to cancel adding it.
 Get:1 http://security.ubuntu.com/ubuntu bionic-security InRelease [88.7 kB]
 Hit:2 http://us.archive.ubuntu.com/ubuntu bionic InRelease
 Get:3 http://us.archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB]
 Get:4 http://repo.saltstack.com/py3/ubuntu/18.04/amd64/latest bionic InRelease [2126 B]
 Hit:5 https://deb.nodesource.com/node_10.x bionic InRelease
 Get:6 http://ppa.launchpad.net/wireguard/wireguard/ubuntu bionic InRelease [15.9 kB]
 Get:7 http://us.archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB]
 Get:9 http://repo.saltstack.com/py3/ubuntu/18.04/amd64/latest bionic/main amd64 Packages [3202 B]
 Hit:8 https://packages.cloud.google.com/apt kubernetes-xenial InRelease
 Get:10 http://us.archive.ubuntu.com/ubuntu bionic-updates/main i386 Packages [662 kB]
 Get:11 http://us.archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages [897 kB]
 Get:12 http://us.archive.ubuntu.com/ubuntu bionic-updates/universe i386 Packages [1012 kB]
 Get:13 http://us.archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages [1061 kB]
 Get:14 http://ppa.launchpad.net/wireguard/wireguard/ubuntu bionic/main i386 Packages [984 B]
 Hit:15 https://packages.cisofy.com/community/lynis/deb stable InRelease
 Get:16 http://ppa.launchpad.net/wireguard/wireguard/ubuntu bionic/main amd64 Packages [984 B]
 Get:17 http://ppa.launchpad.net/wireguard/wireguard/ubuntu bionic/main Translation-en [764 B]
 Fetched 3909 kB in 2s (1978 kB/s)
 Reading package lists... Done
 root@host:~# 

Next, we need to run an update to ensure our new repo is recognized and added to the database. 

root@host:~# apt-get update
Hit:2 http://repo.saltstack.com/py3/ubuntu/18.04/amd64/latest bionic InRelease
Hit:3 http://security.ubuntu.com/ubuntu bionic-security InRelease
Hit:4 http://us.archive.ubuntu.com/ubuntu bionic InRelease
Hit:5 http://ppa.launchpad.net/wireguard/wireguard/ubuntu bionic InRelease
Hit:6 http://us.archive.ubuntu.com/ubuntu bionic-updates InRelease
Hit:7 http://us.archive.ubuntu.com/ubuntu bionic-backports InRelease
Hit:1 https://packages.cloud.google.com/apt kubernetes-xenial InRelease
Hit:8 https://deb.nodesource.com/node_10.x bionic InRelease
Hit:9 https://packages.cisofy.com/community/lynis/deb stable InRelease
Reading package lists... Done
root@host:~#

Finally, we will install Wireguard using apt-get.

root@host:~# apt-get install wireguard
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
  dkms wireguard-dkms wireguard-tools
Suggested packages:
  menu
The following NEW packages will be installed:
  dkms wireguard wireguard-dkms wireguard-tools
0 upgraded, 4 newly installed, 0 to remove and 129 not upgraded.
Need to get 417 kB of archives.
After this operation, 2388 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://us.archive.ubuntu.com/ubuntu bionic-updates/main amd64 dkms all 2.3-3ubuntu9.7 [68.1 kB] 
Get:2 http://ppa.launchpad.net/wireguard/wireguard/ubuntu bionic/main amd64 wireguard-dkms all 1.0.20200330-1ubuntu1~18.04 [253 kB]
Get:3 http://ppa.launchpad.net/wireguard/wireguard/ubuntu bionic/main amd64 wireguard-tools amd64 1.0.20200319-0ppa1~18.04 [88.2 kB]
Get:4 http://ppa.launchpad.net/wireguard/wireguard/ubuntu bionic/main amd64 wireguard all 1.0.20200319-0ppa1~18.04 [7980 B]
Fetched 417 kB in 1s (325 kB/s)
Selecting previously unselected package dkms.
(Reading database ... 115256 files and directories currently installed.)
Preparing to unpack .../dkms_2.3-3ubuntu9.7_all.deb ...
Unpacking dkms (2.3-3ubuntu9.7) ...
Selecting previously unselected package wireguard-dkms.
Preparing to unpack .../wireguard-dkms_1.0.20200330-1ubuntu1~18.04_all.deb ...
Unpacking wireguard-dkms (1.0.20200330-1ubuntu1~18.04) ...
Selecting previously unselected package wireguard-tools.
Preparing to unpack .../wireguard-tools_1.0.20200319-0ppa1~18.04_amd64.deb ...
Unpacking wireguard-tools (1.0.20200319-0ppa1~18.04) ...
Selecting previously unselected package wireguard.
Preparing to unpack .../wireguard_1.0.20200319-0ppa1~18.04_all.deb ...
Unpacking wireguard (1.0.20200319-0ppa1~18.04) ...
Setting up wireguard-tools (1.0.20200319-0ppa1~18.04) ...
Setting up dkms (2.3-3ubuntu9.7) ...
Setting up wireguard-dkms (1.0.20200330-1ubuntu1~18.04) ...
Loading new wireguard-1.0.20200330 DKMS files...
Building for 4.15.0-72-generic
Building initial module for 4.15.0-72-generic
Building initial module for 4.15.0-72-generic
Done.
wireguard:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/4.15.0-72-generic/updates/dkms/
depmod...
DKMS: install completed.
Setting up wireguard (1.0.20200319-0ppa1~18.04) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
root@host:~#

Server Configuration

Enable Kernel Module

Next, because Wireguard operates as a kernel module, we need to enable is using the modprobe command. This will enable the Wireguard kernel module to be updated each time a new kernel is compiled. 

root@host:~# modprobe wireguard
root@host:~# 

We can now verify that the kernel module is active by running the following command.

root@host:~# lsmod | grep wireguard
wireguard             221184 0
ip6_udp_tunnel         16384 1 wireguard
udp_tunnel             16384 1 wireguard
root@host:~#

Key Creation

Now, we need to create a public and private key pair to secure the connection. We will begin by using the umask command to set the default permission settings of the key files.

As an aside, here is some additional information about the umask command. The umask command (or user file-creation mode mask), is used to determine the file permission settings for newly created files. It can also be used to control the basic or default file permission set on new files. It is usually expressed in a four-digit symbolic or octal values. Since we are going to be using umask to set the permissions to 077 on a new file, we want to outline how the permission settings can be calculated.

Wireguard also creates a standard network interface named wg0 and wg1 which function in a similar manner to eth0 or eth1. This allows us to work with those interfaces the same way we work with standard network interfaces using the ipconfig and ip commands. 

Set Permissions

First, to set the permissions on the new keys, we will use the following umask 077 command.

root@host:~  # umask 077  
root@host:~  #  

Next, we will generate the public and private keys needed to encrypt the data transmission.

 root@host:~  # wg genkey | tee privatekey | wg pubkey > publickey 

This will create and save the new keys to the current directory. In our case, since we ran the command while in the /root folder, our keys are stored there. To view the keys, we can use the cat command. (Please note: do NOT share these keys with anyone like we are here. These are only example keys.)

root@host:~  # cat privatekey  
YMJHJqjyQIuro9uVVp3rPoSvD9i92Dw2r2mAt121q3A=  
root@host:~  # cat publickey  
Y5HkgP1jRSM9+Ti9CfpKfF/ZSZlQ0GFrRo3tlv+35gc=  
root@host:~  #

Create Configuration File

Now, we need to create a configuration file for the wg0 interface. We will initially cd into the /etc/wireguard folder and then touch the file using the following command.

root@host:~# cd /etc/wireguard/  
root@host:/etc/wireguard# ll  
total 8  
drwx------   2 root root 4096 Mar 20 07:00 ./  
drwxr-xr-x 102 root root 4096 Apr  1 14:08 ../  
root@host:/etc/wireguard# touch wg0.conf  
root@host:/etc/wireguard#  

The next step is to use vim to edit the wg0.conf file. 

root@host:/etc/wireguard# vim wg0.conf 

Now, we need to copy the following basic configuration settings and copy them into our conf file. Then, we will add the selected IP addresses our interface will use, and place them into the configuration file.

[Interface]  
  PrivateKey = YMJHJqjyQIuro9uVVp3rPoSvD9i92Dw2r2mAt121q3A  
 Address = 10.10.0.1/24 
 Address = fd86:ea04:1111::1/64 
  SaveConfig = true  
  PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ens3 -j MASQUERADE  
  PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o ens3 -j MASQUERADE  
  ListenPort = 51820 

The above terms from the wg0.conf file are defined below.

  • PrivateKey: This field contains the private key generated above.
  • Address : The two IP address values defines the private IPv4 and IPv6 addresses for the WireGuard server. All peers in the VPN network should have a unique value for this setting.
  • SaveConfig : This value, unlike other VPN servers, denotes that Wireguard does not need to restart or reload in order for clients to connect to it. We simply need to use the wg command to add our peers, and they will be able to connect directly. Because this setting is an “ in-memory ” operation, if we restart the server, our peers that were added will be removed. This is where the SaveConfig setting comes into play. This value tells the wg-quick command to save any new peers that are added to our configuration file automatically.
  • PostUp / PostDown: This setting defines any additional steps which need to be run when the wg0 interface is enabled or disabled. In this case, the iptables command is used to denote the IP rules posed to let clients share the server’s main IPv4 or IPv6 address. These rules will clear as soon as the tunnel is dropped.
  • ListenPort : This setting specifies which port WireGuard will listen on for incoming connections.

If we choose to not include the firewall rules in our conf file, we can run the following sysctl command to enable port forwarding.

root@host:~# sysctl -w net.ipv4.ip_forward=1 

Now, we need to modify the permission setting on the wg0.conf file.

root@host:~# chmod -v 600 /etc/wireguard/wg0.conf  
  mode of '/etc/wireguard/wg0.conf' changed from 0644 (rw-r--r--) to 0600 (rw-------)  
root@host:~# 

Update Firewall Rules

Next, we need to allow SSH connections, open the WireGuard VPN port and finally, enable the firewall on the server.

root@host:/etc/wireguard# ufw allow 22/tcp  
 Rules updated 
 Rules updated (v6) 
 root@host:/etc/wireguard# ufw allow 51820/udp 
 Rules updated 
 Rules updated (v6) 
 root@host:/etc/wireguard# ufw enable 
 Command may disrupt existing ssh connections. Proceed with operation (y|n)? y 
 Firewall is active and enabled on system startup 
root@host:/etc/wireguard# 

To verify our settings, we can run the ufw status command.

root@host:/etc/wireguard# ufw status verbose 
 Status: active 
 Logging: on (low) 
 Default: deny (incoming), allow (outgoing), deny (routed) 
 New profiles: skip 
 To                         Action From 
 --                         ------ ---- 
 80,443/tcp (Nginx Full)    ALLOW IN Anywhere 
 22/tcp                     ALLOW IN Anywhere 
 51820/udp                  ALLOW IN Anywhere 
 80,443/tcp (Nginx Full (v6)) ALLOW IN    Anywhere (v6) 
 22/tcp (v6)                ALLOW IN Anywhere (v6) 
 51820/udp (v6)             ALLOW IN Anywhere (v6) 
root@host:/etc/wireguard#

Start the Wireguard Service

Now, we can start the Wireguard service using the following command. 

root@host:/etc/wireguard# cd 
root@host:~# wg-quick up wg0 
 [#] ip link add wg0 type wireguard 
 [#] wg setconf wg0 /dev/fd/63 
 [#] ip -4 address add 10.10.0.1/24 dev wg0 
 [#] ip -6 address add fd86:ea04:1111::1/64 dev wg0 
 [#] ip link set mtu 1420 up dev wg0 
 [#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ens3 -j MASQUERADE 
root@host:~#  
Note:
The “wg-quick” command is a handy command wrapper for several of the standard tasks used alongside the “wg” command. For example, we can enable or disable the wg0 interface using the following commands.
root@host:~#  wg-quick down wg0  
root@host:~#  wg-quick up wg0 

Next, we will enable the Wireguard service to restart automatically when the server boots.

root@host:~# systemctl enable wg-quick@wg0 
 Created symlink /etc/systemd/system/multi-user.target.wants/wg-quick@wg0.service → /lib/systemd/system/wg-quick@.service. 
root@host:~#  

Now, we can verify if the Wireguard service is running.

root@host:~# wg show  
  interface: wg0  
    public key: Y5HkgP1jRSM9+Ti9CfpKfF/ZSZlQ0GFrRo3tlv+35gc=  
    private key: (hidden)  
    listening port: 51820  
root@host:~# 

Also, we can check using our ifconfig command.

root@host:~# ifconfig wg0  
wg0: flags=209<UP,POINTOPOINT,RUNNING,NOARP>  mtu 1420  
inet 10.10.0.1  netmask 255.255.255.0  destination 10.10.0.1  
inet6 fd86:ea04:1111::1  prefixlen 64 scopeid 0x0<global>  
unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 1000 (UNSPEC)  
RX packets 0  bytes 0 (0.0 B)  
RX errors 0  dropped 0 overruns 0  frame 0  
TX packets 0  bytes 0 (0.0 B)  
TX errors 0  dropped 0 overruns 0  carrier 0 collisions 0  
root@host:~# 

Client Installation

The Wireguard client setup is very similar to the server setup in that the only difference is in the configuration file. There are several ways to add a peer (client) in Wireguard. 

Ubuntu Client Installation

First, we will need to set permissions, and then generate a keypair on the client. 

root@client:~  # cd /etc/wireguard 
root@client:~  # umask 077  
root@client:~  # wg genkey | tee privatekey | wg pubkey > publickey  

Create Configuration File

Now, we need to create a configuration file for the wg0 interface. We will first cd into the /etc/wireguard folder and then touch the file using the following command.

root@client:/etc/wireguard# ll  
  total 8  
  drwx------   2 root root 4096 Mar 20 07:00 ./  
  drwxr-xr-x 102 root root 4096 Apr  1 14:08 ../  
root@client:/etc/wireguard# touch wg0-client.conf  
root@client:/etc/wireguard# 

The next step is to use vim to edit our local wg0-client.conf file. 

root@client:/etc/wireguard# vim wg0-client.conf 

Once we have the file open in vim, we need to copy the following basic configuration settings and paste them into our new wg0-client.conf file. Then, we will add our selected IP addresses our interface will use. The settings must contain the server IP address as well as the DNS value and does not contain the ListenPort, PostUp, PostDown, and SaveConfig values.

[Interface] 
 Address = 10.200.200.2/32 
 PrivateKey = <insert client_private_key> 
 DNS = 10.200.200.1 

[Peer] 
 PublicKey = <insert server_public_key> 
 Endpoint = <insert vpn_server_address>:51820 
 AllowedIPs = 0.0.0.0/0 
 PersistentKeepalive = 21 

Finally, we want to secure the file, so we modify the permissions on the file using chmod.

root@client:/etc/wireguard  #   chmod 600 /etc/wireguard/wg0-client.conf 

Next, we should enable the Wireguard service on the client computer

root@client:/etc/wireguard# systemctl enable wg-quick@wg0.service 
 wg-quick up wg0 
 [#] ip link add wg0 type wireguard 
 [#] wg setconf wg0 /dev/fd/63 
 [#] ip address add 10.10.0.2/32 dev wg0 
 [#] ip address add fd86:ea04:1111::2/128 dev wg0 
 [#] ip link set mtu 1420 up dev wg0 
 [#] ip -6 route add ::/0 dev wg0 table 51820 
 [#] ip -6 rule add not fwmark 51820 table 51820 
 [#] ip -6 rule add table main suppress_prefixlength 0 
 [#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820 
 [#] ip -4 rule add not fwmark 51820 table 51820 
 [#] ip -4 rule add table main suppress_prefixlength 0

Check Connection

In order to verify our connection details, we will run the wg command and then the wg-quick save wg0 command to save the settings to our configuration file.

root@client:/etc/wireguard# wg 
 interface: wg0 
   public key: YMJHJqjyQIuro9uVVp3rPoSvD9i92Dw2r2mAt121q3A= 
   private key: (hidden) 
   listening port: 51820 
 peer: Y5HkgP1jRSM9+Ti9CfpKfF/ZSZlQ0GFrRo3tlv+35gc= 
   endpoint: 10.0.0.2:51820 
   allowed ips: 10.0.0.2/24, fd86:ea04:1115::/64 
root@client:/etc/wireguard# wg-quick save wg0 

Then, we can test the connection by pinging the server.

ping 10.0.0.1 
    latest handshake: 1 minute, 37 seconds ago 
    transfer: 192.66 KiB received, 143.08 KiB sent 

Lastly, we should enable Wireguard to run at boot. To add this to our services, we will run the following command.

 root@client:/etc/wireguard  # systemctl enable wg-quick@wg0 

One final note; We can verify the connection at any time using the following command.

root@client:/etc/wireguard# wg show  

Windows Client Installation

Here is the link for the Wireguard msi installer for Windows.

Caution:
The developers of Wireguard recommend using only the approved Windows client as they do not guarantee the security of the connections is any other clients are used.

Other install Options

Wireguard also provides further options for installing the software across multiple platforms. We can view the other Wireguard install options here.

Conclusion

Overall, Wireguard is an effective, stable and useful tool in securing a connection from a local client to your VPN server. We learned how to install and configure Wireguard on the server as well as install and configure the client on your local computer.

How Can We help?

Our Support Teams are filled with talented individuals with intimate knowledge of web hosting technologies, especially those discussed in this article. If you are uncomfortable walking through the steps outlined here, we are just a phone call, chat or ticket away from aiding you through the process. Give us a call at 800.580.4985, or open a chat or ticket with us to speak with one of our knowledgeable Solutions or Experienced Hosting advisors to learn how you can take advantage of these techniques today!

Avatar for David Singer

About the Author: David Singer

I am a g33k, Linux blogger, developer, student, and former Tech Writer for Liquidweb.com. My passion for all things tech drives my hunt for all the coolz. I often need a vacation after I get back from vacation....

Latest Articles

How to use kill commands in Linux

Read Article

Change cPanel password from WebHost Manager (WHM)

Read Article

Change cPanel password from WebHost Manager (WHM)

Read Article

Change cPanel password from WebHost Manager (WHM)

Read Article

Change the root password in WebHost Manager (WHM)

Read Article