WireGuard Easy WireGuard Easy

[SSO] VPN Service

WireGuard® is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography. It aims to be faster, simpler, leaner, and more useful than IPsec, while avoiding the massive headache. It intends to be considerably more performant than OpenVPN. WireGuard is designed as a general purpose VPN for running on embedded interfaces and super computers alike, fit for many different circumstances. Initially released for the Linux kernel, it is now cross-platform (Windows, macOS, BSD, iOS, Android) and widely deployable. It is currently under heavy development, but already it might be regarded as the most secure, easiest to use, and simplest VPN solution in the industry.

Android - configure application exclusion, e.g. Android Auto: Open the Wireguard app, edit the profile, click “All Applications”, select the application you want to exclude.

Links:

Authentik OIDC

wg-easy v15 uses native OIDC for Authentik’s admins group. WireGuard peer keys and UDP traffic remain independent of browser SSO. Traefik still limits the UI to LAN/VPN through localaccess@file.

Setup

Set WG_EASY_AUTHENTIK_CLIENT_ID and WG_EASY_AUTHENTIK_CLIENT_SECRET in ignored config/docker/<host>/.env.wg-easy, then create the Authentik application:

scripts/authentik-apps.py --application wg-easy --apply
scripts/labctl.py service recreate security/wg-easy

Password authentication remains disabled. Before starting wg-easy, ensure an administrator can complete OIDC login through Authentik. For a v14 migration, import wg0.json into a separate v15 state directory and verify OIDC access before retiring the v14 deployment. Never mount v15 over the v14 state; retain v14 data as the rollback source.

The registered callbacks are https://vpn.<domain>/api/auth/oidc/callback and https://vpn.<domain>/api/auth/oidc/link.

Future Hardening

The current OIDC mapping marks every Authentik user’s email as verified. Before relying on email-based account linking beyond the initial administrator setup, consider creating a dedicated wg-easy-email-verified Authentik group and emitting email_verified: true only for its members. This makes email verification an explicit, reviewable approval rather than trusting every local or break-glass account.

Verify

Confirm an admins member can sign in through OIDC, a non-member is denied, the imported peers remain intact, and WireGuard clients continue connecting.

name: wg-easy
services:
  wg-easy:
    image: ghcr.io/wg-easy/wg-easy:15.4.0
    container_name: wg-easy
    hostname: wireguard-easy
    restart: unless-stopped
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      # v15 imports WireGuard settings and peers from the v14 wg0.json backup.
      # Initial v15 setup: create a temporary local admin, select "Yes" for an
      # existing setup, then upload the backed-up wg0.json file.
      # Link that existing local account to Authentik while signed in locally at
      # https://vpn.${MYDOMAIN}/api/auth/oidc/link. Test /api/auth/oidc in a
      # fresh session before setting DISABLE_PASSWORD_AUTH to "true".
      OAUTH_PROVIDERS: oidc
      OAUTH_AUTO_REGISTER: "false"
      OAUTH_OIDC_SERVER: https://sso.${MYDOMAIN}/application/o/wg-easy/
      OAUTH_OIDC_CLIENT_ID: ${WG_EASY_AUTHENTIK_CLIENT_ID}
      OAUTH_OIDC_CLIENT_SECRET: ${WG_EASY_AUTHENTIK_CLIENT_SECRET}
      OAUTH_OIDC_NAME: Authentik
      # Keep password login during setup. Disable it only after the local
      # administrator is linked to OIDC and a fresh OIDC session succeeds.
      DISABLE_PASSWORD_AUTH: "true"
    ports:
      - 51820:51820/udp # VPN
    # kics-scan ignore-block - WireGuard requires read-only access to kernel modules to load the wireguard module
    volumes:
      # Never mount v15 over v14 state: it remains the rollback source.
      - ${DOCKER_VOLUMES}/wg-easy-v15:/etc/wireguard
      - /lib/modules:/lib/modules:ro
    networks:
      - security-wg-easy
    labels:
      traefik.enable: true
      traefik.docker.network: security-wg-easy
      traefik.http.routers.wireguard.rule: Host(`vpn.${MYDOMAIN}`)
      # wg-easy v15 owns native OIDC; Traefik limits the setup UI to LAN/VPN.
      traefik.http.routers.wireguard.middlewares: localaccess@file
      traefik.http.services.wireguard.loadbalancer.server.port: 51821
      homepage.group: Security
      homepage.name: WireGuard Easy
      homepage.icon: wireguard.png
      homepage.href: https://vpn.${MYDOMAIN}/
      homepage.description: "[SSO] VPN Service"

networks:
  security-wg-easy:
    external: true