How to set up a VPN using Wireguard.

What is VPN? Virtual Private Network helps you to extend a private network across public networks. Letting users send and receive data across shared or public network just as they would be in a private network.

Why wireguard?

VPN is no longer some kind of exotic tool for bearded system administrators. The problem with current VPN solutions is that they are difficult to configure correctly, expensive to maintain, and they are also full of legacy code of dubious quality.

A few years ago, Canadian information security specialist Jason A. Donenfeld decided that he had to endure this and started working on WireGuard. Now WireGuard is included in the Linux kernel. It even received praise from Linus Torvalds and in the US Senate.

The declared advantages of WireGuard over other VPN solutions:

  • Easy to use.
  • Uses modern cryptography: Noise protocol framework, Curve25519, ChaCha20, Poly1305, BLAKE2, SipHash24, HKDF, etc.
  • Compact readable code, easier to investigate for vulnerabilities.
  • High performance.
  • Clear and detailed specification.

How wireguard works?

The principles of operation can be described as follows:

  • A WireGuard interface is created, it is assigned a private key and IP address. The settings of other peers are loaded: their public keys, IP addresses, etc.
  • All IP packets arriving at the WireGuard interface are encapsulated in UDP and safely delivered to other peers.
  • Clients set the public IP address of the server in the settings. The server automatically recognizes the external addresses of clients when correctly authenticated data comes from them.
  • The server can change the public IP address without interrupting work. At the same time, it will send an alert to connected clients and they will update their configuration on the fly.
  • WireGuard receives and sends packets based on the public key of the peer with used Cryptokey Routing. When the server decrypts a correctly authenticated packet, its source field is checked. If it matches the allowed-ips configuration of the authenticated peer, then the packet is received by the WireGuard interface. When sending an outgoing packet, the corresponding procedure occurs: the destination field of the packet is taken and the corresponding peer is selected based on that peer, the packet is signed with its own key, encrypted with the peer key and sent to the remote endpoint.


For our very own VPN server we will need an Ubuntu 18.04 server, which you can access as root or an account with sudo privileges.

You can either check API tutorial video or log into user interface and simply create virtual machine on the platform.

Steps of the tutorial

  1. Create an Ubuntu virtual machine in the environment. 
  2. Install WireGuard on that virtual machine and configure it to work as a server. 
  3. Configure the system to route customer traffic through it.
  4. Configure client side on the Windows 10.
  5. Establish connection with the server.

Step 1. Wireguard installation on the Ubuntu 18.04

Before anything, we must make sure we always have latest updates installed.

For that we run command: 

sudo apt update && apt upgrade -y

Once it’s done, we can continue with the Wireguard.

WireGuard maintains its own APT repository from which we’ll install the package and update it when a new version is available. 

Update the packages list and install the tools necessary for managing your system repositories. Chances are that you already have the package on your machine:

sudo add-apt-repository ppa:wireguard/wireguard
sudo apt update
sudo apt install software-properties-common

Add the WireGuard repository:

sudo add-apt-repository ppa:wireguard/wireguard

When prompted, press Enter to continue. add-apt-repository will also automatically update the package list.

Install the WireGuard package:

sudo apt install wireguard

In the procces of installation, you will be asked update or keep menu.lst. Choose “install the package maintainer’s version

sudo reboot

After the installation just reboot the virtual server and the WireGuard module will be compiled against the new kernel.

Step 2. Configuring WireGuard

WireGuard ships with two command-line tools named wg and wg-quick that allow you to configure and manage the WireGuard interfaces.

Run the following command to generate the public and private keys:

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

The files will be generated in the /etc/wireguard directory. You can view the files with cat or less. The private key should never be shared with anyone.

Now that the keys are generated, we’ll need to configure the tunnel device that will route the VPN traffic.

The device can be set up either from the command line using the ip and wg or by creating the configuration file with a text editor.

Before creating a configuration file, we need a server private key, which we will copy to the configuration file.

sudo cat /etc/wireguard/privatekey

Create a new file named wg0.conf and add the following contents:

sudo nano /etc/wireguard/wg0.conf
Address =
SaveConfig = true
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE

The interface can be named anything, however, it is recommended to use something like wg0 or wgvpn0. The settings in the interface section have the following meaning:

  • Address – a comma-separated list of v4 or v6 IP addresses for the wg0 interface. Use IPs from a range that is reserved for the private networks (, or
  • ListenPort – the port on which WireGuard will accept incoming connections.
  • PrivateKey – a private key generated by the wg genkey command. (To see the contents of the file run: sudo cat /etc/wireguard/privatekey)
  • SaveConfig – when set to true, the current state of the interface is saved to the configuration file when shutdown.
  • PostUp – command or script which is executed before bringing the interface up. In this example, we’re using iptables to enable masquerading. This will allow traffic to leave the server, giving the VPN clients access to the Internet. 
  • PostDown – command or script which is executed before bringing the interface down. The iptables rules will be removed once the interface is down.

The wg0.conf and privatekey files should not be readable to normal users. Use chmod to set the permissions to 600:

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

Once done, bring the wg0 interface up using the attributes specified in the configuration file:

sudo wg-quick up wg0

The command will produce something similar to this output:

[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 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

Run wg show wg0 to check the interface state and configuration:

sudo wg show wg0

interface: wg0

public key: r3imyh3MCYggaZACmkx+CxlD6uAmICI8pe/PGq8+qCg=
private key: (hidden)
listening port: 51820

You can also run ip a show wg0 to verify the interface state:

ip a show wg0

4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
inet scope global wg0
valid_lft forever preferred_lft forever

To bring the WireGuard interface at boot time run the following command:

sudo systemctl enable wg-quick@wg0

Step 3. Server Networking and Firewall Configuration

For NAT to work, we need to enable IP forwarding. Open the /etc/sysctl.conf file and add or uncomment the following line:

sudo nano /etc/sysctl.conf

Save the file and apply the change:

sudo sysctl -p
net.ipv4.ip_forward = 1

For the UFW firewall management you need to open UDP traffic on port 51820:

sudo ufw allow 51820/udp

That’s it. The Ubuntu peer that will act as a server has been set up.

Step 4. Windows Clients Setup

Download and install the Windows msi package from the WireGuard website.

Once installed open the WireGuard application and click on “Add Tunnel” -> “Add empty tunnel…” as shown on the image below:

Key pairs will automatically be created and shown on the screen. Just add a tunnel name and insert similar config

In the Peer segment, there are further options:

PublicKey – a public server key of the Ubuntu server (located in /etc/wireguard/publickey)

Endpoint – public IP-address of the Ubuntu server and the WireGuard port (51820)

AllowedIPs –

Then click Save

Step 5. Add client peer to the server

Last step – is to add an open public key and the IP address on the server:

sudo wg set wg0 peer CLIENT_PUBLIC_KEY allowed-ips

Make sure you change the CLIENT_PUBLIC_KEY public key generated on the client computer (sudo cat / etc / wireguard / publickey) and change the IP address of the client if it is different. Windows users can copy the public key from the WireGuard application.

After that, return to the client computer and open the tunnel interface.


Add Yours →

Leave a Reply