Skip to content

Instantly share code, notes, and snippets.

@GeorgeDewar
Last active October 2, 2016 20:13
Show Gist options
  • Save GeorgeDewar/9818851 to your computer and use it in GitHub Desktop.
Save GeorgeDewar/9818851 to your computer and use it in GitHub Desktop.
#!/bin/bash
red='\e[0;31m'
green='\e[0;32m'
NC='\e[0m'
set -e
function usage {
echo Enable/Disable routing all traffic through VPN, and
echo configure proxy settings accordingly
echo
echo Usage:
echo
echo "vpn <setup / on / off / test>"
}
if [ $(basename -- $0) == "bash" ] || [ $(basename -- $0) == "-bash" ]; then
echo -e "${red}You should no longer run 'vpn' using source${NC}"
echo
usage
return 1
fi
function checkRunning {
echo -n "Checking for running OpenVPN client: "
pid=`sudo cat /run/openvpn/client.pid 2>/dev/null || sudo cat /run/openvpn.client.pid 2>/dev/null`
if [ ! -z $pid ] && ps -p $pid -o pid >/dev/null 2>&1; then
echo -e "${green}OK${NC} [PID: $pid]"
else
echo -e "${red}Not found${NC}"
echo
echo Check the logs below and try running \"sudo service openvpn start\"
vpnLogs
if [ "$START" == "Y" ]; then return 1; fi # Already tried that
read -e -p "Attempt to start service now [Y/n]? " -i "Y" START
if [ "$START" == "Y" ]; then
sudo service openvpn start
checkRunning
else
return 1
fi
fi
}
function checkEnabled {
echo -n "Checking for VPN tunnel interface: "
timeout=10
while ! ip addr | grep "tun." | grep -G "$PEER_IP" > /dev/null 2>&1; do
timeout=$(expr $timeout - 1)
if [ $timeout -eq 0 ]; then
echo -e "${red}Not present${NC}"
echo
echo Check the logs below and try running \"sudo service openvpn restart\"
vpnLogs
return 1
fi
echo -n "."
sleep 1
done
echo -e "${green}OK${NC}"
}
function checkRoutes {
echo "Checking routes..."
echo -n " Default route to VPN: "
if [ `route -n | sed -e 's/ \+/,/g' | grep "0\.0\.0\.0,[0-9\.]\+,0\.0\.0\.0" | wc -l 2>&1` -gt 1 ]; then
echo -e "${red}Multiple default routes present${NC}"
printRoutes
return 1
elif route -n | sed -e 's/ \+/,/g' | grep -F 0.0.0.0,$PEER_IP,0.0.0.0 > /dev/null 2>&1; then
echo -e "${green}OK${NC}"
else
echo -e "${red}Missing${NC}"
printRoutes
return 1
fi
echo -n " Local network route: "
if route -n | sed -e 's/ \+/,/g' | grep -F 172.16.0.0,$DEFAULT_GW,255.240.0.0,UG,0,0,0,eth0 > /dev/null 2>&1; then
echo -e "${green}OK${NC}"
else
echo -e "${red}Missing${NC}"
printRoutes
return 1
fi
}
function checkConnectivity {
echo "Checking connectivity..."
echo -n " Ping VPN gateway: "
if response=`ping -c 1 -w 5 10.8.0.1`; then
echo -e "${green}OK${NC}"
else
echo -e "${red}Failed${NC}"
echo
echo $response
return 1
fi
echo -n " Ping external server: "
if response=`ping -c 1 -w 2 203.96.152.4`; then
echo -e "${green}OK${NC}"
else
echo -e "${red}Failed${NC}"
echo
echo $response
return 1
fi
echo -n " HTTP request: "
if response=`curl -s icanhazip.com`; then
echo -e "${green}OK${NC}"
else
echo -e "${red}Failed${NC}"
echo
echo $response
return 1
fi
echo -n " Source IP: "
if [ $response = "$VPN_IP" ]; then
echo -e "${green}$response${NC}"
else
echo -e "${red}$response${NC}"
return 1
fi
}
function preCheck {
if ! (checkRunning && checkEnabled); then return 1; fi
}
function postCheck {
if ! (checkRoutes && checkConnectivity); then return 1; fi
}
function vpnLogs {
echo
echo "Logs from most recent start attempt:"
echo
tac /var/log/syslog | grep ovpn-client | grep OpenVPN -B5000 -m1 | tac | tail -20
}
function printRoutes {
echo
route -n
}
function loadConfig {
if [ ! -f ~/.vpnconfig ]; then
echo "You appear to be running vpn for the first time. Please run vpn setup."
return 1
fi
unset PEER_IP VPN_IP
source ~/.vpnconfig
if [ -z "$PEER_IP" ]; then
echo "Your .vpnconfig file does not appear to contain the PEER_IP property. Please run vpn setup."
return 1
fi
if [ -z "$VPN_IP" ]; then
echo "Your .vpnconfig file does not appear to contain the VPN_IP property. Please run vpn setup."
return 1
fi
if [ -z "$DEFAULT_GW" ]; then
echo "Your .vpnconfig file does not appear to contain the DEFAULT_GW property. Please run vpn setup."
return 1
fi
}
op=$1
if [ "$op" = "setup" ]; then
if ! preCheck; then exit 1; fi
if [ -f ~/.vpnconfig ]; then source ~/.vpnconfig; fi
echo
echo "Please enter the Peer IP of your VPN link. It should be visible in the list below:"
echo
ip addr | grep tun | grep "peer .*/32" -B 1
echo
read -e -p "Peer IP: " -i "${PEER_IP}" PEER_IP
echo
echo "Please enter the public IP address of the VPN server:"
echo -n "Your OpenVPN configuration says: "
grep "^remote .* 443" /etc/openvpn/client.conf
echo
read -e -p "VPN IP: " -i "${VPN_IP}" VPN_IP
echo
echo "Please enter your default gateway for local traffic:"
echo -n "Your current default route is: "
route -n | head -3 | tail -1 | sed 's/ \+/ /g' | cut -d' ' -f2
echo
read -e -p "Default Gateway: " -i "${DEFAULT_GW}" DEFAULT_GW
echo "PEER_IP=$PEER_IP" > ~/.vpnconfig
echo "VPN_IP=$VPN_IP" >> ~/.vpnconfig
echo "DEFAULT_GW=$DEFAULT_GW" >> ~/.vpnconfig
echo
echo "Configuration complete!"
elif [ "$op" = "test" ]; then
if ! loadConfig; then exit 1; fi
if ! preCheck; then exit 1; fi
if ! postCheck; then exit 1; fi
elif [ "$op" = "on" ]; then
if ! loadConfig; then exit 1; fi
if ! preCheck; then exit 1; fi
# Alter routes
sudo route del default 2>/dev/null || true
sudo route add default gw $PEER_IP dev tun0
sudo route del -net 172.16.0.0/12 2>/dev/null || true
sudo route add -net 172.16.0.0/12 gw $DEFAULT_GW dev eth0
echo
echo "VPN enabled; testing..."
echo
if ! postCheck; then exit 1; fi
elif [ "$op" = "off" ]; then
if ! loadConfig; then exit 1; fi
# Alter routes
sudo route del default 2>/dev/null
sudo route add default gw $DEFAULT_GW dev eth0
sudo route del -net 172.16.0.0/12 2>/dev/null || true
echo "VPN disabled."
elif [ "$op" = "update" ]; then
wget https://gist.githubusercontent.com/GeorgeDewar/9818851/raw -O ~/bin/vpn -q
chmod +x ~/bin/vpn
vpn postupdate
echo "Updated successfully"
echo
vpn -v
elif [ "$op" = "postupdate" ]; then
echo "No post-update tasks"
elif [ "$op" = "-v" ]; then
echo "VPN on/off tool version 1.1.1"
else
usage
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment