Skip to content

Instantly share code, notes, and snippets.

@monking
Created July 8, 2019 18:56
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 monking/07eaf03d8e9ce99520919ec42857d458 to your computer and use it in GitHub Desktop.
Save monking/07eaf03d8e9ce99520919ec42857d458 to your computer and use it in GitHub Desktop.
NordVPN helper for GNU/Linux
#!/bin/bash
# depends on openvpn (https://openvpn.net/) and json (npm install -g json)
# WARNING: stores credentials in plain text. It would be much better not to do this...
E_FAILED_DOWNLOAD=3
E_USER_ABORT=4
E_UNZIP=5
E_NOTRUNNING=6
E_ALREADYRUNNING=7
showHelp() {
echo "USAGE: vpn [OPTIONS | kill]" >&2
echo "OPTIONS:" >&2
echo " -h Show this help." >&2
echo " -k Kill a running instance of openvpn (same as argument 'kill')." >&2
echo " -t Use TCP mode." >&2
echo " -u Use UDP mode (default)." >&2
}
bak() {
local path="$1"
local bakPath="$path.bak"
[[ -e "$path" ]] \
&& sudo mv "$path" "$bakPath" \
&& echo -n "$bakPath"
}
rmBak() {
local path="$1"
local bakPath="$path.bak"
[[ -e "$path" && -e "$bakPath" ]] \
&& sudo rm -rf "$bakPath"
}
runningInstances="$(ps -e -o comm | grep openvpn)"
killVpn() {
if [[ -n "$runningInstances" ]]; then
sudo killall openvpn
exit $!
else
echo "openvpn is not currently running." >&2
exit $E_NOTRUNNING
fi
}
mode=udp
while getopts hktu flag; do
case $flag in
h) showHelp; exit;;
k) killVpn;;
t) mode=tcp;;
u) mode=udp;;
esac
done
[[ $OPTIND -gt 1 ]] && shift $((OPTIND-1))
if [[ $1 = kill ]]; then
killVpn
elif [[ -n "$runningInstances" ]]; then
echo "openvpn is already running. Run '$(basename "$0") kill' to stop it." >&2
exit $E_ALREADYRUNNING
fi
recommendedServer="$(curl -s 'https://nordvpn.com/wp-admin/admin-ajax.php?action=servers_recommendations' | json [0].hostname)"
echo "Using recommended server $recommendedServer" >&2
serverConfigDir="/etc/openvpn"
configPath="$serverConfigDir/ovpn_$mode/$recommendedServer.$mode.ovpn"
configArchiveUrl="https://downloads.nordcdn.com/configs/archives/servers/ovpn.zip"
configArchiveHost="downloads.nordcdn.com"
if [[ ! -f "$configPath" ]]; then
if confirm-prompt "$recommendedServer is not among known vpn config files. Download new files from $configArchiveHost?"; then
downloadArchivePath="$HOME/.vpnservers.zip"
if wget --no-clobber -O "$downloadArchivePath" "$configArchiveUrl" || true; then
cd "$serverConfigDir"
bak "$serverConfigDir/ovpn_tcp"
bak "$serverConfigDir/ovpn_udp"
sudo unzip "$downloadArchivePath" || {
echo "Failed to unzip server configs into $serverConfigDir"
exit $E_UNZIP
}
rm "$downloadArchivePath"
rmBak "$serverConfigDir/ovpn_tcp"
rmBak "$serverConfigDir/ovpn_udp"
else
echo "Unable to download new VPN server configurations." >&2
exit $E_FAILED_DOWNLOAD
fi
else
echo "Aborting" >&2
exit $E_USER_ABORT
fi
fi
logPath="/var/log/openvpn.log"
if [[ ! -f "$logPath" ]]; then
sudo touch "$logPath"
fi
echo "Using mode '$mode'." >&2
openvpnOptions=()
openvpnOptions+=(--log "$logPath")
openvpnOptions+=(--config "$configPath")
openvpnOptions+=(--daemon)
passPath="/tmp/nordvpn.auth"
if [[ ! -f "$passPath" ]] && confirm-prompt "Remember username/password?"; then
read -p 'Enter Auth Username: ' username
read -p 'Enter Auth Password: ' -s password
echo -e "$username\n$password" > "$passPath"
unset username
unset password
sudoUser="$(sudo whoami)"
sudo chown "$sudoUser" "$passPath"
sudo chmod 600 "$passPath"
fi
if [[ -f "$passPath" ]]; then
echo "Using saved credentials in $passPath." >&2
openvpnOptions+=(--auth-user-pass "$passPath")
fi
if sudo openvpn "${openvpnOptions[@]}"; then
pid=$!
echo "The VPN is now running as a daemon. Run '$(basename "$0") kill' to stop it." >&2
else
exitCode=$?
echo "Failed to start the VPN." >&2
exit $exitCode
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment