Note: This post was automatically migrated from Markdown to Typst using AI. Read more about the migration process here. Contact me if something in this post is off and bothering you.

Docker and Wireguard

Figure 1: A long, curved futuristic tunnel with blurred light trails conveying high speed motion.

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:

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:

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.

<a style="background-color:black;color:white;text-decoration:none;padding:4px 6px;font-family:-apple-system, BlinkMacSystemFont, &quot;San Francisco&quot;, &quot;Helvetica Neue&quot;, Helvetica, Ubuntu, Roboto, Noto, &quot;Segoe UI&quot;, Arial, sans-serif;font-size:12px;font-weight:bold;line-height:1.2;display:inline-block;border-radius:3px" href="https://unsplash.com/@cadop?utm_medium=referral&amp;utm_campaign=photographer-credit&amp;utm_content=creditBadge" target="_blank" rel="noopener noreferrer" title="Download free do whatever you want high-resolution photos from Mathew Schwartz"><span style="display:inline-block;padding:2px 3px"><svg xmlns="http://www.w3.org/2000/svg" style="height:12px;width:auto;position:relative;vertical-align:middle;top:-2px;fill:white" viewBox="0 0 32 32"><title>unsplash-logo</title><path d="M10 9V0h12v9H10zm12 5h10v18H0V14h10v9h12v-9z"></path></svg></span><span style="display:inline-block;padding:2px 3px">Cover Photo by Mathew Schwartz</span></a>