Installing the WireGuard server¶
The terms "server" and "client"
Usage of the terms
client were purposefully chosen in this guide specifically to help both new users and existing OpenVPN users become familiar with the construction of WireGuard's configuration files.
WireGuard itself simply refers to all connected devices as
peers. It constitutes a connection between computers.
Installing the server components¶
Installing everything we will need for a
wireguard connections is as simple as running:
sudo apt-get install wireguard wireguard-tools wireguard-dkms
For Ubuntu 18.04 and lower, you need to do some extra steps:
sudo add-apt-repository ppa:wireguard/wireguard sudo apt update sudo apt install wireguard wireguard-tools wireguard-dkms
If there is no
wireguard package available for your system, you can follow the instructions below to compile WireGuard from source.
Compile WireGuard from source
With the following commands, you can install WireGuard from source as a backport of the WireGuard kernel module for Linux to 3.10 ≤ kernel ≤ 5.5 as an out-of-tree module. More recent kernels already include WireGuard themselves and you only need to install the
Update your local system¶
sudo apt update && sudo apt upgrade -y
Install the toolchain¶
sudo apt install -y raspberrypi-kernel-headers libelf-dev build-essential pkg-config git
sudo apt install -y linux-headers-$(uname -r) libelf-dev build-essential libmnl-dev git
Download and compile the
git clone https://git.zx2c4.com/wireguard-linux-compat make -C wireguard-linux-compat/src -j$(nproc) sudo make -C wireguard-linux-compat/src install
You can ignore messages like
Warning: modules_install: missing 'System.map' file. Skipping depmod.
Check the module installation was successful
sudo modprobe wireguard
If there is no output,
wireguard was loaded correctly. Note that it may be necessary to re-install the
wireguard module when you update your system's kernel.
Download and compile the
wireguard tools (
git clone https://git.zx2c4.com/wireguard-tools make -C wireguard-tools/src -j$(nproc) sudo make -C wireguard-tools/src install
The ZX2C4 git repository is the official source for
wireguard-linux, see WireGuard#Repositories (external link)
Each network interface has a private key and a list of peers. Each peer has a public key. Public keys are short and simple, and are used by peers to authenticate each other. They can be passed around for use in configuration files by any out-of-band method, similar to how one might send their SSH public key to a friend for access to a shell server.
First, we create the folder containing our
sudo -i cd /etc/wireguard umask 077
Inhere, we generate a key-pair for the server:
wg genkey | tee server.key | wg pubkey > server.pub
Creating the WireGuard configuration¶
Create a config file
sudo nano /etc/wireguard/wg0.conf
and put the following into it:
[Interface] Address = 10.100.0.1/24, fd08:4711::1/64 ListenPort = 47111
echo "PrivateKey = $(cat server.key)" >> /etc/wireguard/wg0.conf exit # Exit the sudo session
to copy the server's private key into your config file.
Forward port on your router¶
If the server is behind a device, e.g., a router that is doing NAT, be sure to forward the specified port on which WireGuard will be running (for this example,
47111/UDP) from the router to the WireGuard server.
NAT: Network address translation
Network address translation modifies network packages. Incoming connection requests have their destination address rewritten to a different one.
NAT involves more than just changing the IP addresses. For instance, when mapping address
18.104.22.168, there is no need to add a rule to do the reverse translation. A
netfilter system called
conntrack recognizes packets that are replies to an existing connection. Each connection has its own NAT state attached to it. The reverse translation is done automatically.
Set up a domain name for your router¶
When connecting from outside your network, you'll need to know the public IP address of your router to connect. However, as most households are getting dynamically-assigned public IP addresses (these addresses change periodically), you need to note down the address every day before leaving the house. Since this is very uncomfortable, we strongly suggest registering a dynamic host record (often called "DynDNS" record).
The public IP address is checked at regular intervals. As soon as it changes, the router (or a DynDNS tool) sends a corresponding message to a URL of the service provider, who then updates the record.
There are many excellent guides and a lot of services offer this for free (with more or less comfort). We suggest a few providers below, however, this list is neither absolute nor exhaustive:
If you already have a hosting package at Strato, you can easily set up a subdomain to be used as a DynDNS record. This is entirely free for members.
This provider offers you several free subdomains under different domain names. SSL and also IPv6 are possible. DNSSEC is activated by default. They offer configuration guides for the Fritz!Box and also
ddclient(update tool for Windows and Linux) on the website.
Go IP is a German DynDNS provider. The service is completely free and allows the registration of one domain and up to 15 subdomains per person. The website is characterized by extensive help with setting up the router.
You can up to three hostnames like
myname.no-ip.orgfor free. A disadvantage is that you have to confirm the domains at least every 30 days, otherwise they will be deleted.
One of the first providers to offer DynDNS was the American company Dyn, whose product "DynDNS" gave its name to an entire service branch. In the meantime, numerous successors whose services are often free of charge came up. DynDNS service is especially easy to use is if it is directly supported by the router.
You can either use the methods the corresponding providers recommend or use existing DynDNS solutions inbuilt in your router (if available). Most providers are compatible with, e.g., the popular Fritz!Box routers (EN / DE).
Start the server¶
Register your server
sudo systemctl enable firstname.lastname@example.org sudo systemctl daemon-reload sudo systemctl start wg-quick@wg0
If successful, you should not see any output.
Error: RTNETLINK answers: Operation not supported
In case you get an error like
RTNETLINK answers: Operation not supported Unable to access interface: Protocol not supported
you should check that the WireGuard kernel module is loaded with the command below:
sudo modprobe wireguard
If you get an error saying the module is missing, try reinstalling WireGuard or restart your server and try again. This may happen when the WireGuard server is installed for a more recent kernel than you are currently running. This typically happens when you have neither updated nor restarted your system for a long time.
Error: RTNETLINK answers: File exists
In case you get an error like
RTNETLINK answers: File exists
you need to check the configured IP addresses (check the CIDR notation). Overlapping IP address ranges cause this error when trying to register a router for an address where a a route already exists. This is meaningful and always an error in your configuration. However, the error message could be more clear about this.
Check everything is running¶
With the following command, you can check if your
wireguard server is running:
The output should look like the following:
interface: wg0 public key: XYZ123456ABC= ⬅ Your public key will be different private key: (hidden) listening port: 47111
Your public key will be different from ours. This is expected (you just created your own key above).
Set your Pi-hole to listen on all interfaces¶
On your Settings page (tab DNS), ensure you set the listing mode of your Pi-hole to one of the
Listen of all interfaces settings. The top one is preferred as it adds a bit of additional safety. Your WireGuard peers/clients will be correctly recognized as being only one hop away.
You can now continue to add clients.