Created
July 8, 2019 18:56
-
-
Save monking/07eaf03d8e9ce99520919ec42857d458 to your computer and use it in GitHub Desktop.
NordVPN helper for GNU/Linux
This file contains hidden or 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 | |
# 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