Communitygithub.com

Homelab-WireGuard-VPN

Einrichtung eines WireGuard-VPN-Servers, Konfiguration von Peers, Schlüsselerzeugung, Split-Tunneling vs. Full-Tunnel-Routing und Fernzugriff auf ein Heimnetzwerk von mobilen Geräten und Laptops. Verwenden Sie ihn, wenn Sie WireGuard für den Fernzugriff auf ein Heimnetzwerk einrichten oder zwischen Split- und Full-Tunnel-Routing entscheiden.

Was ist Homelab-WireGuard-VPN?

Diese Skill-Anleitung beschreibt die vollständige Einrichtung eines WireGuard-VPN-Servers für den Heimgebrauch. WireGuard ist ein schnelles, modernes VPN-Protokoll, das sich ideal für den Fernzugriff auf Heimnetzwerke eignet, da es einfacher zu konfigurieren ist als OpenVPN und schneller als die meisten Alternativen. Die Skill deckt die Serverinstallation auf Linux, die Erstellung von Schlüsselpaaren für Server und Clients, die Konfiguration von Peers (z.B. Telefon, Laptop) sowie die Entscheidung zwischen Split-Tunneling (nur Heimnetzwerkverkehr) und Full-Tunnel (gesamter Verkehr über das Heimnetz) ab. Zusätzlich werden Best Practices wie die Verwendung von DDNS für dynamische IPs, Fehlerbehebung bei Verbindungsproblemen und die Automatisierung der Peer-Konfiguration mit einem Python-Skript behandelt. Die Anleitung ist für Plattformen wie Raspberry Pi, Linux-Hosts, pfSense und Router geeignet.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/homelab-wireguard-vpn

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Homelab WireGuard VPN

WireGuard ist ein schnelles, modernes VPN-Protokoll. Es ist die richtige Wahl für den Fernzugriff auf ein Heimnetzwerk – einfacher zu konfigurieren als OpenVPN und schneller als die meisten Alternativen.

Alle Konfigurationsbeispiele zeigen gängige Einrichtungen. Überprüfen Sie jeden Befehl – insbesondere die iptables-Weiterleitungsregeln und Dateiberechtigungen für Schlüssel – bevor Sie sie auf Ihrem System anwenden, und führen Sie Änderungen in einem Wartungsfenster durch.

Wann verwenden

  • Einrichten eines WireGuard-Servers auf einem Raspberry Pi, Linux-Host, pfSense oder Router
  • Generieren von WireGuard-Schlüsselpaaren und Schreiben von Peer-Konfigurationsdateien
  • Konfigurieren des Fernzugriffs von einem Telefon oder Laptop auf ein Heimnetzwerk
  • Erklären von Split-Tunneling (nur Heimverkehr routen) vs. Full-Tunnel (gesamten Verkehr routen)
  • Fehlerbehebung bei WireGuard-Verbindungen, die nicht hochkommen
  • Automatisieren der Peer-Konfiguration für mehrere Clients

Wie WireGuard funktioniert

Ihr Telefon (WireGuard-Client)
    │
    │  Verschlüsselter UDP-Tunnel (Port 51820)
    │
Ihr Heimrouter (WireGuard-Server – benötigt eine öffentliche IP oder DDNS)
    │
    Ihr Heimnetzwerk (192.168.1.0/24, NAS, Pi, usw.)

Jedes Gerät hat ein Schlüsselpaar (öffentlicher + privater Schlüssel).
Der Server kennt den öffentlichen Schlüssel jedes Clients.
Der Client kennt den öffentlichen Schlüssel des Servers + Endpunkt (IP:Port).
Daten werden Ende-zu-Ende verschlüsselt, ohne zentralen Server oder Zertifizierungsstelle.

Server-Einrichtung (Linux)

# WireGuard installieren
sudo apt update && sudo apt install wireguard -y

# Server-Schlüsselpaar generieren – Dateien von Anfang an mit privaten Berechtigungen erstellen
sudo mkdir -p /etc/wireguard
sudo sh -c 'umask 077; wg genkey > /etc/wireguard/server_private.key'
sudo sh -c 'wg pubkey < /etc/wireguard/server_private.key > /etc/wireguard/server_public.key'

# Server-Konfiguration schreiben – den tatsächlichen privaten Schlüsselwert einfügen
# Speichern Sie private Schlüssel nicht in der Versionskontrolle und teilen Sie sie nicht
sudo tee /etc/wireguard/wg0.conf << 'EOF'
[Interface]
Address = 10.8.0.1/24              # VPN-Subnetz – Server bekommt .1
ListenPort = 51820
PrivateKey = <privaten_Server_Schlüssel_hier_einfügen>

# Bereichsbezogene Weiterleitungsregeln: VPN-Verkehr ein-/auslassen, kein pauschales FORWARD ACCEPT
PostUp   = iptables -A FORWARD -i wg0 -o eth0 -j ACCEPT
PostUp   = iptables -A FORWARD -i eth0 -o wg0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
PostUp   = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -o eth0 -j ACCEPT
PostDown = iptables -D FORWARD -i eth0 -o wg0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
# Telefon – durch den tatsächlichen öffentlichen Telefonschlüssel ersetzen
PublicKey = <öffentlicher_Telefon_Schlüssel>
AllowedIPs = 10.8.0.2/32

[Peer]
# Laptop – durch den tatsächlichen öffentlichen Laptop-Schlüssel ersetzen
PublicKey = <öffentlicher_Laptop_Schlüssel>
AllowedIPs = 10.8.0.3/32
EOF
sudo chmod 600 /etc/wireguard/wg0.conf

# eth0 durch den tatsächlichen Namen der ausgehenden Schnittstelle ersetzen
# Überprüfen mit: ip route show default

# IP-Weiterleitung aktivieren (erforderlich für das Routen von Datenverkehr durch den Server)
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system

# WireGuard starten und beim Booten aktivieren
sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0

Client-Konfiguration

# Für jedes Client-Gerät ein eindeutiges Schlüsselpaar generieren
# Auf dem Client oder auf dem Server ausführen und den privaten Schlüssel sicher übertragen – niemals im Klartext
umask 077
wg genkey | tee phone_private.key | wg pubkey > phone_public.key

# Client-Konfigurationsdatei (phone_wg0.conf):
[Interface]
PrivateKey = <privater_Telefon_Schlüssel>
Address = 10.8.0.2/32
DNS = 192.168.1.2                  # Optional: Pi-hole für DNS über den Tunnel verwenden

[Peer]
PublicKey = <öffentlicher_Server_Schlüssel>
Endpoint = your-home-ip.ddns.net:51820  # Ihre öffentliche IP oder DDNS-Hostname
AllowedIPs = 192.168.1.0/24            # Split-Tunnel: nur Heimnetzwerkverkehr
# AllowedIPs = 0.0.0.0/0, ::/0        # Full-Tunnel: gesamter Verkehr über VPN

PersistentKeepalive = 25              # NAT-Loch offen halten (erforderlich für mobile Clients)

Split-Tunnel vs. Full-Tunnel

# Split-Tunnel: AllowedIPs = 192.168.1.0/24
  Nur Datenverkehr, der für Ihr Heimnetzwerk bestimmt ist, geht über das VPN.
  Internetverkehr (YouTube, Spotify) geht direkt – bessere Leistung auf Mobilgeräten.
  Am besten für: "Ich möchte nur von überall auf mein NAS und meinen Pi zugreifen."

# Full-Tunnel: AllowedIPs = 0.0.0.0/0, ::/0
  GESAMTER Datenverkehr geht über Ihre Heim-Internetverbindung.
  Nützlich für: Nutzung des heimischen DNS/Pi-hole-Werbeblockers.
  Nachteil: Die heimische Upload-Geschwindigkeit wird überall zum Engpass.

# Multi-Subnetz-Split-Tunnel (häufigster Homelab-Anwendungsfall):
  AllowedIPs = 192.168.10.0/24, 192.168.20.0/24, 192.168.30.0/24, 10.8.0.0/24
  Routet alle Ihre VLANs durch den Tunnel; Internet bleibt direkt.

Schlüsselerzeugung und Peer-Verwaltung

import subprocess

def keypair_generieren() -> tuple[str, str]:
    """Erzeugt ein WireGuard-Schlüsselpaar. Gibt (privater_schlüssel, öffentlicher_schlüssel) zurück."""
    privat = subprocess.check_output(["wg", "genkey"]).decode().strip()
    öffentlich = subprocess.run(
        ["wg", "pubkey"], input=privat.encode(), capture_output=True
    ).stdout.decode().strip()
    return privat, öffentlich

def preshared_key_generieren() -> str:
    return subprocess.check_output(["wg", "genpsk"]).decode().strip()

def client_konfiguration_erstellen(
    client_privater_schlüssel: str,
    client_vpn_ip: str,       # z.B. "10.8.0.3"
    server_öffentlicher_schlüssel: str,
    server_endpunkt: str,     # z.B. "home.example.com:51820"
    erlaubte_ips: str = "192.168.1.0/24",
    dns: str = "",
) -> str:
    dns_zeile = f"DNS = {dns}\n" if dns else ""
    return f"""[Interface]
PrivateKey = {client_privater_schlüssel}
Address = {client_vpn_ip}/32
{dns_zeile}
[Peer]
PublicKey = {server_öffentlicher_schlüssel}
Endpoint = {server_endpunkt}
AllowedIPs = {erlaubte_ips}
PersistentKeepalive = 25
"""

def server_peer_block_erstellen(
    client_öffentlicher_schlüssel: str,
    client_vpn_ip: str,
    kommentar: str = "",
) -> str:
    kommentar_zeile = f"# {kommentar}\n" if kommentar else ""
    return f"""
{kommentar_zeile}[Peer]
PublicKey = {client_öffentlicher_schlüssel}
AllowedIPs = {client_vpn_ip}/32
"""

Halten Sie private Schlüssel aus der Versionskontrolle fern. Wenn Sie dieses Skript verwenden, schreiben Sie Schlüsselmaterial in Dateien mit Modus 600 und protokollieren oder drucken Sie es niemals aus.

pfSense / OPNsense WireGuard

# pfSense: VPN → WireGuard → Tunnel hinzufügen
  Schnittstellenschlüssel: Generieren (erstellt automatisch Schlüsselpaar)
  Listen-Port: 51820
  Schnittstellenadresse: 10.8.0.1/24

# Peer hinzufügen (einen pro Client):
  Öffentlicher Schlüssel: <client öffentlicher schlüssel>
  Erlaubte IPs: 10.8.0.2/32

# WireGuard-Schnittstelle zuweisen:
  Schnittstellen → Zuweisungen → Hinzufügen (wg0 auswählen)
  Schnittstelle aktivieren, keine IP erforderlich (wird in der Tunnelkonfiguration festgelegt)

# Firewall-Regeln:
  WAN → eingehenden UDP-Port 51820 erlauben (damit Clients den Server erreichen können)
  WireGuard-Schnittstelle → Datenverkehr zu LAN-Netzwerken erlauben, die erreichbar sein sollen

DDNS (Dynamisches DNS) für Heimserver

Die meisten Heim-Internetverbindungen haben eine dynamische IP. Verwenden Sie DDNS, damit Ihr VPN-Endpunkt nach einem IP-Wechsel erreichbar bleibt.

# Option 1: Cloudflare DDNS – speichern Sie Anmeldeinformationen in einer Secrets-Datei, nicht inline
# docker-compose-Eintrag mit einer env-Datei:
  ddns-updater:
    image: qmcgaw/ddns-updater
    env_file: ./ddns.env   # zone_id und token hier speichern, nicht im compose
    restart: unless-stopped

# ddns.env (chmod 600, nicht in Git eingecheckt):
# SETTINGS_CLOUDFLARE_ZONE_ID=your_zone_id
# SETTINGS_CLOUDFLARE_TOKEN=your_api_token

# Option 2: DuckDNS (kostenlos, einfach)
  Registrieren Sie sich bei duckdns.org → erhalten Sie einen Token und eine Subdomain (myhome.duckdns.org)
  Speichern Sie den Token in /etc/ddns.env (Modus 600), verwenden Sie dann ein kleines root-eigenes Skript:

  # /usr/local/bin/update-duckdns
  #!/bin/sh
  set -eu
  . /etc/ddns.env
  curl --fail --silent --show-error --max-time 10 \
    --get "https://www.duckdns.org/update" \
    --data-urlencode "domains=myhome" \
    --data-urlencode "token=${DUCKDNS_TOKEN}" \
    --data-urlencode "ip="

  # Cron-Job:
  */5 * * * * /usr/local/bin/update-duckdns >/dev/null 2>&1

Fehlerbehebung

# WireGuard-Status und letzten Handshake überprüfen
sudo wg show

# Wenn "latest handshake" nie oder sehr alt ist, ist der Tunnel nicht verbunden.
# Überprüfen Sie:
# 1. Ist UDP-Port 51820 auf dem Router/der Firewall geöffnet?
sudo ufw status  # oder pfSense/UniFi-Firewall-Regeln prüfen

# 2. Ist der öffentliche Schlüssel des Servers in der Client-Konfiguration korrekt?
sudo wg show wg0 public-key   # Mit dem in der Client-Konfiguration vergleichen

# 3. Ist die IP-Weiterleitung auf dem Server aktiviert?
cat /proc/sys/net/ipv4/ip_forward  # Sollte 1 sein

# 4. Deckt AllowedIPs des Clients die IP ab, die Sie erreichen möchten?
# Wenn AllowedIPs = 192.168.1.0/24 und Sie versuchen, 192.168.3.5 zu erreichen, wird es nicht geroutet.

# Kernel-Logs auf WireGuard-Fehler überprüfen
dmesg | grep wireguard

# WireGuard neu starten
sudo wg-quick down wg0 && sudo wg-quick up wg0

Anti-Patterns

# SCHLECHT: Private Schlüssel in der Versionskontrolle speichern oder teilen
# Private Schlüssel sind gleichwertig mit Passwörtern – niemals in Git einchecken

# SCHLECHT: Verwendung von AllowedIPs = 0.0.0.0/0 auf Mobilgeräten ohne Berücksichtigung der Auswirkungen
# Full-Tunnel routet den gesamten mobilen Datenverkehr über Ihren Heim-Upload – normalerweise langsam

# SCHLECHT: Kein PersistentKeepalive auf mobilen Clients setzen
# Mobile Clients hinter NAT lassen Leertunnel ohne dies fallen

# SCHLECHT: Port 51820 in der Firewall öffnen, aber IP-Weiterleitung auf dem Server vergessen
# Tunnel verbindet, aber kein Datenverkehr wird geroutet – verwirrend bei der Fehlersuche

# SCHLECHT: Ein Schlüsselpaar auf mehreren Client-Geräten teilen
# Jedes Gerät muss sein eigenes eindeutiges Schlüsselpaar haben – geteilte Schlüssel brechen das Sicherheitsmodell

# SCHLECHT: Verwendung einer breiten "FORWARD ACCEPT" iptables-Regel
# Bereichsbezogene Weiterleitungsregeln nur für die wg0-Schnittstelle und Richtung verwenden

Best Practices

  • Generieren Sie ein eindeutiges Schlüsselpaar pro Client-Gerät – verwenden Sie Schlüssel niemals wieder
  • Verwenden Sie Split-Tunneling (AllowedIPs = <Heimsubnetze>) für Mobilgeräte
  • Setzen Sie PersistentKeepalive = 25 auf allen mobilen Clients
  • Verwenden Sie DDNS, wenn Ihr ISP eine dynamische IP zuweist; speichern Sie Anmeldeinformationen in Umgebungsdateien, nicht inline
  • Verwenden Sie bereichsbezogene iptables-Weiterleitungsregeln (eingehend nur auf wg0) anstelle eines pauschalen FORWARD ACCEPT
  • Fügen Sie die IP des Pi-hole als DNS = in Client-Konfigurationen hinzu, um Werbeblocker über das VPN zu erhalten
  • Rotieren Sie das Server-Schlüsselpaar regelmäßig und aktualisieren Sie alle Client-Konfigurationen

Verwandte Skills

  • homelab-network-setup
  • homelab-vlan-segmentation
  • homelab-pihole-dns

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

Verwandte Skills