---
id: 2026-08-26-ubuntu-24-04-server-einen-eigenen-wireguard-vpn-server-einrichten
title: "WireGuard VPN-Server auf Ubuntu einrichten: Kompletter Guide"
slug: "ubuntu-24-04-server-einen-eigenen-wireguard-vpn-server-einrichten"
date: "2026-08-26 12:00:00"
updated: "2026-08-26 12:00:00"
author:
  name: "Sebastian Palencsár"
  handle: "sebastian"
category: "serverumgebungen"
tags: ["ubuntu", "wireguard", "vpn", "linux", "security", "netzwerk"]
reading_time: 22
excerpt: "Schritt-für-Schritt-Anleitung zur Einrichtung eines schnellen und sicheren WireGuard VPN-Servers unter Ubuntu mit Dual-Stack IPv4/IPv6, QR-Code-Setup und automatisiertem Client-Management."
---

WireGuard hat die Welt der virtuellen privaten Netzwerke (VPN) grundlegend revolutioniert. Im Gegensatz zu traditionellen Schwergewichten wie OpenVPN oder IPsec arbeitet WireGuard direkt als schlankes **Kernel-Modul**. Mit weniger als 4.000 Zeilen Quellcode bietet es minimale Angriffsfläche, modernste Kryptografie // [Curve25519](https://de.wikipedia.org/wiki/Curve25519){.badge-link-text}, [ChaCha20-Poly1305](https://de.wikipedia.org/wiki/ChaCha20){.badge-link-text}, [BLAKE2s](https://de.wikipedia.org/wiki/BLAKE2){.badge-link-text} // und maximale Datendurchsätze bei extrem niedriger Latenz.

Dieser Leitfaden führt dich durch die vollständige Einrichtung eines produktionsreifen WireGuard-Gateways unter **Ubuntu 24.04 LTS (Noble Numbat)** und **Ubuntu 26.04 LTS (Resolute Raccoon)** inklusive IPv4/IPv6 Dual-Stack, UFW-Firewall-Routing, Post-Quantum Pre-Shared Keys und automatisierter Peer-Generierung per QR-Code.

Die hier vermittelten Netzwerk- und Krypto-Grundlagen sind essenzieller Bestandteil moderner [Serverumgebungen](/de/category/serverumgebungen){.badge-link-text} und orientieren sich an Standards von Prüfungen wie der [LPIC-1 Serie](/de/category/lpic-1-serie){.badge-link-text}.

<blockquote class="infobox infobox--info">
💡 **Hinweis:** WireGuard ist seit Linux Kernel 5.6 fester Bestandteil des offiziellen Kernels. Unter Ubuntu 24.04 (Kernel 6.8) und Ubuntu 26.04 (Kernel 7.0) sind keine externen Repositories (PPAs) oder Kernel-Module aus Fremdquellen mehr erforderlich.
</blockquote>

<blockquote class="infobox infobox--tip">
🚀 **Vorteil gegenüber OpenVPN:** WireGuard kennt kein schwerfälliges Verbindungs-Handshake-Protokoll im Userspace. Verbindungen stehen sofort („Instant Connect“) und überstehen IP-Wechsel (z. B. vom WLAN ins 5G-Mobilfunknetz) ohne Verbindungsabbruch (Roaming).
</blockquote>

## WireGuard Architektur & Tunnel-Konzept

Im WireGuard-Modell sind alle Teilnehmer gleichberechtigte **Peers**. In der Server-Praxis dient der Ubuntu-Host als zentrales Gateway, das den Datenverkehr der Clients verschlüsselt annimmt und über die physische Netzwerkschnittstelle ins lokale Netz oder ins Internet weiterleitet (NAT / Masquerading):

```markdown
┌─────────────────────────────────────────────────────────────┐
│             WireGuard VPN Architektur & Tunnel              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   Remote Clients (Roadwarrior)      WireGuard Gateway       │
│   ┌───────────────────────────┐     ┌───────────────────┐   │
│   │ Laptop / Smartphone       │     │ Ubuntu Server     │   │
│   │ IP: 10.8.0.2 / fd42::2    │     │ IP: 10.8.0.1      │   │
│   └─────────────┬─────────────┘     └─────────┬─────────┘   │
│                 │                             │             │
│                 ▼                             ▼             │
│   ═══════════════════════════════════════════════════════   │
│       Verschlüsselter UDP-Tunnel (Port 51820 / ChaCha20)    │
│   ═══════════════════════════════════════════════════════   │
│                                               │             │
│                                               ▼             │
│                                 ┌───────────────────────┐   │
│                                 │ Internet & LAN-Netz   │   │
│                                 │ (NAT / Masquerading)  │   │
│                                 └───────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘
```

**Die wichtigsten Eckdaten des Setups:**

| Parameter | Wert / Konfiguration | Zweck |
|---|---|---|
| **VPN-Subnetz (IPv4)** | `10.8.0.0/24` | Privater Adressraum für Tunnel-Clients (Server: `10.8.0.1`) |
| **VPN-Subnetz (IPv6)** | `fd42:42:42::/64` | Eindeutige Local-IPv6-Adressen (Server: `fd42:42:42::1`) |
| **VPN-Port** | `51820 / UDP` | Standard-Port für eingehenden WireGuard-Traffic |
| **Verschlüsselung** | ChaCha20-Poly1305 + Noise Protocol | State-of-the-Art symmetrische Tunnelverschlüsselung |
| **Key-Austausch** | Curve25519 (ECDH) + Pre-Shared Key (PSK) | Asymmetrischer Schlüsselaustausch mit Post-Quantum Schutz |

## Vorbereitung & Installation

### 1. System aktualisieren & Pakete installieren

Installiere das WireGuard-Core-Tool `wireguard`, das Hilfswerkzeug `qrencode` (für Smartphone-QR-Codes) und `iptables`:

```bash
sudo apt update && sudo apt upgrade -y
sudo apt install wireguard wireguard-tools qrencode iptables -y
```

Überprüfe, ob das Kernelmodul geladen ist:

```bash
sudo modprobe wireguard
lsmod | grep wireguard
```

### 2. IP-Forwarding im Linux-Kernel aktivieren

Damit der Server Pakete aus dem VPN-Tunnel ins Internet weiterleiten darf, muss das IP-Forwarding für IPv4 und IPv6 im Kernel aktiviert werden. Erstelle dazu eine dedizierte Sysctl-Konfigurationsdatei:

```bash
sudo tee /etc/sysctl.d/99-wireguard.conf << 'EOF'
# IPv4 Packet Forwarding aktivieren
net.ipv4.ip_forward = 1

# IPv6 Packet Forwarding aktivieren
net.ipv6.conf.all.forwarding = 1
EOF
```

Lade die Kernel-Parameter sofort neu:

```bash
sudo sysctl -p /etc/sysctl.d/99-wireguard.conf
```

Prüfe die Ausgabe: Es sollte `net.ipv4.ip_forward = 1` und `net.ipv6.conf.all.forwarding = 1` erscheinen.

## Schlüsselgenerierung (Server & Peer)

WireGuard basiert auf Public-Key-Kryptografie: Jeder Knoten besitzt ein privates und ein öffentliches Schlüsselpaar. Zusätzlich generieren wir einen **Pre-Shared Key (PSK)** für eine zusätzliche symmetrische Verschlüsselungsebene.

Sichere das Konfigurationsverzeichnis mit strikten Rechten ab:

```bash
sudo mkdir -p /etc/wireguard
sudo chmod 700 /etc/wireguard
cd /etc/wireguard
```

Generiere die Serverschlüssel:

```bash
umask 077
wg genkey | tee server_private.key | wg pubkey > server_public.key
```

Zeige die Schlüssel an (notiere dir den öffentlichen Schlüssel):

```bash
echo "Server Public Key: $(cat server_public.key)"
```

## Server-Konfiguration (`wg0.conf`)

Ermittle zunächst den Namen deiner aktiven Standard-Netzwerkschnittstelle (z. B. `eth0`, `enp1s0` oder `ens3`):

```bash
ip -o -4 route show to default | awk '{print $5}'
```

*(Im folgenden Beispiel verwenden wir `eth0`. Falls dein Interface anders heißt, passe den Namen in den `PostUp`- und `PostDown`-Zeilen an).*

Erstelle die Konfigurationsdatei `/etc/wireguard/wg0.conf`:

```bash
SERVER_PRIV_KEY=$(cat /etc/wireguard/server_private.key)

sudo tee /etc/wireguard/wg0.conf << EOF
[Interface]
# Server-Tunnel-IPs (Dual-Stack)
Address = 10.8.0.1/24, fd42:42:42::1/64
ListenPort = 51820
PrivateKey = ${SERVER_PRIV_KEY}

# Firewall- & NAT-Regeln beim Start (PostUp) und Stopp (PostDown)
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -A FORWARD -o wg0 -j ACCEPT; ip6tables -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; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -D FORWARD -o wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

# Platzhalter für Clients (Peers)
EOF
```

Schütze die Datei mit restriktiven Dateirechten:

```bash
sudo chmod 600 /etc/wireguard/wg0.conf
```

## Firewall-Konfiguration (UFW)

Falls du die Uncomplicated Firewall (**UFW**) einsetzt, musst du den WireGuard-Port freigeben und das Routing erlauben:

### 1. Port 51820 UDP freigeben

```bash
sudo ufw allow 51820/udp comment 'WireGuard VPN'
```

### 2. Forwarding-Policy anpassen

Öffne `/etc/default/ufw` und stelle sicher, dass `DEFAULT_FORWARD_POLICY` auf `ACCEPT` steht:

```bash
sudo sed -i 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/' /etc/default/ufw
```

Lade die UFW-Regeln neu:

```bash
sudo ufw reload
```

## WireGuard Service starten & aktivieren

WireGuard bringt mit `wg-quick` einen praktischen Systemd-Wrapper mit. Starte das Interface `wg0`:

```bash
sudo systemctl enable --now wg-quick@wg0
```

Überprüfe den Status des VPN-Interfaces:

```bash
sudo wg show
```

Du solltest nun die Details deines aktiven Interfaces sehen:

```bash
interface: wg0
  public key: <DEIN_SERVER_PUBLIC_KEY>
  private key: (hidden)
  listening port: 51820
```

## Client (Peer) anlegen & verbinden

Nun erstellen wir die Konfiguration für den ersten Client (z. B. Smartphone oder Laptop).

### 1. Client-Schlüssel generieren

Erstelle ein separates Verzeichnis für Client-Profile:

```bash
mkdir -p /etc/wireguard/clients
cd /etc/wireguard/clients
umask 077

# Client 1 Keys
wg genkey | tee client1_private.key | wg pubkey > client1_public.key
wg genpsk > client1_preshared.key
```

### 2. Peer am Server registrieren

Füge den Client zu `/etc/wireguard/wg0.conf` hinzu:

```bash
CLIENT1_PUB=$(cat client1_public.key)
CLIENT1_PSK=$(cat client1_preshared.key)

sudo tee -a /etc/wireguard/wg0.conf << EOF

# Client 1: Smartphone / Laptop
[Peer]
PublicKey = ${CLIENT1_PUB}
PresharedKey = ${CLIENT1_PSK}
AllowedIPs = 10.8.0.2/32, fd42:42:42::2/128
EOF
```

Lade die Serverkonfiguration ohne Neustart des Interfaces neu:

```bash
sudo wg syncconf wg0 <(wg-quick strip wg0)
```

### 3. Client-Konfigurationsdatei erstellen

Ermittle die öffentliche IP-Adresse oder die Domain deines Servers (`SERVER_ENDPOINT`):

```bash
SERVER_ENDPOINT="vpn.deinedomain.de" # oder Server-IPv4
SERVER_PUB=$(cat /etc/wireguard/server_public.key)
CLIENT1_PRIV=$(cat client1_private.key)

tee /etc/wireguard/clients/client1.conf << EOF
[Interface]
PrivateKey = ${CLIENT1_PRIV}
Address = 10.8.0.2/24, fd42:42:42::2/64
DNS = 1.1.1.1, 9.9.9.9

[Peer]
PublicKey = ${SERVER_PUB}
PresharedKey = ${CLIENT1_PSK}
Endpoint = ${SERVER_ENDPOINT}:51820
# 0.0.0.0/0, ::/0 leitet den gesamten Traffic durch das VPN (Full Tunnel)
AllowedIPs = 0.0.0.0/0, ::/0
# Hält die Verbindung hinter NAT-Routern / Firewalls aufrecht
PersistentKeepalive = 25
EOF
```

<blockquote class="infobox infobox--tip">
💡 **Split-Tunneling:** Wenn du nur den Zugriff auf dein Heimnetz/Server über das VPN leiten möchtest, aber normales Surfen über die lokale Internetverbindung laufen soll, setze `AllowedIPs = 10.8.0.0/24, 192.168.1.0/24` (statt `0.0.0.0/0`).
</blockquote>

### 4. QR-Code für Smartphones erzeugen

Für die offizielle WireGuard-App (iOS / Android) kannst du die Konfigurationsdatei direkt im Terminal als scanbaren QR-Code ausgeben:

```bash
qrencode -t ansiutf8 < /etc/wireguard/clients/client1.conf
```

Öffne die WireGuard-App auf dem Smartphone, tippe auf **+** → **QR-Code scannen**, scanne den Terminal-Code und aktiviere den Tunnel.

## Automatisierung: Client-Management Script

Um neue Clients in Zukunft mit einem einzigen Befehl anzulegen, empfiehlt sich ein automatisiertes Verwaltungsscript.

Erstelle `/usr/local/bin/add-wireguard-client`:

```bash
sudo tee /usr/local/bin/add-wireguard-client << 'EOF'
#!/bin/bash
set -euo pipefail

if [ -z "${1:-}" ]; then
    echo "Verwendung: sudo add-wireguard-client <client-name> [client-ip-suffix]"
    echo "Beispiel:   sudo add-wireguard-client laptop 3"
    exit 1
fi

CLIENT_NAME="$1"
IP_SUFFIX="${2:-}"

WG_DIR="/etc/wireguard"
CLIENT_DIR="$WG_DIR/clients"
SERVER_PUB=$(cat "$WG_DIR/server_public.key")
SERVER_ENDPOINT=$(curl -s ifconfig.me || ip route get 1.1.1.1 | awk '{print $7}')

mkdir -p "$CLIENT_DIR"
cd "$CLIENT_DIR"
umask 077

# Automatische IP-Ermittlung falls nicht angegeben
if [ -z "$IP_SUFFIX" ]; then
    LAST_IP=$(grep -oE '10\.8\.0\.[0-9]+' "$WG_DIR/wg0.conf" | sort -t. -k4 -n | tail -1 | awk -F. '{print $4}' || echo 1)
    IP_SUFFIX=$((LAST_IP + 1))
fi

CLIENT_IPV4="10.8.0.${IP_SUFFIX}"
CLIENT_IPV6="fd42:42:42::${IP_SUFFIX}"

echo "==> Generiere Schlüssel für Peer: $CLIENT_NAME ($CLIENT_IPV4)..."
PRIV_KEY=$(wg genkey)
PUB_KEY=$(echo "$PRIV_KEY" | wg pubkey)
PSK=$(wg genpsk)

# Server-Konfiguration erweitern
tee -a "$WG_DIR/wg0.conf" > /dev/null << PEER_CONF

# Peer: ${CLIENT_NAME}
[Peer]
PublicKey = ${PUB_KEY}
PresharedKey = ${PSK}
AllowedIPs = ${CLIENT_IPV4}/32, ${CLIENT_IPV6}/128
PEER_CONF

# Live-Reload ohne Disconnect
wg syncconf wg0 <(wg-quick strip wg0)

# Client-Konfigurationsdatei schreiben
CONF_FILE="$CLIENT_DIR/${CLIENT_NAME}.conf"
tee "$CONF_FILE" > /dev/null << CLIENT_CONF
[Interface]
PrivateKey = ${PRIV_KEY}
Address = ${CLIENT_IPV4}/24, ${CLIENT_IPV6}/64
DNS = 1.1.1.1, 9.9.9.9

[Peer]
PublicKey = ${SERVER_PUB}
PresharedKey = ${PSK}
Endpoint = ${SERVER_ENDPOINT}:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25
CLIENT_CONF

echo "==> Konfiguration gespeichert in: $CONF_FILE"
echo ""
echo "=== QR-CODE FÜR MOBILE GERÄTE ==="
qrencode -t ansiutf8 < "$CONF_FILE"
EOF

sudo chmod +x /usr/local/bin/add-wireguard-client
```

Nun kannst du jederzeit beliebige neue Clients erstellen:

```bash
sudo add-wireguard-client tablet
sudo add-wireguard-client macbook 5
```

## Site-to-Site VPN: Standortvernetzung zweier Netzwerke

Während das Roadwarrior-Setup einzelne Endgeräte anbindet, koppelt ein **Site-to-Site VPN** zwei komplette physische oder virtuelle Netzwerke transparent miteinander. Geräte an Standort A (z. B. `192.168.10.0/24`) können direkt ohne Client-Software auf Server an Standort B (`192.168.20.0/24`) zugreifen:

```markdown
┌─────────────────────────────────────────────────────────────┐
│           Site-to-Site VPN: Standortvernetzung              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   Standort A (Office / Cloud)       Standort B (Home-Lab)   │
│   LAN: 192.168.10.0/24              LAN: 192.168.20.0/24    │
│   ┌───────────────────┐             ┌───────────────────┐   │
│   │ Gateway A (Ubuntu)│             │ Gateway B (Ubuntu)│   │
│   │ IP: 10.8.0.1      │             │ IP: 10.8.0.2      │   │
│   └─────────┬─────────┘             └─────────┬─────────┘   │
│             │                                 │             │
│             ▼                                 ▼             │
│   ═══════════════════════════════════════════════════════   │
│         Dauerhafter WireGuard-Tunnel (UDP Port 51820)       │
│   ═══════════════════════════════════════════════════════   │
│                                                             │
│   Transparentes Routing (ohne NAT):                         │
│   - Gateway A leitet 192.168.20.0/24 -> 10.8.0.2            │
│   - Gateway B leitet 192.168.10.0/24 -> 10.8.0.1            │
│                                                             │
└─────────────────────────────────────────────────────────────┘
```

### 1. Konfiguration Gateway A (`/etc/wireguard/wg0.conf`)

Gateway A fungiert als Responder mit öffentlich erreichbarer IP:

```ini
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <GATEWAY_A_PRIVATE_KEY>
# Forwarding zwischen LAN-Interface (eth0) und VPN-Interface (wg0)
PostUp = iptables -A FORWARD -i wg0 -o eth0 -j ACCEPT; iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -o eth0 -j ACCEPT; iptables -D FORWARD -i eth0 -o wg0 -j ACCEPT

# Peer: Gateway B
[Peer]
PublicKey = <GATEWAY_B_PUBLIC_KEY>
PresharedKey = <SITE_TO_SITE_PSK>
# Erlaube sowohl die Tunnel-IP als auch das gesamte Remote-Subnetz
AllowedIPs = 10.8.0.2/32, 192.168.20.0/24
```

### 2. Konfiguration Gateway B (`/etc/wireguard/wg0.conf`)

Gateway B baut die Verbindung aktiv zu Gateway A auf:

```ini
[Interface]
Address = 10.8.0.2/24
PrivateKey = <GATEWAY_B_PRIVATE_KEY>
PostUp = iptables -A FORWARD -i wg0 -o eth0 -j ACCEPT; iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT
PostDown = iptables -D FORWARD -i wg0 -o eth0 -j ACCEPT; iptables -D FORWARD -i eth0 -o wg0 -j ACCEPT

# Peer: Gateway A
[Peer]
PublicKey = <GATEWAY_A_PUBLIC_KEY>
PresharedKey = <SITE_TO_SITE_PSK>
Endpoint = gateway-a.deinedomain.de:51820
AllowedIPs = 10.8.0.1/32, 192.168.10.0/24
PersistentKeepalive = 25
```

<blockquote class="infobox infobox--tip">
💡 **Statische Route im Hauptrouter:** Damit Geräte in Standort A das Netz `192.168.20.0/24` erreichen, muss im Standard-Gateway (z. B. FRITZ!Box, pfSense) eine statische IPv4-Route hinterlegt werden: Ziel `192.168.20.0/24` via Gateway A (`192.168.10.254`).
</blockquote>

## Eigener DNS-Server & Interne Namensauflösung

In Unternehmens- und Homelab-Umgebungen sollen VPN-Clients oft nicht nur verschlüsselt ins Internet gelangen, sondern auch **interne Hostnamen** (z. B. `vaultwarden.intern` oder `nas.corp`) auflösen können, ohne dass DNS-Anfragen an öffentliche Resolver geschickt werden.

### 1. Unbound DNS-Resolver auf dem Server installieren

```bash
sudo apt install unbound -y
```

Erstelle die Konfiguration `/etc/unbound/unbound.conf.d/wireguard.conf`:

```bash
sudo tee /etc/unbound/unbound.conf.d/wireguard.conf << 'EOF'
server:
    interface: 10.8.0.1
    interface: 127.0.0.1
    access-control: 10.8.0.0/24 allow
    access-control: 127.0.0.0/8 allow
    
    # Datenschutz & DNSSEC
    hide-identity: yes
    hide-version: yes
    harden-glue: yes
    harden-dnssec-stripped: yes
    
    # Interne lokale Domäne auflösen
    local-zone: "intern." static
    local-data: "nas.intern. IN A 192.168.10.50"
    local-data: "wiki.intern. IN A 192.168.10.51"
    local-data: "router.intern. IN A 10.8.0.1"

# Upstream-DNS für alle externen Anfragen
forward-zone:
    name: "."
    forward-addr: 9.9.9.9        # Quad9 Primary
    forward-addr: 149.112.112.112 # Quad9 Secondary
EOF
```

Starte Unbound neu:

```bash
sudo systemctl enable --now unbound
```

### 2. Client-Konfiguration anpassen

Setze in den Client-Profilen die Server-Tunnel-IP als primären DNS:

```ini
[Interface]
DNS = 10.8.0.1, intern
```

Damit leitet der Client alle DNS-Abfragen an den integrierten Unbound-Resolver. Lokale Namen werden direkt aufgelöst, während externe Anfragen datenschutzfreundlich verschlüsselt ins Web weitergeleitet werden.

## Strikter VPN-Kill-Switch für mobile Clients

Auf mobilen Laptops (z. B. auf Reisen oder in offenen Hotel-WLANs) darf bei einem unerwarteten Abbruch des VPN-Tunnels keinesfalls unverschlüsselter Datenverkehr über das physische WLAN fließen (Schutz vor Datendiebstahl / Session-Hijacking).

### UFW Kill-Switch auf dem Linux-Client

Auf einem Linux-Client richtest du einen strikten Kill-Switch mit UFW ein:

```bash
# 1. Standard-Policy: Alles blockieren (eingehend und ausgehend)
sudo ufw default deny incoming
sudo ufw default deny outgoing

# 2. Ausgehenden Traffic über das WireGuard-Interface (wg0) erlauben
sudo ufw allow out on wg0 to any

# 3. Verbindungsaufbau zum WireGuard-Serverport über das physische Interface erlauben
sudo ufw allow out to <SERVER_IP> proto udp port 51820 comment 'WireGuard Server'

# 4. Lokalen LAN-Zugriff (optional) erlauben (z. B. Drucker / Router)
sudo ufw allow out to 192.168.1.0/24

# 5. UFW aktivieren
sudo ufw enable
```

<blockquote class="infobox infobox--warn">
⚠️ **Wirkung des Kill-Switches:** Reißt die WireGuard-Verbindung ab, blockiert die Firewall sofort jede Internetkommunikation. Es können keine unverschlüsselten Pakete unbemerkt über das offene WLAN fließen.
</blockquote>

## Monitoring & Fehlerbehebung

### Status & aktiven Datenverkehr prüfen

Mit `wg show` siehst du in Echtzeit alle verbundenen Clients, deren Endpunkte, den letzten Handshake sowie übertragene Datenmengen:

```bash
sudo wg show
```

Beispielausgabe bei erfolgreicher Verbindung:

```bash
interface: wg0
  public key: 4HkL...8Xg=
  private key: (hidden)
  listening port: 51820

peer: 4HkL...8Xg=
  preshared key: (hidden)
  endpoint: 203.0.113.42:54120
  allowed ips: 10.8.0.2/32, fd42:42:42::2/128
  latest handshake: 14 seconds ago
  transfer: 2.14 MiB received, 18.76 MiB sent
```

<blockquote class="infobox infobox--warn">
⚠️ **Handshake fehlt?** Wenn bei `latest handshake` kein Eintrag steht oder dieser älter als 2 Minuten ist, kommt kein Traffic an. Typische Ursachen:
1. UDP-Port `51820` ist in der Firewall des Cloud-Providers (z. B. Hetzner Cloud Firewall, AWS Security Group) blockiert.
2. Der Client versucht eine Verbindung über Port forwarding / IPv4, der Server-Provider nutzt aber DS-Lite / CGNAT.
3. Falscher Public Key in der Server- oder Client-Konfiguration eingetragen.
</blockquote>

### MTU-Probleme bei Webseiten-Ladehemmungen

Falls der VPN-Tunnel steht, aber manche Webseiten nicht laden oder hängenbleiben, liegt oft eine zu große MTU (Maximum Transmission Unit) vor. Standardmäßig nutzt WireGuard eine MTU von 1420 Bytes.

Passe in der Client-Konfiguration die MTU unter `[Interface]` manuell an:

```ini
MTU = 1360
```

## DNS-Leak-Test

Wenn der VPN-Tunnel aktiv ist, sollten alle DNS-Anfragen über den Tunnel laufen. Anderenfalls „leaken" deine DNS-Abfragen an den lokalen ISP und offenbaren deine Surfactivity.

### DNS-Konfiguration am Client prüfen

Stelle sicher, dass in der Client-Konfiguration unter `[Interface]` ein DNS-Server angegeben ist:

```ini
[Interface]
PrivateKey = <DEIN_PRIVAT_SCHLÜSSEL>
Address = 10.8.0.2/24, fd42:42:42::2/64
DNS = 1.1.1.1, 9.9.9.9
```

<blockquote class="infobox infobox--info">
💡 **Empfohlene DNS-Server:** Cloudflare (`1.1.1.1`, `1.0.0.1`) oder Quad9 (`9.9.9.9`, `149.112.112.112`) bieten DNS-over-HTTPS/TLS und gute Datenschutzrichtlinien.
</blockquote>

### DNS-Leak testen

1. Verbinde dich mit dem WireGuard-VPN
2. Öffne eine Website wie `https://dnsleaktest.com` oder `https://ipleak.net`
3. Führe einen **Standard Test** oder **Extended Test** durch
4. Die angezeigten DNS-Server sollten zum Standort des VPN-Servers gehören, nicht zu deinem lokalen ISP

**Alternativ per Terminal:**

```bash
# Prüfe welcher DNS-Server verwendet wird
resolvectl status | grep "DNS Server"

# DNS-Anfrage über den Tunnel senden
dig +short whoami.akamai.net @1.1.1.1
```

<blockquote class="infobox infobox--warn">
⚠️ **Tipp:** Falls DNS-Leaks auftreten, prüfe ob `DNS = ...` in der Client-Konfiguration gesetzt ist und ob der lokale DNS-Manager (z. B. `systemd-resolved`) den WireGuard-DNS nicht überschreibt.
</blockquote>

## nftables-Alternative für Fortgeschrittene

Ab Ubuntu 22.04 nutzt der Kernel standardmäßig `nftables` als Backdrop für `iptables`. Für produktive Server empfiehlt sich die direkte Nutzung von `nftables` statt der alter `iptables`-Kommandos.

### WireGuard-Regeln mit nftables

Erstelle eine dedizierte nftables-Konfigurationsdatei:

```bash
sudo tee /etc/nftables.d/wireguard.nft << 'EOF'
#!/usr/sbin/nft -f

# Eingehenden WireGuard-Traffic erlauben
add rule inet filter input udp dport 51820 accept

# Forwarding für WireGuard-Tunnel erlauben
add rule inet filter forward iifname "wg0" accept
add rule inet filter forward oifname "wg0" accept

# NAT/Masquerading für IPv4
add rule inet nat postrouting oifname "eth0" ip saddr 10.8.0.0/24 masquerade

# NAT/Masquerading für IPv6
add rule inet nat postrouting oifname "eth0" ip6 saddr fd42:42:42::/64 masquerade
EOF
```

Lade die Konfiguration:

```bash
sudo nft -f /etc/nftables.d/wireguard.nft
sudo systemctl enable nftables
```

<blockquote class="infobox infobox--tip">
💡 **Vorteil von nftables:** Bessere Performance bei großen Regelsätzen, atomare Updates (entweder alle Regeln oder keine), und konsistente Syntax statt der veralteten `iptables`-Legacy-API.
</blockquote>

## Logging & Monitoring

### WireGuard-Kernel-Debug aktivieren

WireGuard loggt standardmäßig absolut geräuschlos im Kernel. Für tiefergehendes Troubleshooting kannst du das dynamische Kernel-Debugging temporär aktivieren:

```bash
# WireGuard Dynamic Debugging im Kernel aktivieren
echo "module wireguard +p" | sudo tee /sys/kernel/debug/dynamic_debug/control

# Live-Log der Kernel-Meldungen für WireGuard anzeigen
sudo dmesg -wT | grep -i wireguard
```

Nach dem Debuggen kannst du das Logging wieder deaktivieren:

```bash
echo "module wireguard -p" | sudo tee /sys/kernel/debug/dynamic_debug/control
```

<blockquote class="infobox infobox--warn">
⚠️ **Vorsicht:** Dynamisches Kernel-Debugging erzeugt bei regem Datenverkehr viele Log-Einträge. Deaktiviere es nach erfolgreicher Fehlerdiagnose wieder.
</blockquote>

### Journalctl & Verbindungsüberwachung

```bash
# Letzte Systemd-Ereignisse von WireGuard anzeigen
journalctl -u wg-quick@wg0 --since "1 hour ago"

# Detaillierte Peer-Informationen und Transfer-Statistiken
sudo wg show wg0 dump

# Aktive UDP-Verbindungen auf Port 51820 prüfen
sudo ss -ulnp | grep 51820
```

## Performance & Tuning

### MTU-Optimierung

Die Standard-MTU von WireGuard (1420 Bytes) funktioniert in den meisten Netzwerken hervorragend. Bei Mobilfunkverbindungen (LTE/5G) oder DSL mit DS-Lite kann es jedoch zu Paketfragmentierung kommen.

Ermittle die optimale MTU per Ping ohne Fragmentierung:

```bash
# Optimale MTU ermitteln (PMTU-Discovery)
ping -M do -s 1392 -c 3 <SERVER_IP>
```

Falls Pakete verloren gehen, reduziere die MTU in der Client-Konfiguration unter `[Interface]`:

```ini
MTU = 1360
```

### TCP BBR Congestion Control

Um den Durchsatz über das Gateway zu maximieren (insbesondere bei schwankenden Ping-Zeiten im Mobilfunk), aktiviere Googles BBR-Algorithmus:

```bash
sudo tee /etc/sysctl.d/99-wireguard-performance.conf << 'EOF'
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
EOF

sudo sysctl -p /etc/sysctl.d/99-wireguard-performance.conf
```

### Firewall-Performance bei vielen Peers

Bei mehr als 50 aktiven Peers empfiehlt sich in `nftables` die Nutzung von Sets anstelle einzelner Filter-Regeln:

```bash
# Effizientes Peer-Set in nftables
sudo nft add set inet filter wireguard_peers '{ type ipv4_addr; }'
sudo nft add element inet filter wireguard_peers '{ 10.8.0.2, 10.8.0.3, 10.8.0.4 }'
sudo nft add rule inet filter forward ip saddr @wireguard_peers accept
```

## Fazit

WireGuard ist die modernste VPN-Lösung für Linux-Server: schlank, performant und mit erstklassiger Kryptografie. Die Einrichtung auf Ubuntu 24.04 LTS oder 26.04 LTS ist dank nativer Kernel-Integration in wenigen Minuten erledigt.

**Die wichtigsten Schritte im Überblick:**

1. **System vorbereiten:** Pakete installieren, IP-Forwarding aktivieren, Firewall konfigurieren
2. **Schlüssel erzeugen:** Server-Keys + Pre-Shared Key für jeden Client
3. **Server konfigurieren:** `wg0.conf` mit Dual-Stack IPv4/IPv6 und NAT-Regeln
4. **Clients anlegen:** Schlüssel generieren, Peer registrieren, Konfiguration per QR-Code übertragen
5. **Monitoring einrichten:** `wg show` für Status, DNS-Leak-Tests für Sicherheit

<blockquote class="infobox infobox--info">
💡 **Für die Praxis:** Beginne mit einem einzelnen Client und teste die Verbindung gründlich, bevor du weitere Peers hinzufügst. Das Automatisierungs-Script spart bei mehreren Geräten enorm viel Zeit.
</blockquote>

## Weiterführende Ressourcen

- [Linux Server Härtung: SSH mit FIDO2 & CrowdSec](/de/serverumgebungen/linux-server-haertung-fido2-crowdsec){.badge-link-text}
- [Ubuntu 24.04 auf 26.04 LTS Upgrade Guide](/de/serverumgebungen/ubuntu-upgrade-von-version-24-04-lts-auf-26-04-lts){.badge-link-text}
- [Linux Grundlagen: Dateirechte und chmod](/de/linux-neulinge/basics-bis-best-practices-alles-ueber-chmod-in-linux){.badge-link-text}
- [Netzwerkgrundlagen: Das OSI-Modell verstehen](/de/netzwerk/das-osi-modell-eine-detaillierte-einfuehrung-in-die-7-schichten){.badge-link-text}
- [LPIC-1 Serie: Linux-Administration](/de/category/lpic-1-serie){.badge-link-text}
