Files
notes/tiddlywiki/wireguard with Docker.md
2026-03-12 22:01:38 +01:00

3.6 KiB
Executable File

Be sure to have system up to date:

dnf update

Install kernel headers:

dnf install -y kernel-headers.x86_64 kernel-devel

Check:

ls -l /usr/src/kernels/$(uname -r)

Install wireguard kernel module:

dnf install -y epel-release elrepo-release -y
dnf install -y kmod-wireguard wireguard-tools

Create persistent directory for container:

mkdir -p /app/persistent_docker/wireguard
cd /app/persistent_docker/wireguard

Run container:

docker run -d \
  --name=wireguard \
  --cap-add=NET_ADMIN \
  --cap-add=SYS_MODULE \
  -e TZ=Europe/London \
  -e SERVERURL=ssh.databasepro.eu `#optional` \
  -e SERVERPORT=51820 `#optional` \
  -e PEERS=1 `#optional` \
  -e PEERDNS=auto `#optional` \
  -e INTERNAL_SUBNET=10.10.10.0 `#optional` \
  -e ALLOWEDIPS=0.0.0.0/0 `#optional` \
  -p 7006:51820/udp \
  -v /app/persistent_docker/wireguard:/config \
  -v /lib/modules:/lib/modules \
  --sysctl="net.ipv4.conf.all.src_valid_mark=1" \
  --restart unless-stopped \
  ghcr.io/linuxserver/wireguard

At the first run that will create configuration under /app/persistent_docker/wireguard

In logfiles, we have the QR-code to use clint side.

A client configuration ready to use is generated under /app/persistent_docker/wireguard/peer1

Example configuration server side:

[Interface]
Address = 10.10.10.1
ListenPort = 51820
PrivateKey = *******************************
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# peer1
PublicKey = *******************************
AllowedIPs = 10.10.10.2/32

Example configuration client side:

[Interface]
PrivateKey = *******************************
ListenPort = 51820
Address = 10.10.10.2/32
DNS = 10.10.10.1

[Peer]
PublicKey = *******************************
AllowedIPs = 0.0.0.0/0
Endpoint = ssh.databasepro.eu:41820

In the previous example, the NAT rule has been defined in the router: ssh.databasepro.eu:41820->(by UDP)->[docker host]:7006.

I guess it was something special on my system (maybe because the host is also Name Server) but to make it working I modified coredns/Corefile as:

. {
	forward . 1.1.1.1  192.168.0.8
}

If you want use docker-compose to start the container, docker-compose.yaml:

version: "2.1"
services:
  wireguard:
    image: ghcr.io/linuxserver/wireguard
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - TZ=Europe/London
      - SERVERURL=ssh.databasepro.eu #optional
      - SERVERPORT=51820 #optional
      - PEERS=1 #optional
      - PEERDNS=auto #optional
      - INTERNAL_SUBNET=10.10.10.0 #optional
      - ALLOWEDIPS=0.0.0.0/0 #optional
    volumes:
      - /app/persistent_docker/wireguard:/config
      - /lib/modules:/lib/modules
    ports:
      - 7006:51820/udp
    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1
    restart: unless-stopped

Start the container with docker-compose:

docker-compose up -d

Troubleshooting

One time, after a kernel upgrade, wireguard stopped to work with the error message:

iptables v1.6.1: can't initialize iptables table `filter': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.

Issue solved reloading iptable_nat module:

modprobe iptable_nat

To load automaticly this module on system reboot, create the file /etc/modules-load.d/iptable_nat.conf with the following contents:

iptable_nat