Originally my media center was a docker containers with OpenVPN to handle VPN traffic. Since they I have updated my setup to use Wireguard instead and I’m documenting the resources I found useful in case anyone wants to do the same. Two main reasons drove me to move from OpenVPN to Wireguard:
The first reason is that my old provider Private Internet Access was bought out by Kape. There haven’t been any changes to PIA yet but the new owner is a bit worrying considering their track record. So I have changed to Mullvad as my new provider and they have very good Wireguard support.
The second reason is that Wireguard offers some compelling improvements over OpenVPN:
- OpenVPN is very resource demanding on the RPi. The Model 4 Raspberry Pi has a new I/O architecture which can properly use Gigabit LAN. Unfortunately the CPU overhead for OpenVPN was high enough that it limited throughput. My Pi would regularly have a core pinned near 100% utilization from OpenVpn. In comparison Wireguard’s performance is considerably lighter leading to better throughput.
- OpenVPN runs in user space where as Wireguard will be included in the kernel eventually. For now this complicates things a bit since it has to be installed separately but once the changes land it will make setup much easier.
Update 1/29/2020: Phoronix reports that Wireguard was just merged into the 5.6 kernel! However it will be a while before 5.6 is the stable kernel for many distrobutions so the installation instructions below will still be needed for a while.
Update 7/24/2020: While Debian 11 Bullseye isn’t releasing until 2021 its features are already being backported to Buster. Wireguard can now be pulled in from the buster-backports repo rather than having to build it!
In terms of researching how to set this up three articles were particularly useful:
Installing Wireguard on Debian
First I wanted general information about installing the Wireguard kernel modules and user space tools.
The Debian wiki generally outlines the process but leaves some details to the reader in terms of file permissions. Linode’s covered those in better details. I only care about the client configuration details since I am not running a server. Additionally instead of writing my own configuration file I used the Mullvad Wireguard configuration tools to generate one.
I also needed to install the following to follow the setup:
Using Wireguard with Docker
There’s a blog post that describes two solutions for using Wireguard with docker. The first involves creating a docker container that runs the Wireguard client. I went with the second approach instead which covers setting up a Wireguard interface on the host and using in a Docker network.
Raspberry Pi Specific Changes for Installation
Finally I want to do this on a Rapsberry Pi 4 which requires additional steps to install raspberrypi-kernel-headers and get Wireguard to run.
Putting It All Together With Ansible
Handling the Mullvad config file
The playbook assumes there is a file called “mullvad.conf” in the same directory as playbook which is the configuration file downloaded from the Mullvad configuration generation tool and the vars section uses the ini plugin for lookups to read the server Address and DNS information from config file:
Note the we have to split the address on “,” since the INI entry contains both the ipv4 and ipv6 address and we only want the first half
Update: Wireguard has been backported from Bullseye to buster and can be installed on a Pi:
We can achieve this in Ansible with the following:
Original Version: The installation process is basically a combination of the two posts on installing, but replacing command with ansible tasks to clean it up:
Configuring the Wireguard Interface
Finally we want to set up the wireguard interface that docker will use. We do this by first copying the Mullvad config over to the machine. Then as noted by the Wireguard on Docker article we remove the “Address” and “DNS” options from the config file since we have to manually configure the interface instead of using the wg-quick command. Then we are free to setup up the interface and configure it:
Creating the Docker Network
Finally all that is left is to create the docker network and setup the firewall to route it through wireguard: