A VPN kill switch prevents traffic from leaking outside the VPN tunnel if the VPN connection unexpectedly drops — important for scenarios where traffic must never bypass the VPN. This guide covers implementing this with iptables.
Why a Kill Switch Matters
Without a kill switch, if your VPN connection drops unexpectedly, your system typically falls back to routing traffic through the regular internet connection directly — potentially exposing traffic that was meant to always go through the VPN, a meaningful concern for privacy-sensitive or security-sensitive use cases.
The Core Kill Switch Concept
Configure firewall rules that only permit traffic through the VPN interface (plus the specific traffic needed to establish the VPN connection itself) — if the VPN interface goes down, all other traffic is blocked by default rather than falling back to an unprotected direct connection.
Basic iptables Kill Switch for a WireGuard Client
iptables -F
iptables -P OUTPUT DROP
iptables -P INPUT DROP
iptables -A OUTPUT -o wg0 -j ACCEPT
iptables -A INPUT -i wg0 -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -p udp --dport 51820 -d YOUR_VPN_SERVER_IP -j ACCEPT
Default-deny policy on both input and output, with explicit allows only for the VPN interface, loopback, and the specific traffic needed to establish the VPN connection itself — anything else is blocked by default.
Understanding Why the VPN Server Connection Itself Is Explicitly Allowed
The traffic establishing the VPN tunnel (to the VPN server's actual public IP, on its specific port) must be allowed outside the tunnel, since the tunnel doesn't exist yet at that point — a necessary, deliberate exception to the "everything through VPN only" rule.
Making the Kill Switch Persistent
sudo apt install iptables-persistent -y
sudo netfilter-persistent save
Testing the Kill Switch
sudo wg-quick down wg0
curl https://ifconfig.me
With the VPN interface down, verify that traffic genuinely fails (rather than falling back to your direct connection) — confirms the kill switch is actually working as intended, not just theoretically configured.
Combining with WireGuard's Own Configuration
[Interface]
PostUp = iptables -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
WireGuard configurations can include kill switch logic directly via PostUp/PreDown hooks, automatically applying/removing the firewall rules alongside the VPN connection lifecycle rather than managing them entirely separately.
Kill Switch Considerations for a Server (vs a Client Device)
On a server context, a kill switch is relevant if the server itself must never send traffic outside a specific VPN (compliance requirements, specific architectural needs) — understand your genuine requirement before implementing, since an overly aggressive kill switch can cause unexpected service disruption if the VPN connection has any instability.
Monitoring VPN Connection Stability
See How to Set Up Effective Server Alerting (Without Alert Fatigue) — if you rely on a kill switch, also monitor VPN connection health/stability, since frequent VPN drops combined with a kill switch means frequent service interruption, worth addressing at the root cause rather than just accepting.
Common Errors
Kill switch also blocks legitimate local network traffic unexpectedly — review your rule set for whether local network access (LAN, if genuinely needed) should be explicitly allowed alongside VPN traffic, since an overly broad default-deny can block more than intended.
Continue Reading
- How to Set Up a VPN Server with WireGuard
- How to Secure a VPN Server Against Common Attacks
- How to Set Up a Mesh VPN with Tailscale or ZeroTier
Browse more articles in Advanced Networking & VPN.