Using a Docker container for a Wireguard VPN server
I've been using Wireguard for a while when away from my house for a couple of reasons:
-
Access to my home network's servers, services, and resources.
-
Security, when accessing the internet via insecure wifi.
-
Ability to use my PiHole (DNS sinkhole).
It's been working great, but as with everything else, I wanted to put it in a Docker container.
The wireguard.yaml file:
---
version: "2.1"
services:
wireguard:
image: lscr.io/linuxserver/wireguard:1.0.20210914
container_name: wireguard
cap_add:
- NET_ADMIN
- SYS_MODULE
networks:
net192:
ipv4_address: 192.168.1.100
environment:
- PUID=1000
- PGID=1000
- TZ=America/Denver
volumes:
- /home/tom/.configs/wireguard/:/config
- /lib/modules:/lib/modules
ports:
- 51820:51820/udp
sysctls:
- net.ipv4.conf.all.src_valid_mark=1
restart: unless-stopped
networks:
macvlan_net:
external: true
---
The macvlan_net
is, as the name would suggest, a Docker MACVLAN network, so the Docker container will be able to get an IP on my local network (192.168.1.x).
docker-compose -f wireguard.yaml up -d
This Docker container is configured to use /config/ as the directory to store configuration information in, and not the default /etc/wireguard/.
From within the Docker container, generate the private and public keys:
wg genkey | tee /config/privatekey | wg pubkey | tee /config/publickey
The /config/wg0.conf file is similar to our previous Wireguard config file, with a few exceptions:
- There are no
ufw
commands, as ufw isn't installed in the container. - This container uses eth0 as it's public-facing interface.
- I'm using a non-default listen port (default for Wireguard is 51820).
[Interface]
Address = 10.0.0.1/24
SaveConfig = true
ListenPort = 51111
PrivateKey = +BfzlVJ6o1n8hRvW4nGhpbhsiyWsCKgIEja6F8alsVg=
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
I edited the wg0.conf file from the Docker host, not from the Docker container, as vim
(or vi
) is installed.
Once the server's wg0.conf file was created, it was a matter of bringing up the tunnel on the server, and adding peers (clients).
wg-quick up wg0
wg set wg0 peer 4uP7u9NxLSJbHnaYBwQXhF6iXIIzeOjr/U6lQ0kCH3A= allowed-ips 10.0.0.2
wg-quick save wg0
Once the server is set up and running, adding the tunnel on the client side is the same as a non-Docker Wireguard setup.
References
Docker Hub - linuxserver/wireguard https://hub.docker.com/r/linuxserver/wireguard