16. September 2026

Eigenes WireGuard VPN mit wg-easy und Docker einrichten

wg-easy mit WireGuard und Docker – VPN-Server, Web-Dashboard und verbundene Clients

WireGuard gehört zu den schnellsten und modernsten VPN-Lösungen. Die manuelle Verwaltung von Schlüsseln, Konfigurationsdateien und Clients kann jedoch schnell unübersichtlich werden.

Mit wg-easy lässt sich ein vollständiger WireGuard-Server inklusive übersichtlicher Weboberfläche als Docker-Container betreiben. Neue VPN-Clients können mit wenigen Klicks erstellt, als Konfigurationsdatei heruntergeladen oder direkt per QR-Code auf ein Smartphone übertragen werden.

In dieser Anleitung installieren wir wg-easy mit Docker Compose auf einem Linux-Server oder VPS. Die Verwaltungsoberfläche wird dabei zunächst nicht öffentlich ins Internet gestellt, sondern sicher über einen SSH-Tunnel geöffnet.


Was ist wg-easy?

wg-easy kombiniert zwei Komponenten in einem Container:

  • einen vollständigen WireGuard-VPN-Server
  • eine browserbasierte Verwaltungsoberfläche

Über die Weboberfläche können unter anderem:

  • WireGuard-Clients erstellt und gelöscht werden
  • Clients vorübergehend deaktiviert werden
  • QR-Codes für Smartphones angezeigt werden
  • WireGuard-Konfigurationen heruntergeladen werden
  • verbundene Clients überprüft werden
  • übertragene Daten angezeigt werden
  • zeitlich begrenzte Clients angelegt werden
  • Zwei-Faktor-Authentifizierung aktiviert werden

Zusätzlich unterstützt wg-easy IPv6, Prometheus-Metriken und serverseitige Firewall-Regeln pro Client.


Voraussetzungen

Für diese Anleitung benötigen wir:

  • einen Linux-Server oder VPS
  • Ubuntu 24.04 oder eine vergleichbare Linux-Distribution
  • eine öffentliche IPv4- oder IPv6-Adresse
  • SSH-Zugriff auf den Server
  • Docker und Docker Compose
  • einen geöffneten UDP-Port für WireGuard
  • optional einen DNS-Namen wie vpn.example.de

wg-easy unterstützt aktuell die Architekturen x86_64 und arm64. Damit kann es sowohl auf typischen VPS-Systemen als auch auf ARM-Servern wie einem Raspberry Pi betrieben werden.


Docker installieren

Falls Docker noch nicht installiert ist, kann die offizielle Installationsroutine verwendet werden:

curl -fsSL https://get.docker.com | sudo sh

Anschließend fügen wir unseren Benutzer der Docker-Gruppe hinzu:

sudo usermod -aG docker "$USER"

Danach einmal abmelden und erneut per SSH anmelden.

Die Installation kontrollieren wir mit:

docker --version
docker compose version

Beide Befehle sollten eine installierte Version anzeigen.


Installationsverzeichnis erstellen

Wir legen ein eigenes Verzeichnis für den wg-easy-Stack an:

sudo mkdir -p /opt/stacks/wg-easy
sudo chown -R "$USER":"$USER" /opt/stacks/wg-easy
cd /opt/stacks/wg-easy

Die Verzeichnisstruktur sieht anschließend so aus:

/opt/stacks/wg-easy/
└── docker-compose.yml


Docker-Compose-Datei erstellen

Nun erstellen wir die Compose-Datei:

nano docker-compose.yml

Folgenden Inhalt einfügen:

volumes:
  etc_wireguard:

services:
  wg-easy:
    image: ghcr.io/wg-easy/wg-easy:15
    container_name: wg-easy
    restart: unless-stopped

    networks:
      wg:
        ipv4_address: 10.42.42.42
        ipv6_address: fdcc:ad94:bacf:61a3::2a

    volumes:
      - etc_wireguard:/etc/wireguard
      - /lib/modules:/lib/modules:ro

    ports:
      - "51820:51820/udp"
      - "127.0.0.1:51821:51821/tcp"

    cap_add:
      - NET_ADMIN
      - SYS_MODULE

    sysctls:
      - net.ipv4.ip_forward=1
      - net.ipv4.conf.all.src_valid_mark=1
      - net.ipv6.conf.all.disable_ipv6=0
      - net.ipv6.conf.all.forwarding=1
      - net.ipv6.conf.default.forwarding=1

networks:
  wg:
    driver: bridge
    enable_ipv6: true
    ipam:
      driver: default
      config:
        - subnet: 10.42.42.0/24
        - subnet: fdcc:ad94:bacf:61a3::/64

Die Konfiguration orientiert sich an der offiziellen Compose-Datei von wg-easy. Das Projekt empfiehlt, für stabile Installationen den Major-Tag 15 anstelle eines unbestimmten Tags wie latest zu verwenden. Dadurch werden Updates innerhalb der Hauptversion installiert, ohne automatisch auf eine möglicherweise inkompatible neue Hauptversion zu wechseln.

Warum wird Port 51821 nur an localhost gebunden?

Die Zeile

- "127.0.0.1:51821:51821/tcp"

sorgt dafür, dass die Weboberfläche nur auf dem Server selbst erreichbar ist.

Der Verwaltungsport wird dadurch nicht direkt im Internet veröffentlicht. Für die Ersteinrichtung verwenden wir stattdessen einen verschlüsselten SSH-Tunnel.

Der eigentliche WireGuard-Port bleibt dagegen öffentlich erreichbar:

- "51820:51820/udp"


wg-easy starten

Vor dem Start prüfen wir die Compose-Datei:

docker compose config

Werden keine Fehler angezeigt, starten wir den Container:

docker compose up -d

Den Status überprüfen wir mit:

docker compose ps

Die laufenden Protokolle können wir mit folgendem Befehl anzeigen:

docker compose logs -f

Die Ausgabe wird mit Strg + C beendet.


Firewall konfigurieren

Für den WireGuard-Tunnel muss standardmäßig der UDP-Port 51820 erreichbar sein.

Bei Verwendung von UFW öffnen wir ihn mit:

sudo ufw allow 51820/udp

Falls SSH noch nicht freigegeben wurde:

sudo ufw allow OpenSSH

Anschließend kann die Firewall aktiviert werden:

sudo ufw enable

Den Status prüfen wir mit:

sudo ufw status

Port 51821/tcp muss nicht freigegeben werden, da die Weboberfläche nur über localhost und den SSH-Tunnel erreichbar ist. Die offizielle Dokumentation nennt UDP-Port 51820 als notwendigen externen WireGuard-Port.

Bei einem VPS muss der Port möglicherweise zusätzlich in der Firewall oder Sicherheitsgruppe des Hosting-Anbieters freigeschaltet werden.


SSH-Tunnel zur Weboberfläche aufbauen

Auf dem eigenen Computer öffnen wir ein Terminal und bauen einen SSH-Tunnel zum VPS auf:

ssh -L 51821:127.0.0.1:51821 benutzer@SERVER-IP

Beispiel:

ssh -L 51821:127.0.0.1:51821 [email protected]

Bei Verwendung eines SSH-Schlüssels:

ssh -i ~/.ssh/id_ed25519 \
  -L 51821:127.0.0.1:51821 \
  [email protected]

Solange diese SSH-Verbindung geöffnet bleibt, erreichen wir die wg-easy-Weboberfläche im Browser unter:

http://127.0.0.1:51821

Die Verbindung zur Weboberfläche läuft dabei durch den verschlüsselten SSH-Tunnel.


Ersteinrichtung durchführen

Beim ersten Aufruf startet der Einrichtungsassistent.

Zunächst legen wir den Administrator fest:

  • Benutzername
  • Passwort
  • Passwortbestätigung

Danach folgt die Konfiguration des WireGuard-Servers.

Host

Als Host tragen wir die Adresse ein, über die sich die VPN-Clients später verbinden.

Das kann beispielsweise eine Domain sein:

vpn.example.de

Alternativ kann die öffentliche IPv4-Adresse des Servers verwendet werden:

203.0.113.10

Bei einer direkten IPv6-Adresse müssen laut Dokumentation eckige Klammern verwendet werden:

[2001:db8:1234::10]

Port

Als Port verwenden wir:

51820

Der hier konfigurierte Port muss mit der Portfreigabe im Docker-Compose-Stack und in der Firewall übereinstimmen.

Nach Abschluss des Assistenten wird die WireGuard-Schnittstelle automatisch eingerichtet.


Einen WireGuard-Client erstellen

Nach der Anmeldung sehen wir die Clientübersicht.

Über die Schaltfläche zum Erstellen eines neuen Clients vergeben wir einen Namen, beispielsweise:

Notebook

oder:

Smartphone

wg-easy erzeugt anschließend automatisch:

  • einen privaten Schlüssel
  • einen öffentlichen Schlüssel
  • eine interne VPN-Adresse
  • eine vollständige WireGuard-Konfiguration

Für jeden Client stehen mehrere Möglichkeiten zur Verfügung.

Konfigurationsdatei herunterladen

Für einen Desktop-PC oder ein Notebook laden wir die Konfiguration als Datei herunter.

Die Datei trägt beispielsweise den Namen:

Notebook.conf

Diese Datei kann anschließend in den offiziellen WireGuard-Client importiert werden.

QR-Code verwenden

Auf Android oder iOS kann der QR-Code direkt mit der WireGuard-App gescannt werden.

Dazu:

  1. WireGuard-App öffnen
  2. neuen Tunnel hinzufügen
  3. „Aus QR-Code erstellen“ auswählen
  4. QR-Code aus wg-easy scannen
  5. Tunnel aktivieren

Der private Schlüssel ist Bestandteil des QR-Codes. Der QR-Code sollte deshalb niemals veröffentlicht oder an Dritte weitergegeben werden.


Verbindung testen

Nachdem der Tunnel auf dem Client aktiviert wurde, testen wir zunächst die öffentliche IP-Adresse.

Auf einem Linux-Client beispielsweise:

curl https://ifconfig.me

Wird die öffentliche IP-Adresse des VPN-Servers angezeigt, wird der gesamte Internetverkehr über WireGuard geleitet.

Zusätzlich kann die interne WireGuard-Adresse des Servers getestet werden:

ping 10.8.0.1

Die tatsächliche Adresse hängt von den im Einrichtungsassistenten gewählten Einstellungen ab.

In der wg-easy-Weboberfläche sollte der Client nach dem ersten erfolgreichen Handshake als verbunden erscheinen.


Split-Tunneling oder vollständiger VPN-Tunnel

Über die Einstellung Allowed IPs wird festgelegt, welcher Datenverkehr über den Tunnel geleitet wird.

Gesamten IPv4-Verkehr über das VPN leiten

0.0.0.0/0

Gesamten IPv4- und IPv6-Verkehr über das VPN leiten

0.0.0.0/0, ::/0

Nur ein internes Netzwerk erreichbar machen

192.168.10.0/24

Mehrere interne Netze verwenden

192.168.10.0/24, 192.168.20.0/24

Wichtig: Allowed IPs beeinflusst in erster Linie das Routing auf dem Client. Für echte serverseitige Zugriffsbeschränkungen sollte die per-Client-Firewall von wg-easy oder eine eigene Firewall verwendet werden.

Die per-Client-Firewall kann in der Administration aktiviert werden und erzwingt die erlaubten Ziele auf dem Server. Diese Funktion benötigt iptables beziehungsweise bei IPv6 zusätzlich ip6tables und wird in der Dokumentation derzeit noch als experimentell bezeichnet.


Clients über die Kommandozeile anzeigen

wg-easy besitzt zusätzlich eine CLI.

Die interaktive CLI starten wir mit:

cd /opt/stacks/wg-easy
docker compose exec -it wg-easy cli

Die vorhandenen Clients können dort aufgelistet werden:

clients:list

Der QR-Code eines Clients lässt sich ebenfalls über die Kommandozeile anzeigen:

clients:qr CLIENT-ID

Die entsprechende Client-ID ist in der Ausgabe von clients:list enthalten.


Administrator-Passwort zurücksetzen

Falls das Administrator-Passwort vergessen wurde, kann es über die CLI zurückgesetzt werden:

cd /opt/stacks/wg-easy
docker compose exec -it wg-easy cli db:admin:reset

Danach fordert wg-easy zur Eingabe eines neuen Passworts auf.

Alternativ kann das Passwort direkt als Argument übergeben werden:

docker compose exec -it wg-easy \
  cli db:admin:reset --password 'NEUES-SICHERES-PASSWORT'

Die interaktive Variante ist sicherer, weil das Passwort dann nicht in der Shell-History gespeichert wird.


wg-easy aktualisieren

Vor einem Update wechseln wir in das Stack-Verzeichnis:

cd /opt/stacks/wg-easy

Anschließend laden wir das aktuelle Image der verwendeten Hauptversion:

docker compose pull

Danach wird der Container neu erstellt:

docker compose up -d

Nicht mehr benötigte Images können anschließend entfernt werden:

docker image prune

Die offizielle Dokumentation empfiehlt für das Starten und Aktualisieren docker compose up beziehungsweise für das vollständige Entfernen docker compose down. docker compose start und stop sollen vermieden werden, da dabei inkonsistente Containerzustände entstehen können.


Backup erstellen

Die WireGuard-Konfiguration liegt in unserem Beispiel im Docker-Volume:

etc_wireguard

Zunächst ermitteln wir den tatsächlichen Namen:

docker volume ls | grep etc_wireguard

Anschließend erstellen wir ein Backup:

mkdir -p ~/backups
docker run --rm \
  -v wg-easy_etc_wireguard:/source:ro \
  -v "$HOME/backups":/backup \
  alpine \
  tar -czf /backup/wg-easy-$(date +%F).tar.gz -C /source .

Der Volume-Name wg-easy_etc_wireguard muss gegebenenfalls an die Ausgabe von docker volume ls angepasst werden.

Das Backup enthält sensible private Schlüssel. Es sollte daher verschlüsselt und ausschließlich an einem geschützten Speicherort aufbewahrt werden.


Weboberfläche dauerhaft über Traefik bereitstellen

Soll die Verwaltungsoberfläche später über eine Domain wie

https://vpn-admin.example.de

erreichbar sein, kann wg-easy hinter einem Reverse Proxy wie Traefik betrieben werden.

Dabei sollte Port 51821 nicht direkt am Host veröffentlicht werden. Stattdessen befinden sich Traefik und wg-easy in einem gemeinsamen Docker-Netzwerk. Traefik leitet HTTPS-Anfragen intern an Port 51821 des Containers weiter.

Die wg-easy-Dokumentation stellt dafür eine eigene Traefik-Anleitung bereit. Der dort gezeigte Dienst verwendet den internen Webport des Containers und ein gemeinsames externes Docker-Netzwerk.

Auch mit Reverse Proxy sollte die Verwaltungsoberfläche zusätzlich geschützt werden, beispielsweise durch:

  • die integrierte wg-easy-Anmeldung
  • Zwei-Faktor-Authentifizierung
  • eine IP-Allowlist
  • Authelia oder Authentik
  • Zugriff ausschließlich über das bereits bestehende VPN

Eine unverschlüsselte, öffentlich erreichbare Weboberfläche sollte vermieden werden. Die wg-easy-Dokumentation bezeichnet den Betrieb ohne Reverse Proxy und ohne HTTPS ausdrücklich als unsicher.


Wichtige Sicherheitshinweise

Beim Betrieb von wg-easy sollten einige Grundregeln beachtet werden:

  1. Die Weboberfläche nicht ungeschützt im Internet veröffentlichen.
  2. Ein langes und einzigartiges Administrator-Passwort verwenden.
  3. Nach Möglichkeit Zwei-Faktor-Authentifizierung aktivieren.
  4. Nur UDP-Port 51820 öffentlich freigeben.
  5. WireGuard-Konfigurationen und QR-Codes vertraulich behandeln.
  6. Nicht mehr benötigte Clients deaktivieren oder löschen.
  7. Regelmäßig Updates und Backups durchführen.
  8. Für produktive Systeme einen festen Major-Version-Tag verwenden.
  9. Den SSH-Zugriff ausschließlich mit Schlüsseln absichern.
  10. Zugriffsbeschränkungen tatsächlich testen und nicht nur konfigurieren.

Fazit

wg-easy macht den Betrieb eines eigenen WireGuard-VPN-Servers deutlich komfortabler. Besonders das Erstellen neuer Clients, der Export von Konfigurationsdateien und die QR-Code-Funktion erleichtern die tägliche Verwaltung.

Mit Docker Compose ist der Dienst schnell installiert und ebenso einfach aktualisiert. Wird die Weboberfläche nur über einen SSH-Tunnel, einen abgesicherten Reverse Proxy oder direkt über das VPN erreichbar gemacht, lässt sich wg-easy auch auf einem öffentlich erreichbaren VPS sicher betreiben.

Damit eignet sich wg-easy sowohl für den privaten Fernzugriff auf das Heimnetz als auch für den geschützten Zugriff auf Server, interne Anwendungen und Verwaltungsoberflächen.


Weiterführende Informationen

Leave a Reply

Your email address will not be published. Required fields are marked *


Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden.

WordPress Cookie Plugin von Real Cookie Banner