Last active
March 5, 2017 21:33
-
-
Save ervinb/d4fe7d39f7b4762c6c5c30359eaec1d2 to your computer and use it in GitHub Desktop.
This file contains 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 | |
## 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