HOWTO Install wireguard
It is quite handy to have a VPN service on demand when I have to connect to a open Wi-Fi. I deployed my own WireGuard service in a VPS with a few moving pieces.
You can either use the Ansible collection, lablabs.wireguard or your own role:
- Install the
wg-quickpackage. - Create
wg0.conf, defining the server’s key pair and the list of peer configurations. - Enable IPv4 and/or IPv6 packet forwarding.
- Open UDP port 51820 in the firewall to allow inbound WireGuard connections.
It worked, at least for a handful devices. But onboarding a new device was tedious:
we have to create a new key pair, adding the public key to the wg0.conf;
and securely distribute the tunnel configuration and client’s private key.
A more intuitive approach would be: the server generates the key pair, update
the peer configuration, and render a QR code containing the complete tunnel configuration.
The user can simply scan the QR code to import the tunnel configuration.
The solution is wg-easy. It provides an admin web UI to manage peers, generates key pairs, and keeps the underlying configuration in sync. I followed the guide to deploy it in a Docker container, worked as a magic.
A few implementation details are worth noting:
- The
wg0interface exists inside thewg-easycontainer’s network namespace, making it invisible from the host’s default namespace. - The webapp maintains states in
wg-easy.db, and automatically syncs to thewg0.conf.
The example docker-compose.yml creates a dedicated network wg
and expose 51821:51821/tcp. If you’re already running traefik as a reverse proxy
on a single host, both of those setup are unnecessary.
For traefik to route requests to a container, they must share a bridge network,
such as traefik-public, which can be reused for wg-easy as well.
Likewise, Traefik forwards requests based on the container name, it is sufficient
to configure the target port as:
traefik.http.services.wg-easy.loadbalancer.server.port: 51821
This leaves the web interface accessible only through traefik, a cleaner deployment.