Easily setup Mullvad as an exit node for Tailscale using Docker
I'm a big fan of Tailscale. It's a great way to quickly and easily set up a VPN between all of my devices.
My home server is configured to only allow SSH connections over Tailscale, and I wanted a way to have that SSH connection running while also having external traffic be private with the help of Mullvad's VPN service.
Docker makes this easy by configuring the tailscale container to share the network stack of the mullvad container.
Setting up the containers
I use docker-compose to define the configuration.
These containers can be started by first copying the configuration below into a new docker-compose.yml
file.
Then, run docker-compose up -d
in the folder containing the docker-compose file.
version: "3.9"
services:
wireguard-mullvad:
image: ghcr.io/linuxserver/wireguard
container_name: mullvad-wireguard
cap_add:
- NET_ADMIN
- SYS_MODULE
environment:
- PUID=1420
- PGID=1420
- TZ=America/New_York
volumes:
- /services/mullvad/wireguard:/config:Z # edit path for config files
- /lib/modules:/lib/modules:ro
ports:
- 53000:51820/udp
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
- net.ipv6.conf.all.disable_ipv6=0
restart: unless-stopped
healthcheck:
test: curl --fail 1.1.1.1 || exit 1
interval: 10s
retries: 6
start_period: 10s
timeout: 2s
tailscale-mullvad:
container_name: tailscale-mullvad
image: tailscale/tailscale:latest
volumes:
- /services/mullvad/tailscale:/var/lib/tailscale # edit path for config files
- /lib/modules:/lib/modules:ro
cap_add:
- NET_ADMIN
- SYS_MODULE
command: tailscaled --tun=userspace-networking
restart: unless-stopped
sysctls:
- net.ipv4.ip_forward=1
- net.ipv6.conf.all.forwarding=1
depends_on:
- wireguard-mullvad
network_mode: service:wireguard-mullvad
healthcheck:
test: wget --no-verbose --tries=1 --spider tailscale.com || exit 1
interval: 10s
retries: 6
start_period: 10s
timeout: 2s
Configuring Mullvad
A wg0.conf file is needed, you can generate it on Mullvad's website.
The wg0.conf file should be placed in the wireguard container at /config/wg0.conf
. Adjust the path on your system depending on the bind mount path.
Restart the containers with docker-compose restart
.
Configuring Tailscale
Log into tailscale and configure it as an exit node with this command.
docker exec -it tailscale-mullvad-usa tailscale up --hostname=mullvad-usa --advertise-exit-node
Testing the connection
Follow steps 3 & 4 here to finish the exit node setup and connect to the exit node.
Mullvad provides a VPN leak tester here.