Docker and Wireguard

Adding docker containers to Wireguard network

Docker is the most convenient way of delivering my applications to servers, and Wireguard is the best VPN tool I have found so far. Naturally I would like to combine the two to give some of my Apps access to a Private Network, in which they can find a database for example.

This greatly increases security and eliminates a while lot of headaches around securing the database.

I have researched a few solutions to accomplish this efficiently:

  • give container direct access to the VPN => complicated Key management
  • Have a container running that can give other containers on a Host access to the VPN => not very elegant, and the container will get access to low level tooling on the host
  • Route container requests to IPs from the VPN through Wireguard directly => Best option that I have found.

The setup

In another post I am planning I will go through detailed steps to set up a secure cloud environment for personal projects. Here I would just like to outline the specifics of joining the container into the VPN.

The assumend setup is a database in a VPN and a container that needs access to this database and is running on a Host that is connected to the VPN. Setting up Wireguard should already be done and you will need the IP your Wireguard interface. The Firewall I am using is nftables

Get it done

The solution works in two steps:

  • create a docker network that will gain access to the VPN
  • Route the requests to IPs on the VPN on the newly created network through the Wireguard interface

Creating the network

docker network create --subnet 10.10.10.0/24

This will create a docker network with the IP range 10.10.10.0 - 10.10.10.255.

Give access to the VPN

Given that the Wireguard interface name is wg0 and its IP is 10.10.0.1 the following rules will do the trick.

nft add table nat
nft add chain nat prerouting { type nat hook prerouting priority 0 \; }
nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
nft add rule nat postrouting ip saddr 10.10.10.0/24 oifname wg0 snat 10.10.0.1
nft add rule nat postrouting masquerade

What this will do is to setup network address translation rules that say that every request that is originating from the IP range 10.10.10.0 - 10.10.10.255 and wants to go through the Wireguard interface wg0 will be disguised as originating from the Wireguard IP itself. When a response is received, this will automatically be done in the reverse direction.

Be aware though that this assumes that your routes are already set up correctly. Using the AllowedIPs configuration for Wireguard will do this. So if you want to access IPs 10.10.0.0 - 10.10.0.255 this would be set to 10.10.0.0/24.

End

Thats it. Your container should now be able to access the database without problems. Using this setup consistently and only allowing connetions to the database from your VPN should increase security significantly over exposing it via the internet directly.

I would also like to thank Nick Babcock, whose post gave me a nudge in the right direction.

unsplash-logoCover Photo by Mathew Schwartz

Back to overview