OpenVPN profile switcher for NordVPN

Hi all,

I wrote a script that polls NordVPN API (documentation by Milosz Galazka), for a recommended server by parameters given by the user, then grabs the appropriate .ovpn profile from NordVPN's servers and sets OpenVPN to use it.

The script uses the bare minimum I was able to get by with, so it can run on pretty much any router that already runs OpenVPN and has approximately 200kB extra (for sending GET requests, requires package for TLS).

The script can be found at https://github.com/UriShX/vpn-profile-switcher. I believe the README describes pretty much everything, but if I left something out or something needs clarification drop me a note here, or open an issue on Github. PRs are welcome.

I saw a couple of threads on the forum (1, 2) discussing a need for a similar thing, so hopefully it will be useful to others beside me too.

I've been using the script to maintain my connection with the VPN server, by running it from crontab every hour. It could maybe do with a bit of improvements, but it's still better in my opinion then checking the NordVPN's recommendation and setting the profile manually each the load on the server increases.

2 Likes

What's the advantage of using the script over listing multiple remotes in the same config?

2 Likes

For me the benefit is mostly knowing I'll keep being connected to the lowest load server in a group + country combination each time I run it from crontab, while keeping only 2 configuration files on the router. That means there's no need to either download the zipped package of configs (which is over 26 MB), no need to maintain the list of configs, or going to the recommendations web app for checking which server supports P2P, for example.

1 Like

by running it from crontab every hour

Not sure if I want my zoom/streaming session disconnected half way through. Maybe once a day in the middle of the night, but then the load dynamic be different during the day.

1 Like

Thanks for your comment mate,

Thanks to it, I tested running the script while making a Zoom call earlier today. The call froze for ~15-20 seconds, then resumed (once OpenVPN restarted, and then some more I suppose). I don't do a lot of video chats / streaming, so doing the crontab thing works in my use case just fine.
In this case, maybe running a script from /etc/rc.local might be useful - besides a watchdog checking for failed connection like in NordVPN's tutorial, it might be useful to check the average ping round trip speeds. I wrote a quick script for that:

#!/bin/sh

# Ping N times
N=10
# Upper Bound for round-trip average
UB=120

while sleep 50; do
    # ping in quiet mode for N times, 
    # grab last raw and evaluate if the avg. round trip took longer then expected
    T=$(ping -qc "$N" 1.1.1.1 |  awk -F '\/' -v UB=$UB '/round-trip/{print ($4+0)<=UB}')

    if [ "$T" -eq 0 ]; then
        /root/vpn-profile-switcher.sh
    fi  
done

I haven't tried it out yet, and I suppose it might be better implemented when combined with NordVPN's (simplistic) watchdog at the bottom of their tutorial. Maybe something a bit more elaborate in the style of this watchdog is more appropriate.

I do think the automatic profile switching script needs a few other functions built in to it, such as:

  • Checking if the server currently connected is between the first few result of the recommended servers and what is the load on each of those first few recommended servers.
  • Saving more then one profile, so I could always be able to switch to a known good server.
  • Switch to the last known good server, or to a specified known-to-be-good one.
  • Check if JQ is installed, and if so forgo using an intermediary for checking for good group + country combinations (by creating a local db, like I set up to be done by a Github action).
1 Like