Sie nutzen ein selbst gehostetes VPN. Sie fragen sich, was passiert, wenn der Tunnel während eines sensiblen Uploads für 12 Sekunden abbricht. In den meisten Standard-Linux-Konfigurationen: fließt der Verkehr unverschlüsselt über Ihre Standardroute, ohne sichtbare Anzeichen. Lokale DNS-Lecks, die echte IP erscheint in den Protokollen des entfernten Servers. Ein App-basierter Kill-Switch wird Sie nicht retten — dies muss auf Kernel-Ebene blockiert werden.
Diese Anleitung richtet einen iptables + systemd Kill-Switch ein, der garantiert, dass nichts unverschlüsselt Ihre Maschine verlässt, selbst während der 50 ms Lücke zwischen zwei WireGuard-Handshakes.
Warum ein Netfilter-Kill-Switch die einzige ernsthafte Garantie ist
Die kommerzielle VPN-Branche spricht seit sieben Jahren über "Kill-Switches", aber die meisten Implementierungen sind fragil, da sie auf Anwendungsebene arbeiten: Die NordVPN- oder ExpressVPN-App erkennt einen Tunnelabbruch und unterbricht den Verkehr, indem sie die Routing-Tabelle manipuliert. Das Problem: Während der 200 bis 800 Millisekunden, die die Anwendung benötigt, um den Abbruch zu erkennen und zu reagieren, verlassen Pakete unverschlüsselt über die Standard-Schnittstelle. Das reicht aus, damit eine aktive BitTorrent-Verbindung Ihre echte IP an den Tracker preisgibt oder ein laufender Multipart-S3-Upload Ihren geografischen Ursprung offenbart.
Der Netfilter-Kill-Switch (iptables oder nftables) umgeht dieses Problem, indem er die Filterregel direkt im Linux-Kernel platziert, nicht in einem Benutzermodus-Prozess. Pakete durchlaufen das Netfilter-Subsystem bei jedem send/sendmsg/sendto-Systemaufruf — es gibt kein Anwendungs-Latenzfenster. Wenn WireGuard abstürzt, werden Pakete weiterhin von Netfilter gedroppt, bis der Tunnel zurückkommt, unabhängig vom Zustand des WireGuard-Prozesses. Deshalb empfiehlt Mullvad Netfilter als zweite Schicht zusätzlich zu ihrer App, und warum Tor-Projektanleitungen den Netfilter-Kill-Switch ausdrücklich für Hosts erwähnen, die Relays betreiben.
Unsere Wahl für iptables statt nftables liegt an der Unterstützung: Ubuntu Server 22.04 LTS und Debian 12 haben iptables immer noch als De-facto-Tool, obwohl das Backend unter der Haube nftables ist. iptables-Befehle sind aus jedem Dokument der letzten 10 Jahre kopierbar, was das Risiko von Tippfehlern reduziert und die Wartung erleichtert. Wenn Sie 2026 auf einem neuen Host neu anfangen und nftables kennen, gehen Sie direkt mit nftables — die Syntax ist sauberer und die Reihenfolge der Ketten ist explizit.
Das Modell, das wir bauen
Die Kernidee in 3 Sätzen:
- Alle OUTPUT-Verkehr wird standardmäßig gedroppt, es sei denn, er verlässt die Maschine über die VPN-Schnittstelle (
wg0). - Ausnahme: Die UDP-Verbindung zum VPN-Server (Handshake) bleibt erlaubt — ohne sie kann der Tunnel nach einem Abbruch nicht wiederhergestellt werden.
- systemd stellt sicher, dass diese iptables-Regeln vor WireGuard angewendet werden und Tunnelneustarts überleben.
Ergebnis: Wenn WireGuard abstürzt, kann Ihre Maschine buchstäblich nichts senden außer dem VPN-Handshake. Sie sehen "keine Verbindung" im Browser, aber es gibt keine Paketlecks.
Vorbereitung
Auf Ubuntu/Debian (getestet auf Ubuntu 22.04 und 24.04, Kernel 5.15+):
sudo apt update
sudo apt install -y iptables iptables-persistent
# Bei der netfilter-persistent-Abfrage: JA für IPv4 und IPv6
Beachten Sie diese Punkte, bevor Sie fortfahren:
- Die öffentliche VPN-IP:
nslookup vpn.example.comoder überprüfen Sie dieEndpoint-Zeile inwg0.conf. - Der VPN-UDP-Port: normalerweise
51820für WireGuard. - Die VPN-Schnittstelle: standardmäßig
wg0, kann bei mehreren Tunnelnwg1sein. - Das lokale LAN-Subnetz, das erreichbar bleiben soll (192.168.1.0/24, 10.0.0.0/8, etc.) — damit Drucker und NAS nicht ausfallen.
IPv4 iptables-Regeln
Erstellen Sie /etc/iptables/rules.v4 mit diesem Inhalt (angepasste Werte in Klammern):
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
# Loopback immer erlaubt
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
# Bereits hergestellte Verbindungen (VPN-Handshake-Antworten, etc.)
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Eingehendes SSH (wenn Sie remote verwalten — andernfalls diese 2 Zeilen löschen)
-A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT
# Ausgehender VPN-Handshake: nur Verkehr außerhalb des Tunnels erlaubt
-A OUTPUT -p udp -d 1.2.3.4 --dport 51820 -j ACCEPT
# Lokales LAN-DNS (Pi-hole, Router) — optional
-A OUTPUT -d 192.168.1.0/24 -j ACCEPT
# Alles andere OUTPUT geht über die VPN-Schnittstelle
-A OUTPUT -o wg0 -j ACCEPT
# Eingehendes auf wg0 erlauben
-A INPUT -i wg0 -j ACCEPT
COMMIT
Ersetzen Sie:
1.2.3.4durch die tatsächliche öffentliche IP Ihres VPN-Servers51820durch Ihren WireGuard-Port192.168.1.0/24durch Ihr LAN-Subnetz- Entfernen Sie die
--dport 22-Zeile, wenn Sie keinen eingehenden SSH-Admin benötigen
Laden Sie die Regeln:
sudo iptables-restore < /etc/iptables/rules.v4
sudo iptables -L -v -n
# Bestätigen Sie, dass die DROP-Kettenzähler bei 0 sind
ip6tables-Regeln (KRITISCH)
Ohne explizit blockiertes IPv6 aktivieren viele Distributionen es standardmäßig und der Verkehr leckt. Erstellen Sie /etc/iptables/rules.v6:
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Wenn Ihr VPN IPv6 unterstützt (selten bei selbst gehosteten):
# -A OUTPUT -p udp -d 2001:db8::1 --dport 51820 -j ACCEPT
# -A OUTPUT -o wg0 -j ACCEPT
# -A INPUT -i wg0 -j ACCEPT
# Andernfalls wird alles IPv6 außerhalb des Loopbacks gedroppt
COMMIT
Laden:
sudo ip6tables-restore < /etc/iptables/rules.v6
An diesem Punkt können Sie testen: Ohne den WireGuard-Tunnel passiert kein Ping ins Internet. Erwartet.
systemd-Dienstreihenfolge für WireGuard nach iptables
Standardproblem: wg-quick@wg0 kann vor netfilter-persistent starten. Während dieses Fensters (~1-3 Sekunden) ist der Tunnel UP, aber die iptables-Regeln sind nicht geladen → mögliches Leck.
Lösung: systemd-Override, der die Reihenfolge erzwingt.
Erstellen Sie /etc/systemd/system/wg-quick@wg0.service.d/killswitch.conf:
sudo mkdir -p /etc/systemd/system/wg-quick@wg0.service.d
sudo nano /etc/systemd/system/wg-quick@wg0.service.d/killswitch.conf
Inhalt:
[Unit]
After=netfilter-persistent.service
Wants=netfilter-persistent.service
Requires=netfilter-persistent.service
[Service]
# Wenn wg-quick abstürzt, erzwinge OUTPUT DROP, um Lecks zu verhindern
ExecStopPost=/sbin/iptables -P OUTPUT DROP
ExecStopPost=/sbin/ip6tables -P OUTPUT DROP
Systemd neu laden:
sudo systemctl daemon-reload
sudo systemctl enable wg-quick@wg0
sudo systemctl enable netfilter-persistent
sudo systemctl restart netfilter-persistent
sudo systemctl restart wg-quick@wg0
Bei jedem Start startet systemd netfilter-persistent zuerst (iptables geladen), dann wg-quick@wg0 (Tunnel up). Kein Leckfenster.
Validierungstests
Test 1 — Tunnel fallen lassen, Stille überprüfen
# Tunnel up
sudo wg show
# Muss einen aktuellen Handshake anzeigen
# Internetzugang testen
curl -s -m 5 https://ifconfig.me
# Muss VPS-IP zurückgeben
# Tunnel fallen lassen
sudo wg-quick down wg0
# Erneut testen
curl -s -m 5 https://ifconfig.me
# Muss ohne Antwort ablaufen — KILL SWITCH AKTIV
Wenn Sie bei dem zweiten Befehl eine IP sehen → Leck, iptables-Regeln sind nicht angewendet. Überprüfen Sie sudo iptables -L -v -n und bestätigen Sie, dass OUTPUT standardmäßig DROP ist.
Test 2 — Einen WireGuard-Absturz simulieren
# Tunnel up
sudo wg-quick up wg0
ping -c 2 1.1.1.1
# Muss OK pingen
# Brutales Beenden des WireGuard-Prozesses (Absturz simulieren)
sudo pkill -9 wg
sudo ip link delete wg0 2>/dev/null
# Erneut testen
ping -c 2 1.1.1.1
# Muss fehlschlagen "Operation nicht erlaubt"
Der Kernel verweigert den Ping, da keine Route mehr erlaubt ist. Ohne ExecStopPost im systemd-Drop-in lassen einige Distributionen ein Leckfenster nach dem Absturz — diese Zeile ist wichtig.
Test 3 — DNS-Leck
# Tunnel UP
dig @9.9.9.9 ifconfig.me +short
# Muss VPS-IP zurückgeben
# Tunnel fallen lassen
sudo wg-quick down wg0
# Erneut testen
dig @9.9.9.9 ifconfig.me +short
# Muss ablaufen / "keine Server konnten erreicht werden"
Selbst DNS wird außerhalb des Tunnels blockiert. Ziel erreicht.
Sonderfälle
Sie betreiben mehrere Tunnel (wg0 + wg1)
Duplizieren Sie die OUTPUT-Ausnahme:
-A OUTPUT -p udp -d 1.2.3.4 --dport 51820 -j ACCEPT # Haupttunnel
-A OUTPUT -p udp -d 5.6.7.8 --dport 51820 -j ACCEPT # Sekundärtunnel
-A OUTPUT -o wg0 -j ACCEPT
-A OUTPUT -o wg1 -j ACCEPT
Tailscale parallel betreiben
Tailscale verwendet standardmäßig UDP 41641. Hinzufügen:
-A OUTPUT -p udp --dport 41641 -j ACCEPT
-A OUTPUT -o tailscale0 -j ACCEPT
Lokales LAN erreichbar halten (NAS, Drucker)
Die Vorlagenregel -A OUTPUT -d 192.168.1.0/24 -j ACCEPT tut dies bereits. Passen Sie das Subnetz an.
Sie möchten keinen eingehenden SSH (mobiler Arbeitsplatz)
Löschen Sie die Zeile --dport 22 -m state --state NEW -j ACCEPT. Bestehende (ESTABLISHED) Verbindung bleibt OK.
Protokollierung gedropter Pakete (Debug)
Um zu sehen, was ohne den Kill-Switch geleckt hätte:
sudo iptables -I OUTPUT 1 -j LOG --log-prefix "OUTPUT-DROP: " --log-level 4
Dann:
sudo journalctl -k -f | grep "OUTPUT-DROP"
Sie sehen jedes Paket, das Ihr Betriebssystem versucht, unverschlüsselt zu senden, wenn der Tunnel unten ist (Apple DNS, NTP, Spotify-Heartbeat, etc.). Lehrreich.
Sobald das Debugging abgeschlossen ist, entfernen Sie die LOG-Regel (sonst füllt sich journalctl):
sudo iptables -D OUTPUT -j LOG --log-prefix "OUTPUT-DROP: " --log-level 4
Bonus: Kill-Switch direkt in wg0.conf
Wenn Sie iptables nicht separat verwalten möchten, akzeptiert WireGuard PostUp/PreDown, die die gleiche Aufgabe erfüllen:
[Interface]
# ...
PostUp = iptables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
PostUp = ip6tables -I OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
PreDown = iptables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
PreDown = ip6tables -D OUTPUT ! -o %i -m mark ! --mark $(wg show %i fwmark) -m addrtype ! --dst-type LOCAL -j REJECT
Pro: keine zusätzliche Datei. Contra: Regeln verschwinden, wenn WireGuard abstürzt, ohne PreDown aufzurufen (Kernel-Panik, OOM-Kill). Der oben beschriebene systemd-Ansatz ist robuster für den langfristigen Einsatz.
Siehe auch die Reise-Kill-Switch-Vorlage im WireGuard 2026-Leitfaden für die Inline-wg0.conf-Version.
Letzte Überprüfung
# Vollständiger Neustart
sudo reboot
# Nach dem Neustart keine manuellen Schritte
ip a show wg0
# Muss Tunnel UP anzeigen
iptables -L OUTPUT -v -n | head -5
# Standardrichtlinie muss DROP sein, Akzeptanzzähler müssen wachsen
curl -s ifconfig.me
# Muss VPS-IP zurückgeben
Alles grün: Ihr Kill-Switch ist eingerichtet, läuft beim Start, übersteht Abstürze. Sie können die Maschine in ein feindliches Netzwerk einstecken, ohne Leckrisiko.
Weiterführende Schritte
Der Kill-Switch blockiert Lecks. Aber für echten Seelenfrieden, fügen Sie hinzu:
- Prometheus + Grafana Monitoring für Ihr VPS-VPN — Echtzeit-Tunnelstatus, Durchsatz, verbundene Peers.
- Split-Tunnel mit Routing-Tabellen — nützlich, wenn einige Apps das VPN umgehen sollen (Steam-Downloads, Time Machine zu lokalem NAS), während der Rest getunnelt bleibt.
- Fertig nutzbare WireGuard-Vorlagen — 8 produktionsgetestete Konfigurationen.
- WireGuard-Konfigurationsgenerator — generiert eine
wg0.confmit vorgefüllten Kill-Switch-PostUp/PreDown-Regeln, kein INI-Schreiben nötig. - Bestes selbst gehostetes VPN 2026 — vergleichen Sie WireGuard mit Tailscale und Headscale, bevor Sie sich für einen Stack entscheiden.
Und die Grundlage: WireGuard-Setup auf Contabo in 20 Minuten.
★ Nürnberger DSGVO-Rechenzentrum · ✓ Dedizierte IPv4 inklusive · 200+ Mbps garantiert
Self-host your VPN on your own VPS → ContaboFull root access · public IPv4 · pick your region→