Skip to content

Instantly share code, notes, and snippets.

@lski
Last active December 4, 2020 14:02
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 lski/84c0d2893cea0d43c34a29e74aaf6f3c to your computer and use it in GitHub Desktop.
Save lski/84c0d2893cea0d43c34a29e74aaf6f3c to your computer and use it in GitHub Desktop.
A script with several command to control a connection to a NordVPN server via the OpenVPN client (as Wireguard casuing issues)
[Unit]
Description=NordVPN Auto Start
After=multi-user.target
After=network-online.target
[Service]
User=root
Type=forking
ExecStart=/home/pi/nordvpn.sh open uk
[Install]
WantedBy=multi-user.target
#!/bin/bash
read -r -d '' HELP << EOM
########################################
##
## An interface for working with NordVPN using the OpenVPN cli package and .ovpn files.
## NB: Must run the 'setup' command on first use.
##
## Commands: (parameters marked [] are optional)
##
## - setup [username] [password]
## Runs auth followed by update_servers to setup a login and download all the server connection information from NordVPN
## - [username] The NordVPN username from your profile page, will prompt if not supplied
## - [password] The NordVPN password from your profile page, will prompt if not supplied
##
## - auth [username] [password]
## Sets an auth file to enable no password opening connection
## - [username] The NordVPN username from your profile page, will prompt if not supplied
## - [password] The NordVPN password from your profile page, will prompt if not supplied
##
## - countries
## Lists countries and their country code for NordVPN, useful for reference.
##
## - recommended []
## returns the current recommended server for the country code
## - [country code] A country code, matching the country codes returned from 'countries' (default: gb)
##
## - update_servers username password
## Resets and downloads all the server connection information from NordVPN and sets login details
## - username The NordVPN username from your profile page
## - password The NordVPN password from your profile page
##
## - open_domain [nord vpn domain] [type] [logfile]
## Opens a VPN connection using the NordVPN server domain in the format returned from 'recommended'
## - [nord vpn domain] A domain name in the format 'uk2056.nordvpn.com'
## - [type] The type tcp or udp (default: udp)
## - [logfile] The output from the OpenVPN connection (default: /etc/openvpn/nord_servers/connection.log)
##
## - open [country code] [type] [logfile]
## opens a VPN connection accepting a country code rather than domain
## - [country code] The country code to open the connection for
## - [type] The type tcp or udp (default: udp)
## - [logfile] The output from the OpenVPN connection (default: /etc/openvpn/nord_servers/connection.log)
##
## - close
## closes all VPN connections by closing openvpn
##
## - status [-v]
## Shows the current status of the VPN and what your IP is (according to NordVPN)
## [-v] Verbose, full details, otherwise returns 'Connected' or 'Disconnected' only
##
## - help
## Shows this message
##
## Recommeneded usages:
## sudo ./nordvpn.sh setup myusername mypassword
## sudo ./nordvpn.sh open us
## sudo ./nordvpn.sh close
## sudo ./nordvpn.sh status
##
########################################
EOM
! [ $(command -v jq) ] && echo "Installing jq" && sudo apt install jq -y -qq
! [ $(command -v openvpn) ] && echo "Installing openvpn" && sudo apt install openvpn -y -qq
NORD_SERVER_LOCATION=/etc/openvpn/nord_servers
check_root () {
# Checks if the function is run as sudo, wont work otherwise
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root"
exit 1
fi
}
function vpn_open {
check_root;
local SERVER=$1;
local LOG=${2:-/etc/openvpn/connection.log};
if [ -z $SERVER ]
then
echo "Server is required"
exit 1;
fi
echo "Opening VPN Connection"
openvpn $SERVER >> "$LOG" &
}
function vpn_close {
check_root;
killall -SIGINT openvpn
}
function nordvpn_countries {
wget -qO- https://nordvpn.com/wp-admin/admin-ajax.php?action=servers_countries | jq -j '.[] | (.code + ", " + .name + "\n")';
}
function nordvpn_recommended() {
local COUNTRY=${1:-gb};
local COUNTRY=${COUNTRY^^}
# Normalise UK as GB as its more obvious that GB
[[ $COUNTRY == "UK" ]] && local COUNTRY=gb;
# Get the country code
local COUNTRY_CODE=$(wget -qO- https://nordvpn.com/wp-admin/admin-ajax.php?action=servers_countries | jq '.[]| select(.code | test("^'$COUNTRY'$"; "i")) | .id');
# Exit with error if none can be found
if [ -z $COUNTRY_CODE ]; then
echo "Country: '$COUNTRY' could not be found";
exit 0;
fi
local server=$(wget -qO- 'https://nordvpn.com/wp-admin/admin-ajax.php?action=servers_recommendations&filters={%22country_id%22:'$COUNTRY_CODE'}' | jq -j '.[0].hostname');
# Add server domain name to output
echo $server
exit 1;
}
function nordvpn_open_domain {
local SERVER=$1;
local TYPE=${2:-udp} # Should be a flag
local LOG=${3:-$NORD_SERVER_LOCATION/connection.log};
if [ -z $SERVER ]
then
echo "Server is required"
exit 1;
fi
echo "NornVPN Server: $SERVER"
vpn_open "/etc/openvpn/nord_servers/ovpn_$TYPE/$SERVER.$TYPE.ovpn"
exit 0;
}
function nordvpn_open {
check_root;
nordvpn_open_domain $(nordvpn_recommended $1) $2 $3
}
function nordvpn_setup {
nordvpn_auth $1 $2
nordvpn_update_servers
}
function nordvpn_auth {
check_root;
local USERNAME=${1}
local PASSWORD=${2}
# Prompt the user for a username if missing
if [ -z $USERNAME ]; then
echo -n "Username: "
read USERNAME
echo # Adds a new line
if [ -z $USERNAME ]; then
echo "Username is required";
exit 0;
fi
fi
# Prompt the user for a password if missing
if [ -z $PASSWORD ]; then
echo -n "Password: "
read -s PASSWORD #-s turns off the echo
echo # Adds a new line
if [ -z $PASSWORD ]; then
echo "Password is required";
exit 0;
fi
fi
echo "Creating auth file"
echo $USERNAME > "$NORD_SERVER_LOCATION/auth.txt"
echo $PASSWORD >> "$NORD_SERVER_LOCATION/auth.txt"
cd $currentDir
}
function nordvpn_update_servers {
check_root;
# If no auth file exists then nobody logged in prior to updating the
if [ ! -f /etc/openvpn/nord_servers/auth.txt ]; then
echo "Authentication is not set, please run setup or auth to set authentication"
exit 1;
fi
# Clear out any previous downloads and server files
echo "Preparing to update servers"
rm -rf $NORD_SERVER_LOCATION/ovpn_udp/
rm -rf $NORD_SERVER_LOCATION/ovpn_tcp/
[ -f "ovpn.zip" ] && sudo rm ovpn.zip
echo "Downloading files"
wget -q https://downloads.nordcdn.com/configs/archives/servers/ovpn.zip
echo "Extracting files"
unzip -qq ovpn.zip -d $NORD_SERVER_LOCATION
rm ovpn.zip
echo "Adding auth file to ovpn files"
for i in $NORD_SERVER_LOCATION/ovpn_udp/*; do sudo sed -i 's|auth-user-pass|auth-user-pass '$NORD_SERVER_LOCATION'/auth.txt|g' "$i"; done
for i in $NORD_SERVER_LOCATION/ovpn_tcp/*; do sudo sed -i 's|auth-user-pass|auth-user-pass '$NORD_SERVER_LOCATION'/auth.txt|g' "$i"; done
}
function nordvpn_status() {
local url='https://nordvpn.com/wp-admin/admin-ajax.php?action=get_user_info_data'
if [[ $1 == "-v" ]]; then
wget -qO- $url | jq -r '(if .status == true then "Connected" else "Disconnected" end) as $status | ("Status: " + $status + "\nIP: " + .ip + "\nLocation: " + .country + (if .city != "Unknown" then ", " + .city else "" end) + (if .region != "Unknown" then ", " + .region else "" end)) | .'
else
wget -qO- $url | jq -r '(if .status == true then "Connected" else "Disconnected" end) | .'
fi
}
if [[ $1 == 'countries' ]]; then
nordvpn_countries
exit 1;
elif [[ $1 == 'recommended' ]]; then
nordvpn_recommended
exit 1;
elif [[ $1 == 'update_servers' ]]; then
nordvpn_update_servers
exit 1;
elif [[ $1 == 'setup' ]]; then
nordvpn_setup $2 $3
exit 1;
elif [[ $1 == 'auth' ]]; then
nordvpn_auth $2 $3
exit 1;
elif [[ $1 == 'open_domain' ]]; then
nordvpn_open_domain $2 $3 $4
exit 1;
elif [[ $1 == 'open' ]]; then
nordvpn_open $2 $3
exit 1;
elif [[ $1 == 'close' ]]; then
vpn_close
exit 1;
elif [[ $1 == 'status' ]]; then
nordvpn_status $2
exit 1;
elif [[ $1 == 'help' ]]; then
echo "$HELP";
exit 1;
else
echo "$1 not recognised"
exit 0;
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment