Skip to content

Instantly share code, notes, and snippets.

@ervinb
Last active March 5, 2017 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ervinb/d4fe7d39f7b4762c6c5c30359eaec1d2 to your computer and use it in GitHub Desktop.
Save ervinb/d4fe7d39f7b4762c6c5c30359eaec1d2 to your computer and use it in GitHub Desktop.
#!/bin/bash
## This script is very hacky way to use VPN only for specific domains.
# For example: if you have a VPN subscription and want to access Pandora outside of the USA (may or may not be legal),
# you'd run it like "veer ovpn.conf www.pandora.com"
#
## How it works:
# Fetches the domain's IPs and routes their connections through a VPN gateway.
#
## Requirements:
# - working OpenVPN setup with a config file
# - dig
#
## Installation
# wget https://gist.githubusercontent.com/ervinb/d4fe7d39f7b4762c6c5c30359eaec1d2/raw/veer.sh -O ~/bin/veer && sudo chmod +x ~/bin/veer
# (tested on Fedora 25)
ovpn_config_path=$1
domain=$2
log() {
echo -e "## $1"
}
usage() {
log "Usage:"
echo "veer <ovpn.conf> <www.domain.com>"
}
check_exe() {
if (hash "$1 2>/dev/null"); then
log "$1 is present."
else
log "$1 missing!"
exit 1
fi
}
get_domain_ips() {
dig $1 +short
}
check_config() {
if ! [ -e $ovpn_config_path ]; then
log "OpenVPN config not found at $ovpn_config_path!"
exit 1
fi
if (grep '^redirect-gateway' $ovpn_config_path); then
log "Remove 'redirect-gateway' from the OpenVPN config file, as it routes *all* traffic to the VPN!"
fi
log "Config OK"
}
get_tun_info() {
route | grep -e 'UH.*tun'
}
kill_openvpn() {
pgrep -f "[o]penvpn.*$ovpn_config_path" | xargs -I PID sudo kill PID
}
start_openvpn() {
sudo openvpn --daemon --ping-restart 0 --persist-tun --config $ovpn_config_path
log "Waiting for the TUN device to appear"
while true; do
local tun_info=$(get_tun_info)
! [ -z "$tun_info" ] && break
printf "."
sleep 2
done
printf "\n"
}
route_domain_trough_vpn() {
log "Fetching VPN gateway"
local vpn_gateway=$(fetch_vpn_gateway)
log "Fetching IPs for $domain"
local ips=$(get_domain_ips $domain)
# the new routes will be auto-cleaned up after the TUN device is destroyed
for ip in $ips; do
log "$ip ($domain) -> $vpn_gateway (VPN GW)"
sudo route add $ip gw $vpn_gateway
done
log "Done"
}
fetch_vpn_gateway() {
# doesn't work when there are multiple TUN devices [WIP]
get_tun_info | cut -d ' ' -f1
}
#######
if [ "$#" -ne 2 ]; then
usage
exit 1
fi
log "Checking requirements"
check_exe "openvpn"
check_exe "dig"
log "Verifying OpenVPN config file"
check_config
log "Cleaning leftover OpenVPN instances if present"
kill_openvpn
log "Starting OpenVPN client"
start_openvpn
log "Routing domain IPs to VPN gateway"
route_domain_trough_vpn
log "Open $domain and enjoy!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment