Quickly Create a WireGuard Server and Clients

Introduction

WireGuard is a modern Virtual Private Network (VPN) server that allows you to securely route your data between your Android, iPhone phone, or Linux, Windows, or OSX computer. The older, open-source standard for creating your own VPN was OpenVPN which is, when compared to WireGuard, much harder to set up and configure.

In this guide, I will walk you through installing and configuring the WireGuard server and creating your first client configuration file. You can be up and running in 10 minutes or less because WireGuard was created to be secure by default obviating the need for complicated tweaking and tuning.

Step 1 - Installation

WireGuard is in the standard repositories of all the majour distributions. The Debian 11 server that I am using to write this guide the installation command is simply:

# apt update
# apt install wireguard
# reboot

The reboot is required because WireGuard is a kernel module that needs to get loaded into the kernel with a reboot.

Step 2 - Configure the server

The installation will create an empty directory at /etc/wireguard. First, move into that directory:

cd /etc/wireguard/

Next, create the WireGuard server configuration with a text editor, here I have used nano:

# nano wg0.conf

Use this template:

[Interface]
Address = <PRIVATE_IP>/24
ListenPort = <PORT>
PrivateKey = <SERVER_PRIVATE_KEY>
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

The [Interface] section is the server configuration. Later we will add a [Peer] after we have created the first client configuration.

The iptables commands are required to make sure your data is routed correctly from the Wireguard interface to your server’s public network interface.

You can choose any private IP address you want, I will go with 10.0.0.1/24 which gives you 255 IPs from 10.0.0.1 - 10.0.0.255 and I’m going to stick with the standard WireGuard port of 51820.

Now, you need to generate the server’s public and private keys. Open a new terminal to your server and run the following command to generate the private key. This command will print the private key and also save it into a file at /etc/wireguard/server_private_key. An example public key output is also shown:

# wg genkey | tee /etc/wireguard/server_private_key
QNogSc8aNEjYZyYhYdDKqwQK7CxT+PmFMz/sjr93uFM=

Next, use that private key to generate the public key, again I have shown the command with an example public key:

# cat "/etc/wireguard/server_private_key" | wg pubkey | tee /etc/wireguard/server_public_key
mjGH9f0eVOZaKFoShw+40QAwtfTkqaEws+03JUW9VlI=

This will print the server’s public key to the terminal and also write it to a file at /etc/wireguard/server_public_key as you will need it later.

You now have everything to complete the [Interface] section. Using the above information it will look like this:

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = QNogSc8aNEjYZyYhYdDKqwQK7CxT+PmFMz/sjr93uFM=
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

Save and exit the editor.

Step 4 - Configure a Client

First, create the directory to store all your client configuration files:

# mkdir /etc/wireguard/clients

The WireGuard client will load any file that ends in .conf so you can give them descriptive names. My first client is going to be Jane’s phone so I will call it jane_phone.conf. Open this with an editor:

# nano /etc/wireguard/clients/jane_phone.conf

This is the template for Jane’s client:

[Interface]
Address = <CLIENT_IP>/24
ListenPort = 51820
PrivateKey = <CLIENT_PRIVATE_KEY>
PublicKey = <CLIENT_PUBLIC_KEY>
DNS = <OPTIONAL_PUBLIC_RESOLVER>

[Peer]
PublicKey = <SERVER_PUBIC_KEY>
PresharedKey = <CLIENT_PRESHARED_KEY>
AllowedIPs = 0.0.0.0/0
Endpoint = <SERVER_PUBLIC_IP>:51820

The Address IP is one of the IPs from the range you have used. I will set this to 10.0.0.2. The DNS line is optional and will be used as the DNS resolver for this client. I like to use the Cloudflare public resolver as it is fast and private. This is located at 1.1.1.1.

Next, generate the keys as we did before:

# wg genkey
OHuE5G29hXVkIHePvMb9RjWkobsWM5g19C+krqugbUQ=
# echo 'OHuE5G29hXVkIHePvMb9RjWkobsWM5g19C+krqugbUQ=' | wg pubkey
BlYw7mX+ZMm9S15tiakhlMIMTcM94Asnc5XRPOMBLSk=

Use the same command to generate a PresharedKey:

# wg genkey
yP4KTyV6VZFg9aCqw1XQxMmlwnfyuv3wWIczg8NsA34=

Using this information Jane’s client config file will look like the following:

[Interface]
Address = 10.0.0.2/24
ListenPort = 51820
PrivateKey = OHuE5G29hXVkIHePvMb9RjWkobsWM5g19C+krqugbUQ=
PublicKey = BlYw7mX+ZMm9S15tiakhlMIMTcM94Asnc5XRPOMBLSk=
DNS = 1.1.1.1

[Peer]
PublicKey = mjGH9f0eVOZaKFoShw+40QAwtfTkqaEws+03JUW9VlI=
PresharedKey = yP4KTyV6VZFg9aCqw1XQxMmlwnfyuv3wWIczg8NsA34=
AllowedIPs = 0.0.0.0/0
Endpoint = 1.2.3.4:51820

Step 5 - Add the client to the server configuration

First, open the WireGuard server config file again:

# nano /etc/wireguard/wg0.conf

And add the following section at the bottom of the file:

[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
PresharedKey = <CLIENT_PRESHARED_KEY>
AllowedIPs = 10.0.0.2/32

Use Jane’s public key, pre-shared key, and the IP you gave her to complete this. Using the details we already generated the entire server config will look like this:

[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = QNogSc8aNEjYZyYhYdDKqwQK7CxT+PmFMz/sjr93uFM=
PublicKey = mjGH9f0eVOZaKFoShw+40QAwtfTkqaEws+03JUW9VlI=
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = BlYw7mX+ZMm9S15tiakhlMIMTcM94Asnc5XRPOMBLSk=
PresharedKey = yP4KTyV6VZFg9aCqw1XQxMmlwnfyuv3wWIczg8NsA34=
AllowedIPs = 10.0.0.2/32

Step 6 - Start WireGuard and enable it to start on boot

You will usually want WireGuard to start automatically when your server boots. Do this with systemd. First, enable the Wireguard service to start on boot:

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

Then you can start and stop WireGuard with the following commands:

# systemctl start wg-quick@wg0.service
# systemctl stop wg-quick@wg0.service

You should be able to start WireGuard now using the start command above.

Step 5 - Connect the client

Get a copy of the client configuration file e.g.: /etc/wireguard/clients/jane_phone.conf to their device open the WireGuard application on the device, create a new tunnel, and point it to this file. They will then connect and all the data from that device will travel through your WireGuard VPN to your server.