Sign inSign up

ljrh/wireguard

By ljrh

•Updated 20 days ago

Fork of linuxserver/wireguard container which addresses recent CVEs (as analyzed by docker scout).

Image
Networking
0

1.7K

ljrh/wireguard repository overview

⁠Intro

A security-patched build of linuxserver/wireguard⁠. It is a drop-in replacement: same base image, same s6 services, same environment variables, same /config layout. The only change is that CoreDNS is compiled from source with a current Go toolchain and pinned, patched dependencies instead of being installed from the Alpine package, so the image does not inherit CVEs from a stale Alpine coredns package.

WireGuard®⁠ is an extremely simple yet fast and modern VPN that utilises state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPsec, while avoiding the massive headache. WireGuard is designed as a general purpose VPN for running on embedded interfaces and super computers alike, fit for many different circumstances.

⁠Why this image exists

The upstream image installs CoreDNS from the Alpine repository. That package is rebuilt infrequently, so it regularly ships a CoreDNS release and Go toolchain that are several security releases behind. This image instead:

  • Clones the pinned CoreDNS release tag at build time
  • Builds it with a pinned, current Go 1.26.x toolchain (CGO_ENABLED=1, so /etc/hosts and resolv.conf behave the same as upstream)
  • Pins the Go modules that most often carry advisories (google.golang.org/grpc, go.etcd.io/etcd/client, golang.org/x/crypto, golang.org/x/mod) to fixed versions
  • Removes all build dependencies afterwards, so image size matches upstream
  • Is rebuilt with --pull --no-cache so the latest Alpine 3.23 package fixes (OpenSSL etc.) are always included

Every release is scanned with Docker Scout before it is pushed.

⁠Current build
ComponentVersion
Base imageghcr.io/linuxserver/baseimage-alpine:3.23
CoreDNS1.14.7 (built from source)
Go toolchain1.26.8
wireguard-tools1.0.20250521-r1
OpenSSL3.5.8-r0

Verify the CoreDNS build inside the image:

docker run --rm --entrypoint /usr/bin/coredns ljrh/wireguard:latest -version  
# CoreDNS-1.14.7  
# linux/amd64, go1.26.8, ...  

⁠Supported Architectures

Only the amd64 images are currently published. A Dockerfile.aarch64 is maintained in the repository in lock-step with the amd64 one and can be built locally on ARM64 hosts if required.

ArchitectureAvailableTag
x86-64✅latest, YYYYMMDD, coredns-x.y.z, patched-goX.Y.Z
arm64❌ (build locally)—
⁠Note on iptables

Some hosts may not load the iptables kernel modules by default. For the container to be able to load the iptables, you may need to assign the SYS_MODULE capability and add the optional /lib/modules volume mount.

⁠Server Mode

If the environment variable PEERS is set to a number or a list of strings separated by comma, the container will run in server mode and the necessary server and peer/client confs will be generated. The peer/client config qr codes will be output in the docker log if LOG_CONFS is set to true. They will also be saved in text and png format under /config/peerX in case PEERS is a variable and an integer or /config/peer_X in case a list of names was provided instead of an integer.

Variables SERVERURL, SERVERPORT, INTERNAL_SUBNET, PEERDNS, INTERFACE, ALLOWEDIPS and PERSISTENTKEEPALIVE_PEERS are optional variables used for server mode. Any changes to these environment variables will trigger regeneration of server and peer confs. Peer/client confs will be recreated with existing private/public keys. Delete the peer folders for the keys to be recreated along with the confs.

To add more peers/clients later on, you increment the PEERS environment variable or add more elements to the list and recreate the container.

To display the QR codes of active peers again, you can use the following command and list the peer numbers as arguments: docker exec -it wireguard /app/show-peer 1 4 5 or docker exec -it wireguard /app/show-peer myPC myPhone myTablet (Keep in mind that the QR codes are also stored as PNGs in the config folder).

The templates used for server and peer confs are saved under /config/templates. Advanced users can modify these templates and force conf generation by deleting /config/wg_confs/wg0.conf and restarting the container.

The container managed server conf is hardcoded to wg0.conf. However, the users can add additional tunnel config files with .conf extensions into /config/wg_confs/ and the container will attempt to start them all in alphabetical order. If any one of the tunnels fail, they will all be stopped and the default route will be deleted.

In server mode the bundled CoreDNS listens on the WireGuard interface address (10.13.13.1 by default) and forwards to the Docker host's resolvers. Peers use it automatically when PEERDNS=auto.

⁠Client Mode

Do not set the PEERS environment variable. Drop your client config(s) into the config folder as /config/wg_confs/<tunnel name>.conf and start the container. If there are multiple tunnel configs, the container will attempt to start them all. CoreDNS is not started in client mode.

⁠Usage

Note: Unless a parameter is flagged as 'optional', it is mandatory and a value must be provided.

services:  
  wireguard:  
    image: ljrh/wireguard:latest  
    container_name: wireguard  
    cap_add:  
      - NET_ADMIN  
      - SYS_MODULE #optional  
    environment:  
      - PUID=1000  
      - PGID=1000  
      - TZ=Etc/UTC  
      - SERVERURL=wireguard.domain.com #optional  
      - SERVERPORT=51820 #optional  
      - PEERS=1 #optional  
      - PEERDNS=auto #optional  
      - INTERNAL_SUBNET=10.13.13.0 #optional  
      - ALLOWEDIPS=0.0.0.0/0 #optional  
      - PERSISTENTKEEPALIVE_PEERS= #optional  
      - LOG_CONFS=true #optional  
    volumes:  
      - /path/to/wireguard/config:/config  
      - /lib/modules:/lib/modules #optional  
    ports:  
      - 51820:51820/udp  
    sysctls:  
      - net.ipv4.conf.all.src_valid_mark=1  
    restart: unless-stopped  

⁠Parameters

Containers are configured using parameters passed at runtime (such as those above). These parameters are separated by a colon and indicate <external>:<internal> respectively. For example, -p 8080:80 would expose port 80 from inside the container to be accessible from the host's IP on port 8080 outside the container.

ParameterFunction
-p 51820/udpwireguard port
-e PUID=1000for UserID
-e PGID=1000for GroupID
-e TZ=Etc/UTCspecify a timezone to use, see this list⁠.
-e SERVERURL=wireguard.domain.comExternal IP or domain name for docker host. Used in server mode. If set to auto, the container will try to determine and set the external IP automatically
-e SERVERPORT=51820External port for docker host. Used in server mode.
-e PEERS=1Number of peers to create confs for. Required for server mode. Can also be a list of names: myPC,myPhone,myTablet (alphanumeric only)
`-e PEERDNS=auto`DNS server set in peer/client configs (can be set as `8.8.8.8`). Used in server mode. Defaults to `auto`, which uses wireguard docker host's DNS via included CoreDNS forward.
-e INTERNAL_SUBNET=10.13.13.0Internal subnet for the wireguard and server and peers (only change if it clashes). Used in server mode.
-e ALLOWEDIPS=0.0.0.0/0The IPs/Ranges that the peers will be able to reach using the VPN connection. If not specified the default value is: '0.0.0.0/0, ::0/0' This will cause ALL traffic to route through the VPN, if you want split tunneling, set this to only the IPs you would like to use the tunnel AND the ip of the server's WG ip, such as 10.13.13.1.
-e PERSISTENTKEEPALIVE_PEERS=Set to all or a list of comma separated peers (ie. 1,4,laptop) for the wireguard server to send keepalive packets to listed peers every 25 seconds. Useful if server is accessed via domain name and has dynamic IP. Used only in server mode.
-e LOG_CONFS=trueGenerated QR codes will be displayed in the docker log. Set to false to skip log output.
-v /configContains all relevant configuration files.
-v /lib/modulesPath to host kernel module for situations where it's not already loaded.
--sysctl=Required for client mode.
--cap-add=NET_ADMINNecessary for Wireguard to create its VPN interface.
--cap-add=SYS_MODULENecessary for loading Wireguard kernel module if it's not already loaded.
--read-only=trueRun container with a read-only filesystem. Not supported in client mode.

⁠User / Group Identifiers

When using volumes (`-v` flags), permissions issues can arise between the host OS and the container, we avoid this issue by allowing you to specify the user `PUID` and group `PGID`.

Ensure any volume directories on the host are owned by the same user you specify and any permissions issues will vanish like magic.

In this instance PUID=1000 and PGID=1000, to find yours use id your_user as below:

id $USER 

Example output:

uid=1000(your_user) gid=1000(your_user) groups=1000(your_user)  

⁠Versions

Fork changelog (security-patch releases only; see the upstream repository for the full history):

  • 06.09.26: - Update CoreDNS to 1.14.7 and Go toolchain to 1.26.8 (fixes CVE-2026-39821, CVE-2026-56862, CVE-2026-56859, CVE-2026-56853, CVE-2026-46600, CVE-2026-42504, CVE-2026-33818 and further stdlib CVEs). Pin google.golang.org/grpc to v1.83.2 (GHSA-hrxh-6v49-42gf, CVE-2026-84304), go.etcd.io/etcd/client to v3.6.14 (CVE-2026-73500), golang.org/x/crypto to v0.56.0 (CVE-2026-78662, CVE-2026-56855, CVE-2026-56854) and golang.org/x/mod to v0.40.0 (CVE-2026-56865, CVE-2026-56864). Drop x/net pin as CoreDNS 1.14.7 already requires v0.57.0. Rebuild picks up OpenSSL 3.5.8-r0 from Alpine (CVE-2026-63073, CVE-2026-75803, CVE-2026-34182 and others).

  • Between these releases I took a break from maintaining.

  • 27.05.26: - Bump golang.org/x/net pin to v0.55.0 to fix CVE-2026-39821 (CRITICAL, CVSS 10.0 — IDNA Punycode validation bypass in ToASCII/ToUnicode).

  • 23.05.26: - Update CoreDNS to 1.14.3 (fixes CVE-2026-33190, CVE-2026-32936, CVE-2026-32934, CVE-2026-35579, CVE-2026-33489) and Go toolchain to 1.26.3 (fixes CVE-2026-42499, CVE-2026-39836, CVE-2026-39820, CVE-2026-33814, CVE-2026-33811). Pin golang.org/x/crypto to v0.52.0 (CVE-2026-46597) and golang.org/x/net to v0.53.0 (CVE-2026-33814) in CoreDNS build.

  • 22.04.26: - Remove jq from image to fix CVE-2026-32316 (heap buffer overflow). No fix available in Alpine 3.23 packages.

  • 11.04.26: - Rebase to Alpine 3.23. Upgrade Go toolchain to 1.26.2 to fix CVE-2026-32283 (crypto/tls deadlock) and CVE-2026-27140 (cmd/go build-time code execution). Update APKINDEX URL to v3.23.

  • 28.03.26: - Pin google.golang.org/grpc to v1.79.3 in CoreDNS build to fix CVE-2026-33186.

  • 11.03.26: - Update CoreDNS to 1.14.2 to fix CVE-2026-26017 and CVE-2026-26018.

  • 11.03.26: - Upgrade Go toolchain to 1.26.1 for CoreDNS build.

  • 02.03.26: - Update CoreDNS to 1.14.1 and Go to 1.25.7 to fix CVE-2025-61728, CVE-2025-61726, CVE-2025-68121, CVE-2025-61731, CVE-2025-68119 and additional security fixes in crypto/tls.

  • 01.01.26: - Update CoreDNS build to use Go 1.25.5 and update dependencies to fix CVEs. Add apk upgrade to build process.

  • 22.12.25: - Build CoreDNS from source with Go 1.24.11 to fix security vulnerabilities (CVE-2025-22871 and others).

⁠License, credits, use of LLM and disclaimer

This is an independent fork of linuxserver/docker-wireguard⁠ and is not endorsed by or affiliated with LinuxServer.io. All container design credit belongs to the LinuxServer.io team. The image is distributed under the same GPL-3.0 license as upstream; source for every published tag is available in the GitHub repository.

No warranty is provided. Use at your own risk. Claude Opus 4.8 has been used to create and maintain this changelog, as well as to perform testing and compilation of the containers before comitting to this repository. Security issues with this fork should be reported via GitHub issues; issues in WireGuard, CoreDNS or the LinuxServer.io base image should go to their respective projects. Please follow the latest WireGuard documentation.

Tag summary

Content type

Image

Digest

sha256:91a811a79…

Size

264 MB

Last updated

20 days ago

docker pull ljrh/wireguard