-
-
Save jonasjancarik/d5b73a1c1274defd290304db1cb0dfaf to your computer and use it in GitHub Desktop.
| echo -e "\n\nDownloading custom ProtonVPN scripts...\n\n" | |
| curl -s -o ~/protonvpn-jj/protonvpn.sh "https://gist.githubusercontent.com/jonasjancarik/d5b73a1c1274defd290304db1cb0dfaf/raw/protonvpn.sh?$RANDOM" | |
| chmod +x ~/protonvpn-jj/protonvpn.sh | |
| curl -s -o ~/Desktop/protonvpn_script.desktop "https://gist.githubusercontent.com/jonasjancarik/d5b73a1c1274defd290304db1cb0dfaf/raw/protonvpn_script.desktop?$RANDOM" | |
| chmod 755 ~/Desktop/protonvpn_script.desktop | |
| gio set ~/Desktop/protonvpn_script.desktop metadata::trusted true | |
| curl -s -o ~/Desktop/protonvpn_disconnect.desktop "https://gist.githubusercontent.com/jonasjancarik/d5b73a1c1274defd290304db1cb0dfaf/raw/protonvpn_disconnect.desktop?$RANDOM" | |
| chmod 755 ~/Desktop/protonvpn_disconnect.desktop | |
| gio set ~/Desktop/protonvpn_disconnect.desktop metadata::trusted true | |
| echo -e "\n\n\e[32m$(tput bold)The script is now installed.$(tput sgr0)\e[0m \nUse the \"ProtonVPN (Free)\" shortcut on the desktop to launch it.\n\n" |
| #!/bin/bash | |
| ################ | |
| # Auto-update # | |
| ################ | |
| # Get the path of the currently installed script | |
| current_script_path=~/protonvpn-jj/protonvpn.sh | |
| # Get the hash of the currently installed script | |
| current_script_hash=$(sha256sum $current_script_path | awk '{print $1}') | |
| # Download the latest version of this script | |
| latest_script_hash=$(set -o pipefail && curl -s https://gist.githubusercontent.com/jonasjancarik/d5b73a1c1274defd290304db1cb0dfaf/raw/protonvpn.sh?$RANDOM | sha256sum | awk '{print $1}') | |
| # Check if the curl command was successful | |
| if [ $? -ne 0 ]; then | |
| echo "${YELLOW}WARNING${ENDCOLOR}: unable to check for updates." | |
| else | |
| # Compare the hashes of the two scripts | |
| if [ ! "$current_script_hash" == "$latest_script_hash" ]; then | |
| read -p "Update available, do you want to download it? (yes/no)" response | |
| if [ "$(echo "$response" | tr '[:upper:]' '[:lower:]')" == "yes" ]; then | |
| echo -e "\nDownloading update to ~/Downloads/protonvpn_install.sh..." | |
| curl -s https://gist.githubusercontent.com/jonasjancarik/d5b73a1c1274defd290304db1cb0dfaf/raw/install.sh?$RANDOM > ~/Downloads/protonvpn_install.sh | |
| chmod +x ~/Downloads/protonvpn_install.sh | |
| echo -e "\nUpdate downloaded, running the install script..." | |
| exec ~/Downloads/protonvpn_install.sh # also exits the current script | |
| else | |
| echo "Update skipped." | |
| fi | |
| fi | |
| fi | |
| ################ | |
| # Main script # | |
| ################ | |
| zip_file=~/Downloads/ProtonVPN_server_configs.zip | |
| config_dir=~/protonvpn_configs | |
| checksum_file="$config_dir/checksum.txt" | |
| auth_fail_counter_file="$config_dir/auth_fail_counter.txt" | |
| # colors | |
| RED="\e[31m" | |
| GREEN="\e[32m" | |
| YELLOW="\e[33m" | |
| ENDCOLOR="\e[0m" | |
| child_process_exit_code="" | |
| # https://www.baeldung.com/linux/background-process-get-exit-code | |
| handle_sigchld() { | |
| if [ -n "$pid" -a ! -d "/proc/$pid" ]; then | |
| wait $pid | |
| child_process_exit_code=$? | |
| # echo pid $pid terminated with exit code $child_process_exit_code | |
| unset pid | |
| fi | |
| } | |
| extract_files() { | |
| # create the target directory if it doesn't exist | |
| mkdir -p "$config_dir" | |
| # remove all .ovpn files from the target directory | |
| find "$config_dir" -type f -name "*.ovpn" -delete 2>/dev/null | |
| # extract the files, silently | |
| # unzip -q -o "$zip_file" -d "$config_dir" 'jp*' | |
| unzip -q -o "$zip_file" -d "$config_dir" | |
| # store the new checksum | |
| echo "$new_checksum" >"$checksum_file" | |
| } | |
| retry_prompt_result="" | |
| retry_prompt() { | |
| # ask user to retry or exit | |
| read -p "Retry? (yes/no)" response | |
| if [ "$(echo "$response" | tr '[:upper:]' '[:lower:]')" == "yes" ]; then | |
| retry_prompt_result="true" | |
| else | |
| retry_prompt_result="false" | |
| echo "Exiting..." | |
| exit 1 | |
| fi | |
| } | |
| check_zip_file() { | |
| config_files=$(find "$config_dir" -type f -name "*.ovpn" 2>/dev/null) | |
| if [ -f "$zip_file" ]; then | |
| # zip file exists | |
| # calculate checksum of the zip file | |
| new_checksum=$(sha256sum "$zip_file" | awk '{print $1}') | |
| if [[ $(find "$zip_file" -mtime +30) ]]; then | |
| echo -e "${YELLOW}WARNING${ENDCOLOR}: The ProtonVPN server configs zip file is older than 30 days. It is recommended to download a new one." | |
| fi | |
| if [ -f "$checksum_file" ]; then | |
| # read stored checksum | |
| old_checksum=$(cat "$checksum_file") | |
| # compare new and stored checksums | |
| if [ "$new_checksum" != "$old_checksum" ]; then | |
| # checksums are different, extract the files | |
| extract_files | |
| fi | |
| else | |
| # checksum file doesn't exist, extract the files | |
| extract_files | |
| fi | |
| else | |
| # zip file doesn't exist | |
| if [[ -z "$config_files" ]]; then | |
| echo -e "\n${RED}ERROR${ENDCOLOR}: No .ovpn config files found in the $config_dir directory. The configs zip file has to be in ~/Downloads to create those." | |
| echo -e "\nPlease download it from https://account.protonvpn.com/downloads#openvpn-configuration-files under OpenVPN configuration files. \n\n Choose these options: \n 1. Select platform: GNU/Linux \n 2. Select protocol: UDP \n 3. Select config file and download: Free server configs \n 4. Click on Download all configurations under the table. \n\n Make sure the downloaded file is in the Downloads folder and that its name is ProtonVPN_server_configs.zip. \n " | |
| # ask user to retry or exit | |
| retry_prompt | |
| if [ "$retry_prompt_result" == "true" ]; then | |
| check_zip_file | |
| fi | |
| else | |
| echo -e "\n${YELLOW}WARNING${ENDCOLOR}: The ProtonVPN server configs zip file was not found. It should be in the ~/Downloads directory to help keep the configs up-to-date. \n\n Please download it from https://account.protonvpn.com/downloads#openvpn-configuration-files under OpenVPN configuration files. \n\n Choose these options: \n 1. Select platform: GNU/Linux \n 2. Select protocol: UDP \n 3. Select config file and download: Free server configs \n 4. Click on Download all configurations under the table. \n\n Make sure the downloaded file is in the Downloads folder and that its name is ProtonVPN_server_configs.zip. \n " | |
| fi | |
| fi | |
| } | |
| check_zip_file | |
| if ! ls "$config_dir"/*.ovpn 1>/dev/null 2>&1; then | |
| echo -e "\n${YELLOW}WARNING${ENDCOLOR}: No configuration files found in the directory $config_dir. Trying to get them from the downloaded configs file...\n" | |
| extract_files | |
| fi | |
| # Check if the current version of update-resolv-conf script is different from the one at GitHub | |
| update_resolv_conf_file="/etc/openvpn/update-resolv-conf" | |
| update_resolv_conf_url="https://raw.githubusercontent.com/ProtonVPN/scripts/master/update-resolv-conf.sh" | |
| if [ -f "$update_resolv_conf_file" ]; then | |
| local_hash=$(sha256sum "$update_resolv_conf_file" | awk '{print $1}') | |
| remote_hash=$(wget -qO- "$update_resolv_conf_url" | sha256sum | awk '{print $1}') | |
| if [ "$local_hash" != "$remote_hash" ]; then | |
| echo "Backing up the current version of update-resolv-conf script to $update_resolv_conf_file.bak" | |
| sudo cp "$update_resolv_conf_file" "$update_resolv_conf_file.bak" | |
| sudo wget "$update_resolv_conf_url" -O "$update_resolv_conf_file" | |
| sudo chmod +x "$update_resolv_conf_file" | |
| fi | |
| else | |
| sudo wget "$update_resolv_conf_url" -O "$update_resolv_conf_file" | |
| sudo chmod +x "$update_resolv_conf_file" | |
| fi | |
| # check if the credentials.txt file exists, if not, ask the user to provide credentials | |
| credentials_file="$config_dir/credentials.txt" | |
| if [ ! -f "$credentials_file" ]; then | |
| echo -e "We need special login details for this - i.e. not your regular ProtonVPN password. Get them from the OpenVPN/IKEv2 username section at https://account.protonvpn.com/account#openvpn\n" | |
| read -p "Username: " username | |
| read -p "Password: " password | |
| echo "$username" >"$credentials_file" | |
| echo "$password" >>"$credentials_file" | |
| rm -f "$auth_fail_counter_file" | |
| fi | |
| if ! sudo -n true 2>/dev/null; then | |
| echo -e "Please enter your password to enable the connection: " | |
| # dummy sudo command to enable sudo for this session | |
| sudo -v | |
| fi | |
| attempt_counter=0 | |
| random_config_file="" | |
| no_config_files_left() { | |
| # echo a message starting with an empty line | |
| echo -e "\n${RED}ERROR${ENDCOLOR}: No configuration files left in the directory $config_dir." | |
| echo -e "Removing the configs zip file to prevent reusing outdated configs..." | |
| rm -f $zip_file | |
| echo -e "\nPlease download a new one from https://account.protonvpn.com/downloads#openvpn-configuration-files under OpenVPN configuration files. \n\n Choose these options: \n 1. Select platform: GNU/Linux \n 2. Select protocol: UDP \n 3. Select config file and download: Free server configs \n 4. Click on Download all configurations under the table. \n\n Make sure the downloaded file is in the Downloads folder and that its name is ProtonVPN_server_configs.zip. \n " | |
| retry_prompt | |
| if [ "$retry_prompt_result" == "true" ]; then | |
| exec $current_script_path | |
| else | |
| exit 1 | |
| fi | |
| } | |
| choose_country() { | |
| # ask the user what country they want to connect through, JP, US or NL: | |
| echo -e "\nPlease choose a country to connect through: \n 1. Japan \n 2. United States \n 3. Netherlands \n" | |
| read -p "Enter a number: " country_number | |
| if [ "$country_number" == "1" ]; then | |
| country="jp" | |
| country_full="Japan" | |
| elif [ "$country_number" == "2" ]; then | |
| country="us" | |
| country_full="the United States" | |
| elif [ "$country_number" == "3" ]; then | |
| country="nl" | |
| country_full="the Netherlands" | |
| else | |
| echo -e "\n${RED}ERROR${ENDCOLOR}: Invalid input. Please enter a number between 1 and 3.\n" | |
| choose_country | |
| fi | |
| } | |
| choose_country | |
| echo -e "\n" | |
| # start OpenVPN using the credentials file and the randomly chosen .ovpn file | |
| while true; do | |
| if ls "$config_dir"/*.ovpn 1>/dev/null 2>&1; then | |
| # store a random config file in the variable random_config_file | |
| random_config_file=$(find $config_dir -name "$country*.ovpn" | shuf -n 1) | |
| else | |
| no_config_files_left | |
| fi | |
| if [ "$attempt_counter" -ge 1 ]; then | |
| echo -e "Trying configuration file: $random_config_file..." | |
| fi | |
| # create the logs directory if it doesn't exist | |
| mkdir -p $config_dir/log | |
| # clear the log file | |
| truncate -s 0 $config_dir/log/openvpn.log | |
| # kill any previously open OpenVPN processes - redirect errors to /dev/null | |
| sudo killall openvpn 2>/dev/null | |
| # count the number of lines in the config file which start with "remote " | |
| # number_of_servers=$(grep -c "^remote " "$random_config_file") | |
| # start OpenVPN in the background | |
| # sudo openvpn --mute-replay-warnings --config "$random_config_file" --auth-user-pass $credentials_file --connect-timeout 10 --connect-retry-max 1 --resolv-retry $number_of_servers --log $config_dir/log/openvpn.log & | |
| sudo openvpn --mute-replay-warnings --config "$random_config_file" --auth-user-pass $credentials_file --connect-timeout 10 --connect-retry 0 --connect-retry-max 1 --log $config_dir/log/openvpn.log & | |
| # save the PID of the OpenVPN process | |
| pid=$! | |
| # echo $pid # for debugging | |
| # Trap signals and kill the subprocess when the script is interrupted or terminated | |
| trap "if ps -p $pid > /dev/null; then kill $pid; fi" SIGINT SIGTERM INT TERM SIGHUP EXIT | |
| trap handle_sigchld SIGCHLD | |
| connection_detected="false" | |
| counter=0 | |
| # wait for the OpenVPN process to finish | |
| while kill -0 $pid 2> /dev/null; do | |
| if ! $connection_detected; then | |
| echo -ne "\r${YELLOW}Connecting through ${country_full} using ProtonVPN... (${counter} seconds)${ENDCOLOR}" | |
| # increment counter | |
| counter=$((counter+1)) | |
| fi | |
| # check if the connection was successful | |
| if ! $connection_detected && sudo grep -q "Initialization Sequence Completed" "$config_dir/log/openvpn.log"; then | |
| connection_detected="true" | |
| echo -ne "\r" | |
| tput el | |
| echo -e "${GREEN}You are now connected through ${country_full} using ProtonVPN.${ENDCOLOR}" | |
| echo -e "\r- To disconnect, press Ctrl+C" | |
| echo -e "\r- If you just close this window, you may have to use the 'Disconnect ProtonVPN' shortcut on the desktop to actually disconnect." | |
| echo "0" >> "$auth_fail_counter_file" | |
| ip_api_response="" | |
| get_ip_details() { | |
| ip_api_response=$(curl -s http://ip-api.com/json/?fields=country,regionName,city,zip,lat,lon,isp,query) | |
| } | |
| api_details_obtained="false" | |
| # try to get the IP details 5 times | |
| for i in {1..5}; do | |
| get_ip_details | |
| if [ $? -eq 0 ]; then | |
| api_details_obtained="true" | |
| echo -e "\n\r" | |
| # clear line | |
| tput el | |
| echo -e "You are connected through this location:" | |
| query=$(echo $ip_api_response | jq -r '.query') | |
| country=$(echo $ip_api_response | jq -r '.country') | |
| regionName=$(echo $ip_api_response | jq -r '.regionName') | |
| city=$(echo $ip_api_response | jq -r '.city') | |
| zip=$(echo $ip_api_response | jq -r '.zip') | |
| lat=$(echo $ip_api_response | jq -r '.lat') | |
| lon=$(echo $ip_api_response | jq -r '.lon') | |
| isp=$(echo $ip_api_response | jq -r '.isp') | |
| org=$(echo $ip_api_response | jq -r '.org') | |
| echo -en "\n\rIP:\t\t$query" | |
| echo -en "\n\rCountry:\t$country" | |
| echo -en "\n\rRegion:\t\t$regionName" | |
| echo -en "\n\rCity:\t\t$city" | |
| echo -en "\n\rZip:\t\t$zip" | |
| echo -en "\n\rLat:\t\t$lat, lon: $lon" | |
| echo -en "\n\rISP:\t\t$isp" | |
| echo -en "\n\rOrg.:\t\t$org" | |
| echo -e "\n\r" | |
| break | |
| fi | |
| sleep 1 | |
| done | |
| fi | |
| if ! $connection_detected; then | |
| sleep 1 | |
| fi | |
| done | |
| echo -e "\n" | |
| echo -ne "\r" | |
| # echo $pid # for debugging | |
| # echo $! # for debugging | |
| # echo $? # for debugging | |
| # reset trap | |
| trap - SIGINT SIGTERM | |
| echo -e "\n" | |
| if [ $child_process_exit_code -ne 0 ]; then | |
| echo "OpenVPN connection failed." | |
| if sudo grep -qE "(All connections have been connect-retry-max.*times unsuccessful, exiting)|(Cannot resolve host address)" "$config_dir/log/openvpn.log"; then | |
| echo "The current configuration file is not working. Renaming it to ${random_config_file}_old" | |
| mv "$random_config_file" "${random_config_file}_old" | |
| if [ $(ls "$config_dir"/*.ovpn | wc -l) -eq 0 ]; then # todo: redirect errors | |
| no_config_files_left | |
| else | |
| echo -e "\n\r" | |
| read -p "Do you want to try again with a different configuration file? (yes/no)" answer | |
| if [ "$(echo "$answer" | tr '[:upper:]' '[:lower:]')" != "yes" ]; then | |
| echo "Exiting." | |
| exit 0 | |
| fi | |
| attempt_counter=$((attempt_counter + 1)) | |
| fi | |
| else | |
| echo -e "\n\rAn unknown error occurred. Exiting.\n\r" | |
| read -n1 -p "Press any key to exit." | |
| echo -e "\n\r" | |
| exit 1 | |
| fi | |
| else | |
| # for some reason auth fail does not exit with a non-zero exit code | |
| if sudo grep -q "AUTH: Received control message: AUTH_FAILED" "$config_dir/log/openvpn.log"; then | |
| echo -e "\n\rAuthentication failed." | |
| # load the counter file | |
| if [ ! -f "$auth_fail_counter_file" ]; then | |
| echo "1" >> "$auth_fail_counter_file" | |
| auth_fail_count=1 | |
| echo -e "\rSometimes this is temporary. Please try again.\n" | |
| else | |
| auth_fail_count=$(cat "$auth_fail_counter_file") | |
| auth_fail_count=$((auth_fail_count + 1)) | |
| echo "$auth_fail_count" > "$auth_fail_counter_file" | |
| read -p "This may be temporary, but your saved login details have already failed ${auth_fail_count} times. Would you like to remove them? (yes/no)" answer | |
| if [ "$answer" = "yes" ]; then | |
| mv "$credentials_file" "$credentials_file"_old | |
| rm "$auth_fail_counter_file" | |
| echo -e "Your login details have been removed (backed up to ${credentials_file}_old). Please try again." | |
| exit 0 | |
| fi | |
| fi | |
| read -n1 -p "Press any key to exit." | |
| echo -e "\n" | |
| exit 1 | |
| fi | |
| echo -e "\nOpenVPN connection closed.\n\r" | |
| read -n1 -p "Press any key to exit." | |
| echo -e "\n\r" | |
| exit 0 | |
| fi | |
| done |
| [Desktop Entry] | |
| Type=Application | |
| Name=Disconnect ProtonVPN (Free) | |
| Exec=sh -c "sudo killall openvpn 2>/dev/null" | |
| Icon=gnome-globe-net | |
| Terminal=true |
| [Desktop Entry] | |
| Type=Application | |
| Name=ProtonVPN (Free) | |
| Exec=sh -c "~/protonvpn-jj/protonvpn.sh" | |
| Icon=gnome-globe-net | |
| Terminal=true |
if I am not mistaken, this looks like a shell script to query the protonvpn api to get a server and/or openvpn configuration?
Is there any documentation or a repository somewhere like github?
I've been looking for a script to get all the premium configurations from the API - either all of them, or just for example, the united states ones.
If only I could find a script to get the lowest load premium US server and spit out the configuration file
Sorry I missed your comment. Check out https://github.com/jonasjancarik/protonvpn-cli-community/ - you can use CLI flags to auto connect to the fastest server in a given country. There is an official CLI but I don't think it has that functionality at the moment https://github.com/ProtonVPN/proton-vpn-cli
Install with
curl -s "https://gist.githubusercontent.com/jonasjancarik/d5b73a1c1274defd290304db1cb0dfaf/raw/install.sh?$RANDOM" | bash