WireGuard is a secure and painless VPN service that runs on a variety of operating systems, including Android and iOS. New clients can easily connect to the service by simply pointing to a QR code.
In this tutorial we will look into installing WireGuard using Docker on Debian 10.
Starting on Linux kernel version 5.6, WireGuard is shipped as a built-in module, but, at the time of writing this post, the stable Debian 10 (Buster) still uses the Linux kernel version 4.19.
Why run it on Docker though?
You may be asking yourself, why bother using Docker when WireGuard is part of the Linux kernel now? I personally like the portability of Docker, that allows moving of a
docker-compose.yml around and turning up services within seconds.
The Docker image we will be using (
linuxserver/wireguard) relies on the WireGuard kernel module available at the host so we need to upgrade the Linux kernel from 4.x to 5.x.
Installing Linux kernel 5.x on Debian 10
The version 5.x of Linux kernel images can't not be found in the main Debian stable repositories. This is where Debian Backports come in. Backports are packages taken from the next Debian release (called "testing"), adjusted and recompiled for usage on Debian stable.
1. Add the backport repositories to apt source lists:
echo "deb http://deb.debian.org/debian buster-backports main" > \ (out)/etc/apt/sources.list.d/backports.list
2. Update the packages list:
3. Install the latest Linux image from backports:
apt -t buster-backports install linux-image-amd64
4. Reboot the system so it boots with the new image:
5. We can confirm the latest Linux image being used by:
uname -r (out)5.10.0-0.bpo.8-amd64
Running WireGuard on Docker
1. Let's create a dedicated folder to keep our new WireGuard container:
mkdir -p /srv/docker/wireguard && cd /srv/docker/wireguard
2. On our
docker-compose.yml file, we will create a WireGuard container using the
linuxserver/wireguard image that listens on port
vi docker-compose.yml (out)services: (out) wireguard: (out) image: ghcr.io/linuxserver/wireguard (out) container_name: wireguard (out) cap_add: (out) - NET_ADMIN (out) - SYS_MODULE (out) environment: (out) - PUID=1000 (out) - PGID=1000 (out) - TZ=America/New_York (out) - SERVERURL=myserver.domain (out) - PEERS=mylaptop,myphone,myserver (out) volumes: (out) - ./data/config:/config (out) - /lib/modules:/lib/modules (out) ports: (out) - 51820:51820/udp (out) sysctls: (out) - net.ipv4.conf.all.src_valid_mark=1 (out) restart: unless-stopped
There's a lot to digest on this configuration file but I'd like to focus on what's most relevant for our WireGuard service.
- SERVERURL: Can be set to an external IP or domain name. If set to
auto, the container will try to automatically set to the external IP.
- PEERS: This is where we put our clients (peers); it can be a number or a list of names.
- ./data/config:/config: This is the location where the configuration files will be stored, along with the QR Codes. If the folder doesn't exist one will be created. You can change it as needed.
- More details about the other parameters can be found at the official page of the
3. Finally, let's start our new container. When we do this for the first time Docker has to download all the images:
docker-compose up -d (out)Creating network "wireguard_default" with the default driver (out)Creating wireguard ... done
And if we edit the
docker-compose.yml file, let's say, to add more peers, we can recreate the new configurations by:
docker-compose up -d --force-recreate (out)Recreating wireguard ... done
Just remember to configure your firewall to allow incoming traffic to port
51820/udp(or port of choice), otherwise peers won't be able to connect.
Connecting new clients
First we need to recover the QR Code created for our peer; those are automatically generated when the container starts based on the
PEERS parameters in our
docker exec -it wireguard /app/show-peer myphone
Alternatively, we can find the QR Code and the configuration file in our Docker
WireGuard Client on Android and iOS
The WireGuard app can be found both on Android and iOS. After installing it:
- Click on the Add icon
- Select Scan from QR Code
- Point your camera to the QR Code shown on the terminal
- Give the tunnel a name, and finally
- Enable the WireGuard tunnel by toggling it on.
The first time we use this app it may ask for additional permissions to control your device connection, that's expected.
WireGuard Client on Debian and Ubuntu
1. Install WireGuard package:
apt-get install wireguard
2. On the client, we will create a
wg0.client file with the content of the generated peer configuration from the WireGuard server.
vi /etc/wireguard/wg0.conf (out)[Interface] (out)Address = ... (out)PrivateKey = ... (out)ListenPort = ... (out)DNS = ... (out) (out)[Peer] (out)PublicKey = ... (out)Endpoint = ... (out)AllowedIPs = 0.0.0.0/0, ::/0
If you get an error like
/usr/bin/wg-quick: line 32: resolvconf: command not foundyou may need to
apt-get install openresolv.
3. Finally, we bring the tunnel interface up:
wg-quick up wg0
4. Check the new external IP on MyIP.com.