WireGuard is an extremely simple, fast and modern open-source Virtual Private Network (VPN) implementation. It is a VPN protocol based on modern cryptographic technology.  

WireGuard uses state-of-the-art cryptography, like the Noise protocol framework, Curve25519, ChaCha20, Poly1305, BLAKE2, SipHash24, HKDF etc. which makes it secure choice based on modern cryptography standards.

WireGuard lives and runs inside operating system's kernel, which makes it blazing fast. When it comes to simplicity you can't get VPN implementation simpler then WireGuard, it is very simple to set up and running.

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 - wireguard.com

What you can expect from this article?

In this article we are going to set up our own private VPN server on Azure cloud, using following steps:

  • Private VPN severe running in Azure cloud on Ubuntu server.
  • Setup mobile devices such as phone to use your VPN server.
  • Configure your laptop or PC to be able to connect to use VPN server.

If you follow the script, I promise it won't take more than 10 minutes to set up and running your one VPN system.

1) Create Azure virtual machine

Login to Azure portal and create new Ubuntu virtual machine. Azure's web portal is very easy to follow & all sections are pretty much self-explanatory, but you can follow the settings in this snapshot.

azure - create virtual machine
Azure: Create virtual machine

Now we need to configure firewall ports. Go to settings network and open following ports.

  • 51820/UDP for sending and receiving VPN traffic.
  • 22/TCP for connecting to your server for configuration, once you are done with server setup this port disabled.
azure network firewall
Networking - Firewall
For security reasons port: 51820/UDP should be the only incoming port open on your server. You can close every other incoming port unless your server is serving other applications.

Once your machine is created we can download private key to your laptop or pc and connect using your favorite ssh client. The key file should be something like 'your-server-key.pem'.

2) WireGuard Server Setup

If the selected version of Ubuntu is lower than 20.04 you need to add following repository, otherwise you can skip the following script.

sudo add-apt-repository ppa:wireguard/wireguard &&
sudo apt-get update 
Add WireGuard repository

Now your repository is set up or you are on Ubuntu 20.04 or higher which includes the sources by default, run following script to install WireGuard.

 sudo apt install wireguard
Install WireGuard

Create folder wg/keys and  generate server keys. This will generate server's private and public keys into wg/keys folder.

mkdir wg && 
mkdir wg/keys &&
umask 077 && 
wg genkey |tee wg/keys/server_private_key|wg pubkey>wg/keys/server_public_key
Create server's public and private keys

Now we have keys generated, next step is to create WireGuard network interface configuration file. WireGuard uses wg0 as default terminology for network interface. Following bash script will create server interface config inside etc.

echo "
[Interface]
Address = 10.200.200.1/24
SaveConfig = true 
ListenPort = 51820
PrivateKey=$(cat wg/keys/server_private_key)"|sudo tee /etc/wireguard/wg0.conf
Generate WireGuard's server interface config (wg0)

As far as the WireGuard is concerned we are done with configuration. We need to do some housekeeping on operating system level in order for VPN server to properly send and receive internet traffic to/from clients.

2.1) IP Forwarding

IP forwarding lets your system acts like router which receives data packages from one network and delivers to other one. Since our VPN server is expected to get all internet traffics from our devices to internet and vice versa without exposing our location or IP address.

Enable IP forwarding otherwise your server won't be able to send or receive network traffic.

sudo sysctl -w net.ipv4.ip_forward=1
IP forwarding

In order to make change permanent, update sysctl.conf file.

sudo nano /etc/sysctl.conf
# uncomment line: net.ipv4.ip_forward = 1
# reload changes
sudo sysctl -p /etc/sysctl.conf
Update IP forwarding configuration

2.2) Firewall Rules

The iptables is useful utility to manage firewall rules on Linux. We need to configure some firewall rules to complete the setup. Following script configures some IP rules along with some NAT routing.


#IP4
sudo iptables -A FORWARD -i wg0 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

#IP6
sudo ip6tables -A FORWARD -i wg0 -j ACCEPT 
sudo ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

#NAT
sudo iptables -t nat -A POSTROUTING -s 10.200.200.0/24 -o eth0 -j MASQUERADE
Firewall rules

Since IP tables are in-memory and gets wiped-out on system reboot. We can save this IPTables configuration rules between server reboots. Execute following bash script to persist IPTables.

sudo apt install iptables-persistent &&
sudo systemctl enable netfilter-persistent &&
sudo netfilter-persistent save
Persist IPTables

2.3) Spin up the Wireguard Interface

Now the final step is to start the WireGuard server by spinning up wg0.

sudo wg-quick up wg0 &&
sudo systemctl enable wg-quick@wg0
Start WireGuard server

If everything goes as planned this following command should have output like following:

sudo wg show

#Output:
#public key: DXE5hJmOnxCTwlrP+eqpYhF/1MjQUKBbf7z9+tSADyk=
#  private key: (hidden)
#  listening port: 51820
Server status

Server is up and running now. We need to configure clients. The client configuration is two-step process:

First we need to tell server which client needs to be supported, by generating client configuration and attaching to server.

Second we need to tell the client device which VPN server to use.

2.4) Generate Clients

Now we are going to generate client configurations and attach them to server.

mkdir wg/clients
Creat clients folder

For mobile devices it is easier to scan QR Code rather than dealing with file downloads. Install qr encode with following script which we would use to generate QR images for clients configurations later on.

sudo apt install qrencode
Install QR Encode library
Although following configurations are for two clients iPhone & laptop/pc but you can repeat it for as many as needed.

Generate Configuration for iPhone

Following script will create public/private keys for iPhone client and attach to server:

umask 077 &&
wg genkey | tee wg/keys/iphone8_private_key | wg pubkey > wg/keys/iphone8_public_key && 
echo "wg set wg0 peer $(cat wg/keys/iphone8_public_key) allowed-ips 10.200.200.2/32" | sudo bash -
Create client keys & attach to server

Status command should have output something like following showing server with one client.

sudo wg show

#Output
#interface: wg0
#  public key: TGE5hJmOnxCTylrP+edpYhF/1MjQUKBbf7q9+tSADnk=
#  private key: (hidden)
#  listening port: 51820

#peer: yLemxg5QVBEL4FWd2SXPP5HnX3+CCNDvF0A5fCjdikg=
#  allowed ips: 10.200.200.2/32

Server with one client

Next step is to create WireGuard config for client. We are going to generate client configuration using this script. Don't forget to add public IP of your VPN server to following script. The public IP can be found from first step when Ubuntu VM is created.

echo "[Interface] #iphone8
Address = 10.200.200.2/32
PrivateKey = $(cat 'wg/keys/iphone8_private_key')
DNS = 1.1.1.1 # Cloudflare DNS but you can use DNS of your choice

[Peer]
PublicKey = $(cat 'wg/keys/server_public_key')
Endpoint = <Public IP of your VPN Server>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 21" > wg/clients/iphone8.conf
Generate configuration for iPhone

Now your configuration is generated for device. We have two options either download config file to your device, in this case iPhone. Or generated QR Image out of iphone8.conf, which can be easily scanned via camera.

To generate QR Code image, run the following script.


qrencode -o wg/clients/iphone8.png -t png < wg/clients/iphone8.conf
Generate QR image for your phone configuration

Generate Configuration for laptop or PC

The first thing we need to do is generate keys for device. In your server terminal run following:

wg genkey | tee wg/keys/laptop_private_key | wg pubkey > wg/keys/laptop_public_key
Generate public/private key for your laptop

Now add your client to VPN server's config.

echo "wg set wg0 peer $(cat wg/keys/laptop_public_key) allowed-ips 10.200.200.4/32" | sudo bash -
Attach your laptop/pc to VPN server

Next step is to create configuration file for your client. Following bash script will create config file for your client and save it to wg/clients.

echo "[Interface] #laptop
Address = 10.200.200.4/32
PrivateKey = $(cat 'wg/keys/laptop_private_key')
DNS = 1.1.1.1 # Cloudflare DNS 

[Peer]
PublicKey = $(cat 'wg/keys/server_public_key')
Endpoint = <vpn-server-IP>:51820  
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 21" > wg/clients/laptop.conf
Generate configuration file for laptop/pc
One important thing to be noted in above client configurations is Address field. For first client it is 10.200.200.2/32, second 10.200.200.4/32. Don't forget to increment/change last section of your client IP address range, otherwise you would be scratching your head for server not sending data to client & vice versa.

Until this point everything including keys, configurations & QR images are sitting on your VPN server. Now it is time to download to client device.

3) WireGuard Client Setup

Let start with configuring an iPhone to be connected to VPN server. Now open new ssh terminal on your laptop/pc (not the server) and download the image generated earlier to your local machine.

scp vpn-server-user-name@vpn-server-ip:wg/clients/iphone8.png wg/
Copy QR image to your local machine

Setup iPhone to use VPN Server

Download WireGuard app from App Store. Open iphon8.png just downloaded & scan QR Code.

When we enable VPN tunnel inside WireGuard app, you should be able to see something like following by tapping on settings. If you tap on view log you should be able to see communication with your VPN server. The top of phone should have little vpn sign.

ios - iphone wireguard app image
IOS Wireguard image

You can check your location using mylocation.org and that should be location of your VPN server. Open other apps such as youtube to see if your internet is still working.

Connect your laptop to VPN Server

This section we are going to configure Linux desktop machine. This example show Ubuntu/Debian based configuration but it is applicable to any Linux distro. Now open bash terminal on your laptop/pc (not server). Download configuration file generated above to '/etc/wireguard/wg0-client.conf' on your laptop/pc.

sudo scp vpn-server-user-name@vpn-server-ip:wg/clients/laptop.conf /etc/wireguard/wg0-client.conf
Download WireGuard config

Install WireGuard on client machine using following script.

add-apt-repository ppa:wireguard/wireguard
apt-get update
apt-get install wireguard-dkms wireguard-tools linux-headers-$(uname -r)
Install WireGuard on your PC

Spin up the VPN network interface.

sudo wg-quick up wg0-client
Enable VPN network interface

You need to manually spin up vpn client interface every time you reboot your machine, which is not difficult but in order to avoid headache you can auto enable on reboot with following command.

sudo systemctl enable wg-quick@wg0-client.service
VPN client interface service

Now your network traffic from local machine is going through VPN tunnel of your own VPN server. A quick way to check is the following command.

sudo wg show 
#interface: wg0-client
#  public key: 7aGrxgEDkraHVgDs4OWIDHqpq6vcoueeyJeOtyGbcwk=
#  private key: (hidden)
#  listening port: 52998
#  fwmark: 0xca6c

#peer: dJfZ9T9NaqhUtUzPtqYRtNUroq/+tjEOQn+NxovGZg0=
#  endpoint: <you vpn server ip>:51820
#  allowed ips: 0.0.0.0/0
#  latest handshake: 46 seconds ago
#  transfer: 13.52 MiB received, 4.22 MiB sent
#  persistent keepalive: every 21 seconds
check vpn connection status

You can check your location using mylocation.org and that should be location of your VPN server. Wala! we have configured VPN server with iPhone & Laptop connected.

Conclusion

WireGuard is extremely fast VPN protocol and by far the most popular one. The reason it is so popular is blazing fast, secure and simple. Unlike OpenVPN and IPSec, WireGuard does one thing and do it with absolution perfection. Setting up VPN server wasn't easier with earlier VPN technologies, especially configuring your own home server or raspberry pi.

Although this article uses Ubuntu VM in the cloud to demonstrate WireGuard VPN but these steps are applicable to any device capable of running Linux operating system.

If you come that far hope you enjoyed the reading. Please give feedback & share if you like the article. Cheers!

Here are Some helpful links:

WireGuard Cloud - Github

wireguard-vpn-typical-setup - ckn.io