Skip to content

Instantly share code, notes, and snippets.

@richardevcom
Last active May 15, 2026 07:19
Show Gist options
  • Select an option

  • Save richardevcom/0707f6c7c348b13615a5c9521488f7f2 to your computer and use it in GitHub Desktop.

Select an option

Save richardevcom/0707f6c7c348b13615a5c9521488f7f2 to your computer and use it in GitHub Desktop.
tmp
#!/bin/bash
# Apply hardened killswitch using nftables
# Policy: Drop ALL traffic except:
# 1. Loopback (lo)
# 2. VPN tunnel (tun0) - for NordVPN
# 3. WireGuard (wg0) - for future Mullvad
# 4. OpenVPN control traffic to remote server
set -e
echo "[*] Applying killswitch (nftables)..."
# Get OpenVPN remote server IP from config
OVPN_CONFIG="${1:-/etc/openvpn/nord/tcp/example.ovpn}"
REMOTE_IP=$(grep -m 1 '^remote ' "$OVPN_CONFIG" 2>/dev/null | awk '{print $2}' | head -1)
if [ -z "$REMOTE_IP" ]; then
echo "[!] Could not extract remote IP from config"
exit 1
fi
# Resolve hostname to IP if needed
if ! [[ "$REMOTE_IP" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
echo "[*] Resolving $REMOTE_IP..."
REMOTE_IP=$(tor-resolve "$REMOTE_IP" 2>/dev/null || echo "")
if [ -z "$REMOTE_IP" ]; then
echo "[!] DNS resolution failed"
exit 1
fi
fi
echo "[*] Remote VPN server IP: $REMOTE_IP"
# Create nftables table for killswitch
sudo nft flush ruleset 2>/dev/null || true
sleep 1
sudo nft add table inet killswitch
# Input chain (what comes in)
sudo nft add chain inet killswitch input { type filter hook input priority 0\; policy drop\; }
sudo nft add rule inet killswitch input iif lo accept
sudo nft add rule inet killswitch input iif tun0 accept
sudo nft add rule inet killswitch input iif wg0 accept
sudo nft add rule inet killswitch input ct state established,related accept
# Output chain (what goes out)
sudo nft add chain inet killswitch output { type filter hook output priority 0\; policy drop\; }
sudo nft add rule inet killswitch output oif lo accept
sudo nft add rule inet killswitch output oif tun0 accept
sudo nft add rule inet killswitch output oif wg0 accept
# CRITICAL: Allow OpenVPN handshake to remote server
sudo nft add rule inet killswitch output ip daddr $REMOTE_IP tcp dport 443 accept
sudo nft add rule inet killswitch output ip daddr $REMOTE_IP udp dport 1194 accept
sudo nft add rule inet killswitch input ip saddr $REMOTE_IP tcp sport 443 accept
sudo nft add rule inet killswitch input ip saddr $REMOTE_IP udp sport 1194 accept
# Allow Tor daemon communication (loopback)
sudo nft add rule inet killswitch output oif lo tcp dport 9050 accept
echo "[+] Killswitch active: All traffic blocked except VPN/Tor"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment