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.