Securing Docker with Wireguard

Mark Percival
Apr 23, 2019 · 3 min read

I typically develop on a remote machine. That means I’m SSH’d (actually ‘mosh’) into a remote VPS, and doing all my development remotely via the terminal.

At some point, I added Docker to the mix. Docker improved my developer experience by allowing me to quickly spin up an environment on a remote machine and not have to worry about installing a bunch of stuff globally (Postgres, Redis, etc). But also learned that Docker alters your iptable rules in order to work and has the side effect of possibly exposing ports to the outside world if you’re not careful.

The goal of this article is to describe how I both secure Docker and access my remote instances via Wireguard.

Wireguard to the rescue

Setting up a VPN used to be a somewhat involved process, but Wireguard has changed that. Wireguard is remarkably fast, lightweight, and easy to set up on both the client an server.

There are plenty of articles on installing Wireguard, instead, I’ll focus on my setup for accessing remote services from your local machine while denying any public internet connections.

The summary of my setup is this:

  • The server is available via the Wireguard interface on a private IP address, for example,
  • I map in /etc/hosts to a hostname I want to use, let’s say
  • I block inbound eth0 (external) access to Docker via iptable rules, as recommended by the Docker docs.
  • Now I access like I normally would and have access to any running Docker instance that’s exposing a port.
  • Bonus: I use LetsEncrypt with DNS validation to create a valid certificate for This connection is already encrypted via Wireguard, but the certificate allows me to hit the development webserver with my local browser and be under valid HTTPS.

The nitty gritty details

Iptable Rules

It’s just 3 rules in the DOCKER-USER group for iptables. (Modifying the DOCKER-USER iptable chain is the Docker-preferred way to modify iptable rules that co-exist with Docker’s modifications)

sudo iptables -A DOCKER-USER -o eth0 -j RETURN
sudo iptables -A DOCKER-USER -i eth0 -m state --state ESTABLISHED,RELATED -j RETURN
sudo iptables -A DOCKER-USER -i eth0 -j DROP

Let’s break it down:

sudo iptables -A DOCKER-USER -o eth0 -j RETURN
sudo iptables -A DOCKER-USER -i eth0 -m state --state ESTABLISHED,RELATED -j RETURN

The first 2 rules allow for outbound traffic on `eth0`, and inbound return traffic from established and related connections. Basically allowing docker containers to freely talk to the outside world for connections it initiates.

sudo iptables -A DOCKER-USER -i eth0 -j DROP

The final instruction is what secures the docker instances, dropping any packets from eth0 that don’t match the above rules.

That’s it. Wireguard is amazing. I can open my laptop and not wait for the VPN to connect. I just get immediate access to my development box via a secure connection, and no more port forwarding/tunnels wrangling.

My Wireguard config

Client side

Address =
PrivateKey = {PrivateKey}
ListenPort = 21814

Server Side

Address =
SaveConfig = true
ListenPort = 995
PrivateKey = {PrivateKey}


This isn’t a perfect solution. You need to make sure you set up your iptable rules to persist after a reboot. You should also still practice good security habits. For example, don’t run your Postgres instance with no password just because it’s behind a firewall. Wireguard is a great VPN solution, but like all tools, it’s possible to misconfigure something and expose your remote system if you’re not careful. Layer your security accordingly.


Guide to installing Wireguard

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store