Skip to content

Instantly share code, notes, and snippets.

@rfprod
Created August 1, 2018 07:12
Show Gist options
  • Save rfprod/6336e07f22cde0c89b0b756763342c12 to your computer and use it in GitHub Desktop.
Save rfprod/6336e07f22cde0c89b0b756763342c12 to your computer and use it in GitHub Desktop.
Iptables VPN killswitch
#!/bin/bash
#---------------------------------------------------------------
# General instructions.
#---------------------------------------------------------------
# You need to setup iptables firewall, so your machine can connect ONLY
# to specified VPN servers (no other traffic allowed, except local,
# so there will be no "leaks"). Here's a script for that.
#---------------------------------------------------------------
# Configuration instructions.
#---------------------------------------------------------------
# Search for CONFIGURE_THIS substring in this file.
# You need to setup table servers=().
# Specify IP's of preferred VPN servers.
# Also check that other variables at the beginning of the script are set
# properly, otherwise it will block your entire connection.
# Make an iptables backup with:
# sudo iptables-save > working.iptables.rules
# Restore with:
# sudo iptables-restore < working.iptables.rules
# It supports TCP and UDP connections, if you need only one of those, remove
# unwanted two lines from for () loop. Also check if your provider is using
# same ports - might be different.
# Run this script like:
# sudo /home/user/scripts/iptables-vpn-killswitch.sh.
# If you want to load it on boot (iptables usually resets after re-boot),
# add to your /etc/rc.local file line like:
# bash /home/user/scripts/iptables-vpn-killswitch.sh.
#---------------------------------------------------------------
# Iptables setup, vpn killswitch:
# - drops all traffic not going trough vpn;
# - allows traffic in local area network;
# - appliy special rules for UPNP and Multicast discovery.
#---------------------------------------------------------------
printf "\nIptables setup, vpn killswitch:\n"
printf " - drops all traffic not going trough vpn;\n"
printf " - allows traffic in local area network;\n"
printf " - apply special rules for UPNP and Multicast discovery.\n\n"
#---------------------------------------------------------------
# Backup working iptables rules first.
#---------------------------------------------------------------
printf "Backing up iptables...\n"
currentDate=`date '+%Y_%m_%d__%H_%M_%S'`
printf " > current date: ${currentDate}\n\n"
# UNCOMMENT_LINE # sudo iptables-save > "${currentDate}.working.iptables.rules"
#---------------------------------------------------------------
# Configuration.
#---------------------------------------------------------------
# UNCOMMENT_LINE # FW="/sbin/iptables"
# UNCOMMENT_LINE # LCL="192.168.1.0/24"
# UNCOMMENT_LINE # VPN="10.0.0.0/12"
# UNCOMMENT_LINE # local_interface="eno1" # CONFIGURE_THIS
# UNCOMMENT_LINE # virtual_interface="tun0" # CONFIGURE_THIS
# VPN Servers
# UNCOMMENT_LINES #
#servers=(
#123.123.123.123 # CONFIGURE_THIS
#124.124.124.124 # CONFIGURE_THIS
#)
# UNCOMMENT_LINES #
#---------------------------------------------------------------
# Remove old rules and tables.
#---------------------------------------------------------------
printf "\nCurrent configuration:\n"
printf " - FW=${FW}\n"
printf " - LCL=${LCL}\n"
printf " - VPN=${VPN}\n"
printf " - local_interface=${local_interface}\n"
printf " - virtual_interface=${virtual_interface}\n"
printf " - servers=${servers}\n\n"
printf "\nDeleting old iptables rules...\n"
#---------------------------------------------------------------
# Remove old rules and tables.
#---------------------------------------------------------------
# UNCOMMENT_LINE # iptables -F
# UNCOMMENT_LINE # iptables -X
# UNCOMMENT_LINE # iptables -t nat -F
# UNCOMMENT_LINE # iptables -t nat -X
# UNCOMMENT_LINE # iptables -t mangle -F
# UNCOMMENT_LINE # iptables -t mangle -X
printf "\nSetting up new rules...\n"
#---------------------------------------------------------------
# Default Policy - Drop anything!
#---------------------------------------------------------------
printf "\n - Rule: Default Policy - Drop anything\n"
# UNCOMMENT_LINE # $FW -P INPUT DROP
# UNCOMMENT_LINE # $FW -P FORWARD DROP
# UNCOMMENT_LINE # $FW -P OUTPUT DROP
#---------------------------------------------------------------
# Allow all local connections via loopback.
#---------------------------------------------------------------
printf "\n - Rule: Allow all local connections via loopback\n"
# UNCOMMENT_LINE # $FW -A INPUT -i lo -j ACCEPT
# UNCOMMENT_LINE # $FW -A OUTPUT -o lo -j ACCEPT
#---------------------------------------------------------------
# Allow Multicast for local network.
#---------------------------------------------------------------
printf "\n - Rule: Allow Multicast for local network\n"
# UNCOMMENT_LINE # $FW -A INPUT -j ACCEPT -p igmp -s $LCL -d 224.0.0.0/4 -i $local_interface
# UNCOMMENT_LINE # $FW -A OUTPUT -j ACCEPT -p igmp -s $LCL -d 224.0.0.0/4 -o $local_interface
#---------------------------------------------------------------
# UPnP uses IGMP multicast to find media servers.
# Accept IGMP broadcast packets.
# Send SSDP Packets.
#---------------------------------------------------------------
printf "\n - Rule: Accept IGMP broadcast packets, send SSDP packets\n"
# UNCOMMENT_LINE # $FW -A INPUT -j ACCEPT -p igmp -s $LCL -d 239.0.0.0/8 -i $local_interface
# UNCOMMENT_LINE # $FW -A OUTPUT -j ACCEPT -p udp -s $LCL -d 239.255.255.250 --dport 1900 -o $local_interface
#---------------------------------------------------------------
# Allow all bidirectional traffic from your firewall to the
# local area network.
#---------------------------------------------------------------
printf "\n - Rule: Allow bidirectional traffic from firewall to LAN\n"
# UNCOMMENT_LINE # $FW -A INPUT -j ACCEPT -s $LCL -i $local_interface
# UNCOMMENT_LINE # $FW -A OUTPUT -j ACCEPT -d $LCL -o $local_interface
#---------------------------------------------------------------
# Allow all bidirectional traffic from your firewall to the
# virtual privat network.
#---------------------------------------------------------------
printf "\n - Rule: Allow bidirectional traffic from firewall to VPN\n"
# UNCOMMENT_LINE # $FW -A INPUT -j ACCEPT -i $virtual_interface
# UNCOMMENT_LINE # $FW -A OUTPUT -j ACCEPT -o $virtual_interface
#---------------------------------------------------------------
# Connection to VPN servers (UDP 443).
#---------------------------------------------------------------
printf "\n - Rule: Connect to VPN over 443 port\n"
# UNCOMMENT_LINES #
#server_count=${#servers[@]}
#for (( c = 0; c < $server_count; c++ ))
#do
# $FW -A INPUT -j ACCEPT -p udp -s ${servers[c]} --sport 1194 -i $local_interface
# $FW -A OUTPUT -j ACCEPT -p udp -d ${servers[c]} --dport 1194 -o $local_interface
# $FW -A INPUT -j ACCEPT -p tcp -s ${servers[c]} --sport 443 -i $local_interface
# $FW -A OUTPUT -j ACCEPT -p tcp -d ${servers[c]} --dport 443 -o $local_interface
#done
# UNCOMMENT_LINES #
#---------------------------------------------------------------
# Log all dropped packages, debug only.
# View in one of the following:
# - /var/log/syslog
# - /var/log/messages
#---------------------------------------------------------------
#iptables -N logging
#iptables -A INPUT -j logging
#iptables -A OUTPUT -j logging
#iptables -A logging -m limit --limit 2/min -j LOG --log-prefix "IPTables general: " --log-level 7
#iptables -A logging -j DROP
# Disable internet for "no-internet" user
#iptables -A OUTPUT -m owner --gid-owner no-internet -j DROP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment