What's new

VPN Failover script

Butterfly Bones

Very Senior Member
There was a thread here by another poster. There were some disagreements and that thread was deleted. I found the script by @Martineau on Pastebin, but I have this total inability to grasp scripting so can we bring it back? I'm technically proficient in most things networking, though I am an amateur working on my own network only.

Here is the GitHub link. https://github.com/MartineauUK/VPN-Failover

Can we restart the discussion on this? I have the script copied into my /jffs/scripts directory and chmod to 755, but not clear how to call the script from the openvpn-event script that contains only this.
Code:
#!/bin/sh
cp /jffs/configs/resolv.dnsmasq /tmp/resolv.dnsmasq
I only run one instance of a VPN client and it is very stable, but every so often it will drop connection and then block all clients (as intentionally) configured. I'd like to automatically restart the VPN client, which is what this script appears to accomplish.

My mental block against scripting keeps me from understanding how to set up the originate and terminate scripts. :oops:
Thank you

edit - I've added this line to my openvpn-event
Code:
'sh /jffs/scripts/VPN_Failover 1 ignore=2,3,4,5 interval=60 timeout=45 silent &'
Is this enough with only one VPN client or do I need something else?
 
Last edited:

Butterfly Bones

Very Senior Member
@Martineau
Getting this error.
Code:
@RT-AC86U-1234:/tmp/home/root# sh /jffs/scripts/VPN_Failover.sh: line 643: syntax error: unexpected word (expecting ")")
 

Martineau

Part of the Furniture
There was a thread here by another poster. There were some disagreements and that thread was deleted. I found the script by @Martineau on Pastebin, but I have this total inability to grasp scripting so can we bring it back? I'm technically proficient in most things networking, though I am an amateur working on my own network only.

Here is the pastebin link. https://pastebin.com/RNPJDhjJ

Can we restart the discussion on this? I have the script copied into my /jffs/scripts directory and chmod to 755, but not clear how to call the script from the openvpn-event script that contains only this.
Code:
#!/bin/sh
cp /jffs/configs/resolv.dnsmasq /tmp/resolv.dnsmasq
I only run one instance of a VPN client and it is very stable, but every so often it will drop connection and then block all clients (as intentionally) configured. I'd like to automatically restart the VPN client, which is what this script appears to accomplish.

My mental block against scripting keeps me from understanding how to set up the originate and terminate scripts. :oops:
Thank you

edit - I've added this line to my openvpn-event
Code:
'sh /jffs/scripts/VPN_Failover 1 ignore=2,3,4,5 interval=60 timeout=45 silent &'
Is this enough with only one VPN client or do I need something else?
Perhaps this should be moved to the Asuswrt-Merlin forum, given my script exploits the RMerlin firmware/environment etc.

I assume you have tested the script (v1.10a) via the SSH console, to ensure that it suits your needs?
e.g. Artificially force each VPN connection to FAIL the throughput/performance test
Code:
./VPN_Failover.sh 1 forcesmall minrates=1m,1m,1m,1m,1m verbose=y
NOTE: There are many scenarios for the combination of ACTIVE VPN Clients etc, but I suspect the only guaranteed working scenario is when ALL VPN clients are DOWN, and the script is used to initiate the monitoring.

So I would suggest that the script is initially started asynchronously from either wan-start or init-start for ease of implementation, and your proposed command should be fine.
Code:
'sh /jffs/scripts/VPN_Failover 1 ignore=2,3,4,5 interval=60 timeout=45 silent &'
P.S. The use of the script isn't 100% foolproof, so if your life/health depends on the VPN/Kill switch etc. be aware that whilst the script can either monitor ALL configured GUI VPN clients (or as many server/port/protocol connections for a single VPN Client), there is no explicit watchdog for the VPN_Failover.sh script unless you add it.
 
Last edited:

Martineau

Part of the Furniture
@Martineau
Getting this error.
Code:
@RT-AC86U-1234:/tmp/home/root# sh /jffs/scripts/VPN_Failover.sh: line 643: syntax error: unexpected word (expecting ")")
Which version have you downloaded?
Code:
head -n 2 /jffs/scripts/VPN_Failover.sh
Have you issued
Code:
dos2unix /jffs/scripts/VPN_Failover.sh
I have just performed a download (v1.10a), and the script runs fine here.
Code:
./PastebinScript.sh junk.sh RNPJDhjJ

(PastebinScript.sh): 9675 v1.01 © 2016-2018 Martineau. Get Pastebin script 'junk.sh'.... https://pastebin.com/raw.php?i=RNPJDhjJ
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 37882    0 37882    0     0   169k      0 --:--:-- --:--:-- --:--:--  169k
Code:
./junk.sh

 **ERROR** VPN Client '' is INVALID (1-5 only)
Code:
./junk.sh -h

#======================================================================================================= © 2016-2019 Martineau, v1.10a
#
# Check every 30 secs, and switch to alternate VPN Client if current VPN Client is DOWN, or expected cURL data transfer is 'SLOW'
#
#          VPN_Failover   [-h|--help] | {vpn_instance to monitor} [ignore='csv_vpn_clients] [interval='seconds'] [timeout='seconds']] [force[big | small]
#                         [curlrate='number'] [minrates='csv_rates'] [verbose=y] [delay='seconds'] [noswitch[='hhmm-hhmm'[,...]]] [silent] [multiconfig]
#
#          VPN_Failover   1
#                         Monitor VPN Client 1 every 30 secs and if DOWN switch to VPN Client 2 and then monitor VPN Client 2
#                         (This initiates the round robin for ALL VPN Clients (if configured) in sequence 2,3,4,5 then back to VPN Client 1)
#          VPN_Failover   2 ignore=3,4,5
#                         Monitor VPN Client 2 every 30 secs and if DOWN switch to VPN Client 1 and then monitor VPN Client 1
#                         (This initiates the round robin ONLY for the two VPN Clients; VPN1 (Primary) and VPN2 (Fail-over)
#          VPN_Failover   2 interval=60
#                         Monitor VPN Client 2 every 60 secs and if DOWN switch to VPN Client 3 and then monitor VPN Client 3
#          VPN_Failover   5 timeout=45
#                         Monitor VPN Client 5 every 30 secs and if DOWN switch to VPN Client 1 and allow max 45 secs for Client 1 to start
#                         then monitor VPN Client 1
#          VPN_Failover   3 force curlrate=1M
#                         If the 12MB cURL transfer rate is <1048576 Bytes per second, then treat this as VPN Client 3 'DOWN'
#                         (This cURL rate is not applicable to other VPN Clients if a switch occurs)
#          VPN_Failover   3 force curlrate=1M verbose=y
#                         As previous example, but additional cURL transfer statistics/progress messages are shown on the console. (Useful to determine appropriate 'minrates=')
#          VPN_Failover   3 forcesmall curlrate=1000 verbose=y noswitch=08:59-17:00
#                         If the 433Byte cURL transfer rate is <1000 Bytes per second, no (disruptive) VPN Switch is performed during 'office' hours 9-5
#          VPN_Failover   3 forcesmall curlrate=1000 verbose=y noswitch
#                         If the 433Byte cURL transfer rate is <1000 Bytes per second, no (disruptive) VPN Switch is performed at ANY time.
#                         (If VPN Client 3 is DOWN; the 'noswitch' directive is temporarily ignored to ensure the next round-robin VPN Client is started and found to be UP)
#          VPN_Failover   1 force curlrate=900K minrates=?,500k,123456
#                         Explicitly override three of the VPN Client minimum cURL rates e.g. VPN1=9921600B/sec,VPN2=512000B/sec and VPN3=123456B/sec (VPN4 and VPN5 remain 0B/sec)
#                         If the 12MB cURL transfer rate is <9921600 Bytes per second, then treat this as VPN Client 1 'DOWN'
#                         (If a switch to VPN Client 2 occurs, a min rate of 512000B/sec will be expected, and if a switch to VPN3 occurs, a min rate of 123456B/sec will be expected)
#          VPN_Failover   1 multiconfig
#                         Monitor VPN Client 1 every 30 secs and if DOWN, retrieve the next round-robin VPN Client 1 config from '/jffs/configs/VPN_Failover' and restart VPN Client 1.
#                         (So rather than be limited by 5 VPN GUI configs, you can now specify an unlimited custom server list for a SINGLE VPN ISP
#                         e.g. 1 vpn.LA.server     553     udp     #HMA Los Angeles
#                              1 vpn.NY.server     443     tcp     #HMA New York
#                              1 vpn.SF.server     1194    udp     #HMA San Francisco
 

Butterfly Bones

Very Senior Member
Perhaps this should be moved to the Asuswrt-Merlin forum, given my script exploits the RMerlin firmware/environment etc.

I assume you have tested the script (v1.10a) via the SSH console, to ensure that it suits your needs?
e.g. Artificially force each VPN connection to FAIL the throughput/performance test
Code:
./VPN_Failover.sh 1 forcesmall minrates=1m,1m,1m,1m,1m verbose=y
OK, I'll flag my post and ask that it be moved.

Yes I have version 1.10a. and testing it in the terminal. I run Linux and am comfortable from the command line and using the tools like chmod, etc.

NOTE: There are many scenarios for the combination of ACTIVE VPN Clients etc, but I suspect the only guaranteed working scenario is when ALL VPN clients are DOWN, and the script is used to initiate the monitoring.

So I would suggest that the script is initially started asynchronously from either wan-start or init-start for ease of implementation, and your proposed command should be fine.
Code:
'sh /jffs/scripts/VPN_Failover 1 ignore=2,3,4,5 interval=60 timeout=45 silent &'
OK, that makes more sense now. I added it to wan-start since I have your ChkWAN.sh script running from there as well. I have the "Block routed clients if tunnel goes down"in the VPN Client page and it works, that it partly why I want this script to be able to monitor if the VPN tunnel drops.

P.S. The use of the script isn't 100% foolproof, so if your life/health depends on the VPN/Kill switch etc. be aware that whilst the script can either monitor ALL configured GUI VPN clients (or as many server/port/protocol connections for a single VPN Client), there is no explicit watchdog for the VPN_Failover.sh script unless you add it.
The "Block routed clients if tunnel goes down" works well for me, and nothing is that critical for me.

Have you issued
Code:
dos2unix /jffs/scripts/VPN_Failover.sh
I run Linux so I don't see that necessary. I downloaded the script directly from pastebin via Google Chrome on my Linux box, then uploaded to the AC86U via FileZilla FTP client, did a "chmod 755 VPN_Failover.sh", and then tested from the command line. Everything looked correct since my Linux terminal is color coded for executable files on the router.

I just redid the entire process and now it works as expected. I probably mistyped something. Thank you very much! I'll test it from a few scenarios in the next few hours to confirm the behavior.
 

Butterfly Bones

Very Senior Member
I'm struggling to get this to rum every 15 minutes. I'd prefer to run as a cron like this, similar to how you run the ChkWAN script.
Code:
cru a VPN_Failover "1,16,31,46 * * * * /jffs/scripts/VPN_Failover.sh 1 ignore=3,4,5 silent"
Once started it still runs every 30 seconds.
Code:
Mar 20 12:01:10 (VPN_Failover.sh): 5239 VPN Client Monitor: Checking VPN Client 1 connection status....
Mar 20 12:01:11 (VPN_Failover.sh): 5239 VPN Client Monitor: VPN Client 1 status OK
Mar 20 12:01:41 (VPN_Failover.sh): 5239 VPN Client Monitor: Checking VPN Client 1 connection status....
Mar 20 12:01:41 (VPN_Failover.sh): 5239 VPN Client Monitor: VPN Client 1 status OK
Mar 20 12:02:11 (VPN_Failover.sh): 5239 VPN Client Monitor: Checking VPN Client 1 connection status....
Mar 20 12:02:12 (VPN_Failover.sh): 5239 VPN Client Monitor: VPN Client 1 status OK
Mar 20 12:02:42 (VPN_Failover.sh): 5239 VPN Client Monitor: Checking VPN Client 1 connection status....
Mar 20 12:02:42 (VPN_Failover.sh): 5239 VPN Client Monitor: VPN Client 1 status OK
Mar 20 12:03:12 (VPN_Failover.sh): 5239 VPN Client Monitor: Checking VPN Client 1 connection status....
Mar 20 12:03:12 (VPN_Failover.sh): 5239 VPN Client Monitor: VPN Client 1 status OK
Mar 20 12:03:42 (VPN_Failover.sh): 5239 VPN Client Monitor: Checking VPN Client 1 connection status....
Mar 20 12:03:43 (VPN_Failover.sh): 5239 VPN Client Monitor: VPN Client 1 status OK
I tried the "once" modifier that you use in the ChkWAN script, but that does not seem to work, the VPN_Failover fails to run at all.
I've tried this line from the wan-start, and it runs every 30 seconds. ugh...
Code:
sh/jffs/scripts/VPN_Failover.sh 1 ignore=3,4,5 interval=900 silent &
Any suggestions how to get it to run every 15 minutes and not on hour or half hour where I have other cron jobs. Ideally like above on 1.16.31.46 minutes after each hour.

Thank you.
 

Martineau

Part of the Furniture
I'm struggling to get this to rum every 15 minutes. I'd prefer to run as a cron like this, similar to how you run the ChkWAN script.
Code:
cru a VPN_Failover "1,16,31,46 * * * * /jffs/scripts/VPN_Failover.sh 1 ignore=3,4,5 silent"
Once started it still runs every 30 seconds.
I tried the "once" modifier that you use in the ChkWAN script, but that does not seem to work, the VPN_Failover fails to run at all.
By and large, if invoking the script 'help'
Code:
./VPN_Failover.sh -h
doesn't show the option/directive keyword, then usually it isn't available and you will get an error message and the script will intentionally ABORT if you try to invoke it.
NOTE: Sometimes there are 'hidden' options for debugging etc.;)
I've tried this line from the wan-start, and it runs every 30 seconds. ugh...
Code:
sh/jffs/scripts/VPN_Failover.sh 1 ignore=3,4,5 interval=900 silent &
I have tried specifying interval=900 and the script issues a message indicating when the next invocation of the script will run, and ran as expected:
Code:
./VPN_Failover.sh 1 interval=900

 20:09:29 v1.11 VPN Client Monitor: Checking VPN Client 1 connection status....

            VPN Client 1 connection status OK

            Will check VPN Client 1 connection status again in 900 [email protected]:24:31

 20:24:31 v1.11 VPN Client Monitor: Checking VPN Client 1 connection status....  

            VPN Client 1 connection status OK 

            Will check VPN Client 1 connection status again in 900 [email protected]:39:33
No idea why the script did not seemingly honour your interval=900 directive...unless the args needed to be in quotes if called from wan-start? :confused:

Anyway I have uploaded v1.11 which now includes the 'once' directive
Code:
./VPN_Failover.sh 1 once

 20:08:18 v1.11 VPN Client Monitor: Checking VPN Client 1 connection status....

            VPN Client 1 connection status OK

 20:08:19 v1.11 VPN Client Monitor: Monitoring VPN Client 1 terminated
You should now be able to schedule the script using cru/cron to your desired schedule
 

Butterfly Bones

Very Senior Member
By and large, if invoking the script 'help'
Code:
./VPN_Failover.sh -h
doesn't show the option/directive keyword, then usually it isn't available and you will get an error message and the script will intentionally ABORT if you try to invoke it.
NOTE: Sometimes there are 'hidden' options for debugging etc.;)

I have tried specifying interval=900 and the script issues a message indicating when the next invocation of the script will run, and ran as expected:
Code:
./VPN_Failover.sh 1 interval=900

 20:09:29 v1.11 VPN Client Monitor: Checking VPN Client 1 connection status....

            VPN Client 1 connection status OK

            Will check VPN Client 1 connection status again in 900 [email protected]:24:31

 20:24:31 v1.11 VPN Client Monitor: Checking VPN Client 1 connection status....

            VPN Client 1 connection status OK

            Will check VPN Client 1 connection status again in 900 [email protected]:39:33
No idea why the script did not seemingly honour your interval=900 directive...unless the args needed to be in quotes if called from wan-start? :confused:

Anyway I have uploaded v1.11 which now includes the 'once' directive
Code:
./VPN_Failover.sh 1 once

 20:08:18 v1.11 VPN Client Monitor: Checking VPN Client 1 connection status....

            VPN Client 1 connection status OK

 20:08:19 v1.11 VPN Client Monitor: Monitoring VPN Client 1 terminated
You should now be able to schedule the script using cru/cron to your desired schedule
Thank you, I now have it running. I only have this in the cron.
Code:
1,16,31,46 * * * * /jffs/scripts/VPN_Failover.sh 1 once #VPN_Failover#
If I add "ignore=3,4,5" (with no quotes) it just does not run, though it will in a terminal run from the command line. o_O

I want to test more, but I'm cross eyed from battling this and a couple other things for the last hours. Rain has stopped, time for fresh air. :D

I appreciate the expertise and responding quickly, for us scripting deficient users.
 

RMerlin

Asuswrt-Merlin dev
Why not just use the ping options present in OpenVPN? --ping-restart for instance will restart the connection if no ping is received within a given period of time. Putting multiple remote servers should allow a round-robin reconnection to occur (assuming all servers share the same parameters).
 

Butterfly Bones

Very Senior Member
Why not just use the ping options present in OpenVPN? --ping-restart for instance will restart the connection if no ping is received within a given period of time. Putting multiple remote servers should allow a round-robin reconnection to occur (assuming all servers share the same parameters).
That has not worked for me. I use VPN Unlimited or Pure VPN service and I just added it to my Custom Configuration and get this.
Code:
Mar 20 19:13:07 rc_service: httpds 13536:notify_rc start_vpnclient1
Mar 20 19:13:07 ovpn-client1[16161]: Options error: Unrecognized option or missing or extra parameter(s) in config.ovpn:37: ping-restart (2.4.7)
Mar 20 19:13:07 ovpn-client1[16161]: Use --help for more information.
Mar 20 19:13:07 init: VPN_LOG_ERROR: 487: Starting OpenVPN failed...
 

Butterfly Bones

Very Senior Member

Butterfly Bones

Very Senior Member
You don't need the "--" part.
Still fails to start. AC86U 384.10 beta 2
Remove that line and it runs fine. :confused:
Code:
Mar 21 11:13:03 rc_service: httpds 13536:notify_rc start_vpnclient1
Mar 21 11:13:03 ovpn-client1[16161]: Options error: Unrecognized option or missing or extra parameter(s) in config.ovpn:37: ping-restart (2.4.7)
Mar 21 11:13:03 ovpn-client1[16161]: Use --help for more information.
Mar 21 11:13:03 init: VPN_LOG_ERROR: 487: Starting OpenVPN failed...
 

RMerlin

Asuswrt-Merlin dev
I just tested it with a PIA client and it's working for me.

upload_2019-3-21_14-45-48.png
 

Butterfly Bones

Very Senior Member

RMerlin

Asuswrt-Merlin dev
Just tested with HMA client and it FAILS for me.....
Maybe they are pushing an incompatible setting. The man page indicates that ping-exit and ping-timeout are mutually exclusive. What settings are pushed by your provider?
 

Martineau

Part of the Furniture
You don't need the "--" part.
FYI

'--'
prefix is now optional and accepted by the firmware (can't remember when it changed) to allow users to simply copy'n'paste directives direct from the OpenVPN man page without causing confusing OpenVPN errors, whereas on previous firmware releases the directives had to be edited to remove the prefix on the router.
 

sone

Occasional Visitor
Thank you @Martineau this script is exactly what I was looking for and works perfectly!

---

Just a side question.. if you use the multiconfig option where you list server/ports in /jffs/configs/VPN_Failover.. how do handle the OpenVPN configuration files (certs, settings, authorization, etc) that is usually uploaded for the 5 WebUI clients?
 
Last edited:

Latest threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top