WireGuard Kernel-VPN & Cryptokey-Routing: Punkt-zu-Punkt- & Site-to-Site-Topologien
Erstellt: 08.11.2026 · Zuletzt aktualisiert: 08.11.2026 · Nejat Hakan
Management Summary: Veraltete VPN-Technologien wie OpenVPN und IPsec leiden unter immenser Code-Komplexität, zeitraubenden User-Space-Kontextwechseln und fehleranfälligen Schlüsselaushandlungen. Durch die direkte Integration in den Linux-Kernel (
wireguard.ko) revolutioniert WireGuard das verschlüsselte Tunneling: Mit weniger als 4.000 Zeilen prüfbarem C-Code kombiniert es modernste Kryptografie (Noise Protocol, Curve25519, ChaCha20-Poly1305) mit einem genialen architektonischen Prinzip: Cryptokey Routing.
-
Kernel-Space-Architektur
Erfahre, warum
wireguard.koMulti-Gigabit-Durchsätze erreicht, ohne die teuren User-to-Kernel-Kontextwechsel von TUN/TAP-Daemons zu durchlaufen. -
Cryptokey-Routing
Die Doppelfunktion von
AllowedIPsverstehen: Gleichzeitig interne Routingtabelle des Kernels und Ingress-Paketfilter. -
Punkt-zu-Punkt (Road Warrior)
Sichere Remote-Einwahl für Administratoren mit Split-Tunneling in das Firmen- oder Homelab-LAN inklusive automatischer
nftables-Maskierung. -
Site-to-Site-Vernetzung
Zwei entfernte Unternehmens- oder RZ-Standorte transparent über das Internet verbinden – ohne doppeltes NAT oder proprietäre Hardware.
1. Die WireGuard-Architektur: Minimalistisch & Unsichtbar
Während OpenVPN im User-Space läuft und jedes Paket über die Schnittstelle /dev/net/tun kopiert werden muss, arbeitet WireGuard direkt als Subsystem im Linux-Kernel:
%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
subgraph LEG["Altes VPN (OpenVPN)"]
direction TB
A1["Kernel-Netzwerk-Stack"] <-->|"Kontextwechsel (TUN)"| B1["User-Space OpenVPN<br/>TLS-Handshake, OpenSSL"]
end
subgraph WG["Modernes VPN (WireGuard)"]
direction TB
A2["Kernel-Netzwerk-Stack"] <-->|"Zero-Copy Direkt"| B2["wireguard.ko Modul<br/>ChaCha20-Poly1305"]
end
LEG -->|"Kernel-Architektur"| WG
Kryptografische Grundlagen
WireGuard verzichtet bewusst auf die Aushandlung von Verschlüsselungsverfahren, um Downgrade-Angriffe unmöglich zu machen: * Schlüsselaustausch: Noise Protocol Framework auf Basis von Curve25519 (Diffie-Hellman). * Verschlüsselung & Integrität: ChaCha20 für symmetrische Verschlüsselung in Kombination mit Poly1305 für die Authentifizierung (AEAD). * Hashing: BLAKE2s für Hashing und Schlüsselableitung. * Stealth-Modus: WireGuard antwortet niemals auf unauthorisierte Pakete. Port-Scanner sehen einen geschlossenen UDP-Port; der Server ist im Internet unsichtbar, bis ein kryptografisch gültiger Handshake eintrifft.
2. Das mentale Kernmodell: Cryptokey-Routing
Im traditionellen Netzwerkbetrieb werden Routingtabellen (ip route) und Paketfilter (iptables) getrennt verwaltet. WireGuard verschmilzt beides zu einem Konzept: Cryptokey Routing.
Jeder Peer wird im Kernel ausschließlich über seinen Public Key identifiziert, dem eine Liste von AllowedIPs zugeordnet ist:
%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
subgraph EGRESS["Ausgehend (Egress Routing)"]
direction TB
E1["Kernel sendet an Peer-IP"] --> E2{"AllowedIPs Treffer?"}
E2 -->|"Treffer"| E3["Mit Peer-Key verschlüsseln<br/>In UDP kapseln & senden"]
end
subgraph INGRESS["Eingehend (Ingress Filter)"]
direction TB
I1["UDP-Paket empfangen"] --> I2["Mit Peer-Key entschlüsseln"]
I2 --> I3{"Quell-IP in AllowedIPs?"}
I3 -->|"JA"| I4["In Netzwerk-Stack leiten"]
I3 -->|"NEIN"| I5["Lautlos verwerfen (Spoofing)"]
end
EGRESS -->|"Cryptokey Modell"| INGRESS
AllowedIPs erfüllt zwei Aufgaben gleichzeitig
- Für ausgehenden Verkehr (Routing): Es teilt dem Kernel mit: „Jedes Paket an diesen IP-Bereich muss verschlüsselt an diesen Peer gesendet werden.“
- Für eingehenden Verkehr (Firewall): Es dient als Filterregel: „Akzeptiere entschlüsselte Pakete dieses Peers nur, wenn seine innere Quell-IP in dieser Liste steht.“
3. Schlüsselpaare im Terminal generieren
WireGuard-Schlüssel sind Base64-codierte 32-Byte-Zeichenketten. Erzeuge sie mit dem Befehl wg:
# Server-Schlüsselpaar generieren
wg genkey | tee server_private.key | wg pubkey > server_public.key
# Client-Schlüsselpaar generieren
wg genkey | tee client_private.key | wg pubkey > client_public.key
# Optional: Pre-Shared Key (PSK) für quantenresistente Absicherung
wg genpsk > preshared.key
# Dateirechte absichern
chmod 600 *.key
4. Szenario 1: Punkt-zu-Punkt (Road-Warrior-Einwahl)
Ein Administrator verbindet sich von unterwegs mit einem zentralen Debian-VPN-Gateway, um auf interne LAN-Server zuzugreifen (192.168.1.0/24).
%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
LAPTOP["Laptop (Road Warrior)<br/>VPN: 10.200.0.2/24"] -->|"UDP 51820"| GW["Debian VPN-Gateway<br/>WAN: 203.0.113.10<br/>VPN: 10.200.0.1/24"]
GW -->|"Geroutet & NAT"| LAN["Firmen-LAN<br/>192.168.1.0/24"]
Gateway-Konfiguration (/etc/wireguard/wg0.conf)
Zunächst IPv4-Forwarding im Kernel aktivieren:
echo "net.ipv4.ip_forward=1" | sudo tee /etc/sysctl.d/60-wireguard-forward.conf
sudo sysctl --system
Konfiguration /etc/wireguard/wg0.conf anlegen:
# Datei: /etc/wireguard/wg0.conf (Server)
[Interface]
Address = 10.200.0.1/24
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>
# Beim Start NAT-Maskierung für LAN-Zugriff aktivieren, beim Stopp entfernen
PostUp = nft add table ip wg_nat; nft add chain ip wg_nat post { type nat hook postrouting priority 100 \; }; nft add rule ip wg_nat post oifname "eth0" masquerade
PostDown = nft delete table ip wg_nat
# Client: Laptop des Administrators
[Peer]
PublicKey = <CLIENT_PUBLIC_KEY>
PresharedKey = <PRESHARED_KEY>
AllowedIPs = 10.200.0.2/32
Client-Konfiguration (/etc/wireguard/wg0.conf)
# Datei: /etc/wireguard/wg0.conf (Client Laptop)
[Interface]
Address = 10.200.0.2/24
PrivateKey = <CLIENT_PRIVATE_KEY>
DNS = 192.168.1.1
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
PresharedKey = <PRESHARED_KEY>
Endpoint = 203.0.113.10:51820
# Split-Tunnel: Nur VPN- und internes LAN-Routing über den Tunnel leiten
AllowedIPs = 10.200.0.0/24, 192.168.1.0/24
# Hält NAT-Zustände hinter Mobilfunk/CGNAT-Firewalls dauerhaft offen
PersistentKeepalive = 25
(Für einen Full-Tunnel, der den gesamten Internetverkehr über das Gateway routet, setze AllowedIPs = 0.0.0.0/0, ::/0).
5. Szenario 2: Site-to-Site-Standortvernetzung
Verbinde zwei getrennte Netzwerke (Standort A: 192.168.10.0/24 und Standort B: 192.168.20.0/24) transparent über einen VPN-Tunnel:
%%{init: {'flowchart': {'wrappingWidth': 350}}}%%
flowchart TB
LANA["Standort A LAN<br/>192.168.10.0/24"] <--> GWA["Standort A Gateway<br/>VPN: 10.200.0.1/30"]
GWA <-->|"Verschlüsselter Tunnel"| GWB["Standort B Gateway<br/>VPN: 10.200.0.2/30"]
GWB <--> LANB["Standort B LAN<br/>192.168.20.0/24"]
Gateway Standort A
# Datei: /etc/wireguard/wg-site2site.conf (Standort A)
[Interface]
Address = 10.200.0.1/30
ListenPort = 51820
PrivateKey = <SITE_A_PRIVATE_KEY>
[Peer]
PublicKey = <SITE_B_PUBLIC_KEY>
Endpoint = site-b.example.com:51820
# Lokales Subnetz von Standort B über diesen Peer routen
AllowedIPs = 10.200.0.2/32, 192.168.20.0/24
PersistentKeepalive = 25
Gateway Standort B
# Datei: /etc/wireguard/wg-site2site.conf (Standort B)
[Interface]
Address = 10.200.0.2/30
ListenPort = 51820
PrivateKey = <SITE_B_PRIVATE_KEY>
[Peer]
PublicKey = <SITE_A_PUBLIC_KEY>
Endpoint = site-a.example.com:51820
# Lokales Subnetz von Standort A über diesen Peer routen
AllowedIPs = 10.200.0.1/32, 192.168.10.0/24
PersistentKeepalive = 25
6. NAT-Traversal & MTU-Optimierung
1. Carrier-Grade NAT (CGNAT) & Stateful Firewalls
Befindet sich ein Client hinter einem DS-Lite- oder Mobilfunkanschluss mit CGNAT (100.64.0.0/10), schließt die Provider-Firewall ungenutzte UDP-Sitzungen nach wenigen Sekunden Inaktivität.
Der Parameter PersistentKeepalive = 25 sendet alle 25 Sekunden ein winziges, authentifiziertes Ping-Paket, um die Firewall-Zustandstabelle dauerhaft geöffnet zu halten.
2. MTU-Dimensionierung: Paketfragmentierung verhindern
Klassisches Ethernet nutzt eine MTU von 1500 Byte. WireGuard kapselt Originalpakete in einen zusätzlichen UDP-Header:
Standard-Ethernet MTU: 1500 Byte
- Äußerer IPv4-Header: - 20 Byte (oder 40 Byte bei IPv6)
- Äußerer UDP-Header: - 8 Byte
- WireGuard Kapselungs-Header: - 32 Byte
- Authentifizierungs-Tag: - 16 Byte
------------------------------------------------------------------------
Optimale WireGuard-Tunnel-MTU: 1420 Byte (bzw. 1412 Byte bei IPv6)
Sollten HTTPS-Webseiten im Tunnel hängenbleiben, erzwinge TCP-MSS-Clamping in nftables:
# Datei: /etc/nftables.conf (In der forward-Chain)
chain forward {
type filter hook forward priority filter; policy drop;
# Passt die maximale Segmentgröße automatisch an die Pfad-MTU an
tcp flags syn tcp option maxseg size set rt mtu
}
7. Dienst-Steuerung & Live-Status
Tunnel mit wg-quick starten und dauerhaft als systemd-Service einbinden:
# Tunnel starten
sudo wg-quick up wg0
# Autostart beim Systemstart aktivieren
sudo systemctl enable --now wg-quick@wg0
Tunnelstatus in Echtzeit prüfen
Ausgabe:
interface: wg0
public key: jX9+B8...
private key: (hidden)
listening port: 51820
peer: 7kL2...
endpoint: 198.51.100.42:54210
allowed ips: 10.200.0.2/32
latest handshake: 1 minute, 14 seconds ago
transfer: 14.20 MiB received, 82.41 MiB sent
Handshake-Prüfung
Der Wert latest handshake zeigt an, ob der Tunnel aktiv ist. Liegt der letzte Handshake unter 3 Minuten, steht die Verbindung stabil. Fehlt dieser Wert, blockiert eine Firewall den UDP-Port 51820 oder die Schlüssel stimmen nicht überein.
8. Nächste Schritte
Mit gehärtetem OpenSSH, Stateful Firewalls und verschlüsselten WireGuard-Tunneln steht die Sicherheitsarchitektur. Im nächsten Schritt folgt das Werkzeug für die Tiefenanalyse des Netzwerkverkehrs:
-
Wire-Level Paketanalyse mit tcpdump & BPF
Pakete auf Bit-Ebene mitschneiden, Berkeley Packet Filters (BPF) konstruieren, TCP-Flags auswerten und PCAPs für Wireshark exportieren.