Using WireGuard to create a VPN Tunnel
So you've got a server stuck behind a NAT you can't configure, may it's managed by your building's external IT supplier or you just aren't allowed to tinker with the port forwarding settings. How can you allow external access to this device?
This guide heavily leans upon the guide created Justin at DigitalOcean, cheers Justin! Using Wireguard, we can create a VPN tunnel between the server and an external end-point (such as an Google Cloud Compute engine). For this configuration i've got the following set up:
-
Google Compute Engine (called SERVER 1)
- Zone: us-east1-b (use whichever you'd like)
- g1-small (1 vCPU, 1.7GB Memory)
- Static external IP set
- IP Forwarding turned ON
-
Ubuntu 18.04 LTS Local Server (called SERVER 2)
- Running in a Hyper-V virtual box
- 2GB RAM
- 10GB SSD
- Network configured using DHCP and has access to internet
Step 1 - installing the required packages
We first need to install the Wireguard package on both servers. This requires adding the Wireguard repo, to do this run the following on both Server 1 and Server 2:
sudo add-apt-repository ppa:wireguard/wireguard
Then run:
sudo apt-get update
And finally:
sudo apt-get install wireguard-dkms wireguard-tools
Step 2 - Create a private key
We need to generate a private key on both Server 1 and Server 2, this allows them to securely authenticate with eachother. Type the following on both servers (without the $):
$ (umask 077 && printf "[Interface]\nPrivateKey = " | sudo tee /etc/wireguard/wg0.conf > /dev/null)
$ wg genkey | sudo tee -a /etc/wireguard/wg0.conf | wg pubkey | sudo tee /etc/wireguard/publickey
Step 3 - Create the configuration file
Open the following file on Server 1 & Server 2 using whichever text editor you prefer (such as nano or vim) and add the following (don't change the private key though!):
/etc/wireguard/wg0.conf
[Interface]
PrivateKey = **generated_private_key**
ListenPort = 5555
SaveConfig = true
You can pick any free port you'd like, for the sake of simplicity we picked 5555. The SaveConfig flag means that the config file is overwritten when the wg service is stopped. Therefore you'll need to stop the service before changing any of the values, otherwise they'll be overwritten.
We need to add a unique address to each server, this gets mapped to the wg0 interface when the tunnel is brought online, for this guide we will use the 10.0.0.0/24 subnet.
Now, on server 1, add the address of: 10.0.0.1 like so:
[Interface]
PrivateKey = **generated_private_key**
ListenPort = 5555
SaveConfig = true
Address = 10.0.0.1/24
On server 2, we'll use 10.0.0.2, like so:
[Interface]
PrivateKey = **generated_private_key**
ListenPort = 5555
SaveConfig = true
Address = 10.0.0.2/24
Defining the peer
We've now finished the 'Interface' section, next is the 'Peer' section which defines the neighbour server (server 1 for server 2 and vice versa). We'll need the public key from the first server. You can get this by typing:
cat /etc/wireguard/publickey
On server 2's copy of wg0.conf, add the following underneath the interface section:
[Peer]
PublicKey = public_key_of_first_server
AllowedIPs = 10.0.0.1/32
Finally, you'll need to add the external IP address of server 1, so that server 2 knows where to connect to:
[Peer]
PublicKey = public_key_of_first_server
AllowedIPs = 10.0.0.1/32
Endpoint = public_ip_of_first_server:5555
Opening the ports
You'll need to open port 5555 on both server, so run the following on both server 1 & 2:
sudo ufw allow 5555
Now, start the wg-quick application, this configures the network adapter to use the settings we configured earlier:
sudo systemctl start wg-quick@wg0
Now the service is up, let's see if the interface is up too! To verify this, run:
ip addr show wg0
connorloughlin@discovery_ubuntu:~$ ip addr show wg0
7: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
link/none
inet 10.0.0.2/24 scope global wg0
valid_lft forever preferred_lft forever
You should see something like the above.
You can use the wg
command to view the active VPN configuration:
sudo wg
On server 1, where we haven't yet configured the peer section, you should see something like:
interface: wg0
public key: public_key_of_this_server
private key: (hidden)
listening port: 5555
Whereas on server 2, we see:
interface: wg0
public key: public_key_of_this_server
private key: (hidden)
listening port: 5555
peer: jeGkBcmeX4T184Kp+izStcLM7J/bY19KzUGsXZLr/hs=
endpoint: public_IP_of_first_server:5555
allowed ips: 10.0.0.1/32
Adding the missing peer information to Server 1
On server 1, we haven't yet added the peer information, we'll need the public key from server 2, which you can get by running:
sudo wg
Execute the following on server 1 to add the peer information:
sudo wg set wg0 peer public_key_of_second_server endpoint public_IP_of__server:5555 allowed-ips 10.0.0.2/32
Run sudo wg
again on both to confirm they're both configured correctly. If so, try pinging eachother!
Server 1 - ping 10.0.0.2
Server 2 - ping 10.0.0.1
If you get a ping response, your tunnel has been configured! To configure the server to automatically start the VPN tunnel on reboot, enter the following on both servers:
sudo systemctl enable wg-quick@wg0