Skip to content

Instantly share code, notes, and snippets.

@hrushikesh198
Last active November 19, 2019 23:00
Show Gist options
  • Save hrushikesh198/c82b9f65b2617f2da216986151885cee to your computer and use it in GitHub Desktop.
Save hrushikesh198/c82b9f65b2617f2da216986151885cee to your computer and use it in GitHub Desktop.
Internet kill switch for Ivacy VPN on Mac

Internet kill switch for Ivacy VPN on Mac: I have tested it on macOs Sierra. It might work on other versions of mac. Use at your own risk. Use this as a guideline for setting up your own kill switch. You need to change few things to get it working for yourself. With minor changes it should work for other VPNs also.

Files:

  • kill-switch : this is the shell script providing status/start/stop/restart functionalities.
  • Variables
    • CONN_NAME : Name of your vpn connetion in Sytem Preferences > Network. For me it is Ivacy.
  • ks.conf: It is the pfctl config template.
  • Variables
    • VPN_PROVIDER_ADDR : I figured out the address for reconnecting Ivacy using tcpflow -c -i en0. From the captured packets you can zero in on all the ip-addresses required to connect.
    • WIFI, VPN : Corresponding Interfaces

Usage:

  • Turn off kill-switch
  • Enable auto reconnect in your vpn dialer
  • Connect to desired location/server
  • Turn on kill-switch
  • When vpn connection drops, It allows connections to vpn provider only. Hence auto reconnect works fine.
  • After vpn reconnection every thing works fine
  • Turn off the kill switch if you want to connect regularly.

Note:

  • sudo iftop -i en0 is an useful command to check what traffic is going out from wifi without vpn. You should see a vpn destination addr transferring a lot of data. This address is whitelisted by kill-switch during start up.
#! /bin/bash
set -eu -o pipefail
CONN_NAME=Ivacy
script=${0##*/}
BASE=$(cd $(dirname $0);pwd)
usage="Usage: $script -h|-|0|1|2\n - status\n 0 stop\n 1 start\n 2 restart\n"
function err_exit {
code=$1
msg=$2
echo "Error($code): $msg"
echo -e $usage
exit $code
}
function start {
vip=$(scutil --nc show ${CONN_NAME}|grep 'CommRemoteAddress'|cut -d' ' -f 5)
echo "Starting $script, VIP: $vip"
sed "s/{VIP}/${vip}/" $BASE/ks.conf | sudo pfctl -e -F rules -f -
}
function stop {
echo "Stopping $script"
sudo pfctl -d || true
}
function status {
cnt=$(sudo pfctl -s rules 2>/dev/null|wc -l)
echo -e "Rules Loaded: $cnt"
sudo pfctl -s rules 2>/dev/null
sudo pfctl -s info 2>/dev/null
}
function main {
if [ $# -lt 1 ]; then
err_exit 1 "Subcommand not provided"
fi
if [ "$1" = "1" ]; then
start
elif [ "$1" = "0" ]; then
stop
elif [ "$1" = "2" ]; then
stop
start
elif [ "$1" = "-" ]; then
status
elif [ "$1" = "-h" ]; then
echo -e $usage
else
err_exit 2 "Unrecognized Subcommand - $1"
fi
}
main $*
# --------------------------------------------------------------
# Sun, 22 Jan 2017 14:23:05 -0800
# sudo pfctl -Fa -f ks.conf -e
# --------------------------------------------------------------
WIFI = en0
VPN = ppp0
VPN_IP = {VIP}
VPN_PROVIDER_ADDR = 4lc4h.x.incapdns.net
set block-policy drop
set ruleset-optimization basic
set skip on lo0
block all
# DNS
pass quick proto {tcp, udp} from any to any port 53 keep state
# Broadcast
pass from any to 255.255.255.255 keep state
pass from 255.255.255.255 to any keep state
# Multicast
pass proto udp from any to 224.0.0.0/4 keep state
pass proto udp from 224.0.0.0/4 to any keep state
# DHCP
pass on $WIFI proto {tcp,udp} from any port 67:68 to any port 67:68 keep state
pass on $WIFI inet proto icmp all icmp-type 8 code 0
pass on $WIFI proto {tcp, udp} from any to {$VPN_PROVIDER_ADDR, $VPN_IP}
pass on $VPN all
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment