WireGuard · Transport

📦Datenpakete, Overhead & MTU

Nach dem Handshake besteht jede WireGuard-Nachricht aus einem 16-Byte-Kopf und dem mit ChaCha20-Poly1305 verschlüsselten inneren IP-Paket. Daraus folgt die bekannte Standard-MTU von 1420.
🔢 Der Zähler als Nonce
Jede Richtung zählt ab 0. Der 64-Bit-Zähler steht im Klartext im Kopf und bildet die 96-Bit-Nonce für ChaCha20-Poly1305 (4 Null-Bytes + Zähler, Little Endian). Eine Nonce wird mit demselben Schlüssel nie zweimal benutzt.
🛡️ Replay-Schutz
Der Empfänger merkt sich in einem Schiebefenster (Bitmap nach RFC 6479), welche Zählerstände er schon gesehen hat. Doppelte oder zu alte Pakete werden verworfen – leicht vertauschte Reihenfolge (UDP!) ist aber erlaubt.
🧾 Kein Zustand ohne Grund
Datenpakete werden nur über receiver_index der Sitzung zugeordnet – kein Nachschlagen per IP-Adresse. Das macht Roaming möglich.

📐Warum 1420?

Die Rechnung für den ungünstigsten Fall (äußeres IPv6), damit dieselbe MTU unabhängig vom Transportweg passt:
MTU der Leitung (Ethernet)1500
− äußerer IPv6-Kopf− 40
− UDP-Kopf− 8
− WireGuard-Kopf (Typ 1 + reserviert 3 + Index 4 + Zähler 8)− 16
− Poly1305-Authentisierungs-Tag− 16
= Tunnel-MTU (wg-quick-Standard)1420

Mit reinem IPv4 als Transport wären 1440 möglich (60 statt 80 Byte Overhead). Bei PPPoE (MTU 1492) passen nur 1412 – sonst drohen Fragmentierung oder „hängende“ TLS-Verbindungen. Tailscale wählt mit 1280 bewusst das IPv6-Minimum, um auch auf exotischen Strecken sicher zu sein.

🧮Paketrechner

Größe des inneren Pakets, äußeres Protokoll und Leitungs-MTU wählen – die Balken zeigen den Aufbau Byte für Byte.
Äußeres Protokoll (Transport zwischen den Peers)
MTU der Leitung: 1500
Größe des inneren IP-Pakets: 84 Byte
Tunnel-MTU
150080 = 1420
40 IP + 8 UDP + 16 WG-Kopf + 16 Tag = 80 Byte Overhead
📦 Paket auf der Leitung
176 Byte von max. 1500
84
äußerer IP-Kopf
40 B
UDP
8 B
WG-Kopf (Typ, Index, Zähler)
16 B
inneres Paket (verschlüsselt)
84 B
Polsterung
12 B
Poly1305-Tag
16 B
Leitung = IP 40 + UDP 8 + WG-Kopf 16 + ⌈84⌉₁₆ 96 + Tag 16 = 176 Byte
Effizienz = 84 / 176 = 47.7 % Nutzlast

Das innere Paket wird vor dem Verschlüsseln mit Nullen auf ein Vielfaches von 16 Byte aufgefüllt (verschleiert die genaue Länge), aber nie über die Tunnel-MTU hinaus. Ein Keepalive ist ein Datenpaket ohne Inhalt: 16 Byte Kopf + 16 Byte Tag = 32 Byte, mit IPv4/UDP 60 Byte auf der Leitung.

🚶Roaming – der Endpoint wandert mit

WireGuard merkt sich als Endpoint immer die Absenderadresse des letzten authentisierten Pakets. Deshalb überlebt ein Tunnel den Wechsel von WLAN zu Mobilfunk.
Schritt 1/5
📶 Heim-WLAN198.51.100.7:51000📡 Mobilfunk (CGNAT)192.0.2.99:38211💻🖥️ ServerEndpoint des Laptops:198.51.100.7:51000
Laptop im Heim-WLAN

Der Server hat als Endpoint des Laptops 198.51.100.7:51000 gespeichert – die Adresse, von der das letzte gültige Paket kam.

🐧Kernel vs. wireguard-go

Kernel (Linux)wireguard-go
OrtLinux-Kernelmodul (seit Linux 5.6 im Mainline-Kernel)Userspace-Programm, erzeugt ein TUN-Device
SpracheCGo
PlattformenLinux (native Implementierungen auch für Windows: WireGuardNT, FreeBSD, OpenBSD)Linux, macOS, Windows, BSD – überall, wo es TUN gibt
Leistungkein Kontextwechsel pro Paket, sehr schnellKopien zwischen Kernel und Userspace; durch Optimierungen (z. B. GSO/GRO, Batching) inzwischen ebenfalls schnell
Typisch fürServer, Router, wg-quick unter LinuxmacOS-/Android-Apps, Container ohne Kernelmodul, Tailscale (tailscaled bindet wireguard-go ein)
Protokollidentisch – beide sprechen dasselbe Protokoll und können miteinander redenidentisch