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, Linux, Windows, or macOS computer.

In this guide, I will walk you through installing and configuring the WireGuard server and creating your first client configuration file.

Prerequisites

You should run the following commands as root or you will need to add sudo to the start of each command.

You will need to configure your router to port-forward the standard WireGuard port of 51820 to the (static) IP address of the server you are going to use to run WireGuard...

... you have to enable IPv4 forwarding on the server...

echo "net.ipv4.ip_forward=1" > /etc/sysctl.conf

... and you need to allow port 51820 and 'masquerade' through the server firewall (IP masquerading is a process where one computer acts as an IP gateway for a network).

ufw allow 51820/udp
ufw reload

Debian Distributions

firewall-cmd --permanent --zone=public --add-port=51820/udp
firewall-cmd --permanent --zone=public --add-masquerade
firewall-cmd --reload

RHEL Distributions

Installation

WireGuard is in the standard repositories of all the major distributions.

dnf update
dnf install wireguard-tools
reboot

WireGuard is a kernel module that needs to get loaded into the kernel with a reboot

Configure the server

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

cd /etc/wireguard/

Use the umask command below to set the folder and files permissions correctly.

umask 0077

Next, create the WireGuard server configuration with a text editor.

nano wg0.conf

Use this template:

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

Change eth0 to your adapter - check with 'ip -a'

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. First, make a directory to store created keys.

mkdir /etc/wireguard/keys

This command will print the private key and also save it into a file at /etc/wireguard/keys/server_private_key. An example public key output is also shown:

wg genkey | tee /etc/wireguard/keys/server_private_key

qN5RxYv4EUKyMO0iMtoG+E1W+Z/Vewz2nN06PRvuDkU=

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

cat "/etc/wireguard/keys/server_private_key" | wg pubkey | tee /etc/wireguard/keys/server_public_key

o8QzQ2oW1hW0S1B7Q5DPyUE0AXoA2595kmIcpAfhTQI=

This will print the server’s public key to the terminal and also write it to a file at /etc/wireguard/keys/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 = qN5RxYv4EUKyMO0iMtoG+E1W+Z/Vewz2nN06PRvuDkU=
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

Save and exit the editor.

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 an iPhone so I will call it phone.conf. Open this with an editor:

nano /etc/wireguard/clients/phone.conf

This is the template for the iPhone client:

[Interface]
PrivateKey = <CLIENT_PRIVATE_KEY>
Address = <CLIENT_IP>/24
DNS = <OPTIONAL_RESOLVER>

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

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 | tee /etc/wireguard/keys/phone_private_key

kKWGKN780KifER4T24LGyjA4SLQvQ7OUcnwdBP1VdnY=

cat "/etc/wireguard/keys/phone_private_key" | wg pubkey | tee /etc/wireguard/keys/phone_public_key

ixazMQY6MNK5iKE438WB0lpl1J0FQzzU2Vpsp0s8bQQ=

Use the same command to generate a PresharedKey:

wg genkey

YL7rp8hAgHuiB4iYs9Uut7aqlCgCCzH0bbC8BEN3X3w=

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

[Interface]
PrivateKey = kKWGKN780KifER4T24LGyjA4SLQvQ7OUcnwdBP1VdnY=
Address = 10.0.0.2/24
DNS = 1.1.1.1

[Peer]
PublicKey = o8QzQ2oW1hW0S1B7Q5DPyUE0AXoA2595kmIcpAfhTQI=
PresharedKey = YL7rp8hAgHuiB4iYs9Uut7aqlCgCCzH0bbC8BEN3X3w=
AllowedIPs = 0.0.0.0/0
Endpoint = 1.2.3.4:51820
PersistentKeepalive = 25

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 the public key, pre-shared key, and the IP 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 = qN5RxYv4EUKyMO0iMtoG+E1W+Z/Vewz2nN06PRvuDkU=
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# phone
[Peer]
PublicKey = ixazMQY6MNK5iKE438WB0lpl1J0FQzzU2Vpsp0s8bQQ=
PresharedKey = YL7rp8hAgHuiB4iYs9Uut7aqlCgCCzH0bbC8BEN3X3w=
AllowedIPs = 10.0.0.2/32

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 [email protected]

Created symlink /etc/systemd/system/multi-user.target.wants/[email protected] → /lib/systemd/system/[email protected].

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

systemctl start [email protected]
systemctl stop [email protected]

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

Check Status

wg

Transferring a configuration file

You have three ways to create an interface:

  • Create from file or archive
  • Create from a QR Code
  • Create from scratch

It’s easy to generate a QR Code on your computer using qrencode:

dnf install qrencode
qrencode -t ansiutf8 < /etc/wireguard/clients/iphone.conf

Scan the QR Code with the WireGuard app on the iPhone and you’re done.


WireGuard: fast, modern, secure VPN tunnel
WireGuard: fast, modern, secure VPN tunnel