Setting up Wireguard on VPS
Introduction
You have one or more services running on a VPS somewhere. Because the VPS is sitting on the internet with a public IP, the easiest way to access it is by exposing a port on that VPS where the service is running. This, however, opens up a load of possible security issues. Because now anyone on the internet can access the service just like you. This is perfectly fine in most cases, I mean, all websites that you browse work this way – they are exposed so that people can access them. If you don't want anyone else to access services on your VPS, you can leverage the power of VPN technology.
Setup Plan
Currently, all services on the VPS are listening on the server's public IP, which is the only network interface together with localhost. Here's what we will do:
- Install and setup Wireguard interface on the server
- Setup clients
- Stop all services and bind them only to the Wireguard interface
- Adjust firewall rules according to our new setup
This guide assumes that you will access these services only from a few devices. If, for example, you would like to provide your whole home network with access to the services running on your VPS, you will have to do it a bit differently.
|‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾| |‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾|
| HOME | | VPS |
|Android Device------------------------------------->---WG tunnel---> |
|[Interface] | | |
|eth0: 192.168.20.55 (private IP from DHCP at home) | | Server |
|WG IP: 10.20.20.2/29 | | [Interface] |
|WG public key: 16f5das48wa1f684g1a489awg5a | | eth0: 78.97.52.14 (example public IP) |
|WG private key: gzf74894ger89a46sd14g84r8esg | | WG IP: 10.20.20.1/29 |
| | | WG public key: 6t57489hgnufjfiosdjjfp98h |
|Windows Device------------------------------------->---WG tunnel---> WG private key: 4gfd89a7g1fd56g848g4fdg41fd |
|[Interface] | | |
|eth0: 192.168.20.56 (private IP from DHCP at home) | | |
|WG IP: 10.20.20.3/29 | | |
|WG public key: fgd489fdsg84168e46g1514ge5g | | |
|WG private key: iyut789tr496516sh416g4164h6h | | |
|___________________________________________________| |___________________________________________________|
*note: don't worry, the public and private keys in the diagram are just random placeholder values
Installation on the VPS
Since we are running Debian, we can get Wireguard from the official repository. I usually prefer building software from source, but for the sake of this guide, I will go the easier route and simply use the repo version.
Note that since it's Debian, the packages are sometimes a bit outdated. At the time of writing, the tools weren't available in the newest version – even in the unstable repo. The default stable repo has even older packages.
The situation around Debian and Wireguard is a bit confusing. Debian is known to be stable but has older packages. If you don't want to worry about anything, just install it from the stable repo:
$ sudo apt install wireguard
However, if you are on Debian 10, Wireguard still isn't integrated into the 4.19 kernel, which means the installation will bring the wireguard-dkms (Dynamic Kernel Module Support) package as well. On Debian 11, this should not be necessary, because Wireguard is already natively in the 5.10 kernel (which is default for Debian 11). I have it a bit more complicated. I am in fact running Debian 11, but with the 5.4 kernel (backported from Debian 10), which also doesn't have Wireguard natively, but that's just a side note. You can see the version status of the Wireguard package here:
To find out how to add testing or unstable to Debian 11, check out my guide over here.
Configure Wireguard on the server
The main configuration folder is located in /etc/wireguard
. This directory will contain both configuration and private/public key, therefore it is only accessible with root by default. To get to this directory, you need to elevate privileges.
$ sudo su
(root)$ cd /etc/wireguard/
Create configuration file for the Wireguard interface
Create a new file in /etc/wireguard
. The name of the file will also be the name of the interface (like eth0,lo,etc.) + .conf file extension. I like the default naming, so I will use name it wg0.conf
. Before creating the file, change umask to 077, so that the file is readable only by root. Umask controlls what permissions will newly created files and directories have. The default umask is 022. When we use the umask
command with a different number, all new files and directories will be created under permissions we have set. This modifies the default umask value only for the current sub-shell. To go back to the default umask, just logout/login. You can also make the changes permanent if you want. You can read more about umask
here.
(root)$ umask 077
(root)/etc/wireguard$ touch wg0.conf
Prepare wg0.conf
Open wg0.conf
with your favorite editor.
(root)$ vi /etc/wireguard/wg0.conf
We can start slowly preparing the config file, step by step. Right now, add the [Interface]
block, which will define properties of the server's Wireguard interface.
- Address – The local IP of the server within the Wireguard tunnel and subnet mask in CIDR notation. I know I will only have 3 clients, therefore I picked a small subnet /29 with only 6 usable hosts. (Basic subnetting knowledge is required).
- ListenPort – The port on the server Wireguard will use to communicate with other peers. After everything is set up, this will be the only port exposed to the open internet. If left unspecified, default is 51820.
- PrivateKey – The private key of the server that will be generated in a moment. This key should never be shared or leave the server. We will only send out the public key (as the name suggests).
Always keep private keys on devices where they were created. They should never be moved accross network or even accross devices.
The wg0.conf file should look like this right now:
[Interface]
Address = 10.20.20.1/29
ListenPort = 51895
PrivateKey =
Generate server public/private keys
Wireguard is built around the public and private key pairs structure. There is technically no such a thing as client or server in Wireguard, because everything is a peer. We use the client/server terminology to help our mind imagine the setup better. Each peer will generate its own private and public key. The private key will never leave the device where it originated from and should be kept well secured. The public key will be copied over to the other peers. In my case, the VPS will become a peer to both the Android and Windows device (clients). However, Android nor Windows will even know about each other, they will only be aware of the VPS, which will be their only peer. Reason for this is that they only need to talk to the VPS, not to each other.
Still as root, with umask set to 0077 (check by typing umask
in the terminal) and in the /etc/wireguard
directory, create a new subdirectory for the public/private keys and preshared keys (will explain in a second).
(root)$ mkdir keys psk
(root)$ cd keys
(root)$ wg genkey | tee wg0_private.key | wg pubkey > wg0_public.key
Setting up the clients
1. Windows
Download and install Wireguard
Download the Windows Installer from the official Wireguard website.
Run the wireguard-installer.exe
and after a few moments, this window should appear:
Moving network services to WG interface
Adjusting Firewall rules