Last active
May 15, 2026 07:19
-
-
Save richardevcom/0707f6c7c348b13615a5c9521488f7f2 to your computer and use it in GitHub Desktop.
tmp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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