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
1500 − 80 = 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
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 | |
|---|---|---|
| Ort | Linux-Kernelmodul (seit Linux 5.6 im Mainline-Kernel) | Userspace-Programm, erzeugt ein TUN-Device |
| Sprache | C | Go |
| Plattformen | Linux (native Implementierungen auch für Windows: WireGuardNT, FreeBSD, OpenBSD) | Linux, macOS, Windows, BSD – überall, wo es TUN gibt |
| Leistung | kein Kontextwechsel pro Paket, sehr schnell | Kopien zwischen Kernel und Userspace; durch Optimierungen (z. B. GSO/GRO, Batching) inzwischen ebenfalls schnell |
| Typisch für | Server, Router, wg-quick unter Linux | macOS-/Android-Apps, Container ohne Kernelmodul, Tailscale (tailscaled bindet wireguard-go ein) |
| Protokoll | identisch – beide sprechen dasselbe Protokoll und können miteinander reden | identisch |