Dual WAN Failover Script

Ranger802004

Very Senior Member
WAN Failover is designed to replace the factory ASUS WAN Failover functionality, this script will monitor the WAN Interfaces using a Target IP Address and pinging these targets to determine when a failure occurs. When a failure is detected in Failover Mode, the script will switch to the Secondary WAN interface automatically and then monitor for failback conditions. When the Primary WAN interface connection is restored based on the Target IP Address, the script will perform the failback condition and switch back to Primary WAN. When a failure is detected in Load Balancing Mode, the script will remove the down WAN interface from Load Balancing and restore it when it is active again.

Requirements:
- ASUS Merlin Firmware v386.5 or higher
- JFFS custom scripts and configs Enabled
- Dual WAN Enabled
- ASUS Factory Failover Disabled (Network Monitoring Options, Allow Failback Option under WAN > Dual WAN)

Installation:
Code:
/usr/sbin/curl -s "https://raw.githubusercontent.com/Ranger802004/asusmerlin/main/wan-failover.sh" -o "/jffs/scripts/wan-failover.sh" && chmod 755 /jffs/scripts/wan-failover.sh && sh /jffs/scripts/wan-failover.sh install

Updating:
Code:
/jffs/scripts/wan-failover.sh update

Uninstallation:
Code:
/jffs/scripts/wan-failover.sh uninstall

Configuration:
During installation or reconfiguration, the following settings are configured:
- WAN0 Target: This is the target IP address for WAN0, the script will monitor this IP via ICMP Echo Requests “ping” over the WAN0 interface. Verify the target IP address is a valid server for ICMP Echo Requests prior to installation or configuration. It is recommended to use different Target IP Addresses for each WAN interface. Example: 8.8.8.8
- WAN1 Target: This is the target IP address for WAN1, the script will monitor this IP via ICMP Echo Requests “ping” over the WAN1 interface. Verify the target IP address is a valid server for ICMP Echo Requests prior to installation or configuration. It is recommended to use different Target IP Addresses for each WAN interface. Example: 8.8.4.4
- Ping Count: This is how many consecutive times a ping must fail before a WAN connection is considered disconnected.
- Ping Timeout: This is how many seconds a single ping attempt will execute before timing out from no ICMP Echo Reply “ping”. If using an ISP with high latency such as satellite internet services, consider setting this to a higher value such as 3 seconds or higher.
- WAN Disabled Timer: This is how many seconds the script pauses and checks again if Dual WAN, Failover Mode, or WAN links are disabled/disconnected.
- Boot Delay Timer: This is how many seconds System Uptime has to be before script begins checking WAN Status.
- QoS Settings are configured for each WAN interface because both interfaces may not have the same bandwidth (download/upload speeds). The script will automatically change these settings for each interface as they become the active WAN interface. If QoS is disabled or QoS Automatic Settings are being used, these settings will not be applied.
o WAN0 QoS Download Bandwidth: Value is in Mbps
o WAN1 QoS Download Bandwidth: Value is in Mbps
o WAN0 QoS Upload Bandwidth: Value is in Mbps
o WAN1 QoS Upload Bandwidth: Value is in Mbps
o WAN0 QoS Packet Overhead: Value is in Bytes
o WAN1 QoS Packet Overhead: Value is in Bytes
o WAN0 QoS ATM: This will enable or disable Asynchronous Transfer Mode (ATM) for WAN0, research this technology to verify it is not required for your ISP. In most use cases, this setting is Disabled.
o WAN1 QoS ATM: This will enable or disable Asynchronous Transfer Mode (ATM) for WAN1, research this technology to verify it is not required for your ISP. In most use cases, this setting is Disabled.
- Packet Loss Logging: This will log packet loss detections that are less than 100% packet loss but more than 0% packet loss. These events are not enough to trigger a WAN Failover/Failback condition but may be informal data as to the performance of a WAN interface. If the Ping Timeout setting is too low (1-2 seconds) combined with a high latency WAN interface such as satellite internet services, this logging can become excessive with the described configuration.

Optional Configuration:
- To enable or disable email notifications, pass the command arguments "email enable" or "email disable", default mode is Enabled. Example: "/jffs/scripts/wan-failover.sh email enable" ***Email Notifications work with amtm or AIProtection Alert Preferences****
Options that can be adjusted in the configuration file
- BOOTDELAYTIMER: This will delay the script from executing until System Uptime reaches this time.
- SKIPEMAILSYSTEMUPTIME: This will delay sending emails while System Uptime is less than this time. Default: 180 Seconds
- EMAILTIMEOUT: This defines the timeout for sending an email after a Failover/Failback event. Default: 30 Seconds
- WAN0TARGETRULEPRIORITY: This defines the IP Rule Priority for the WAN0 Target IP Address. Default: 100
- WAN1TARGETRULEPRIORITY: This defines the IP Rule Priority for the WAN1 Target IP Address. Default: 100
- LBRULEPRIORITY: This defines the IP Rule priority for Load Balance Mode, it is recommended to leave this default unless necessary to change. Default: 150
- OVPNSPLITTUNNEL: This will enable or disable OpenVPN Split Tunneling while in Load Balance Mode. Default: 1 (Enabled)
- WAN0ROUTETABLE: This defines the Routing Table for WAN0, it is recommended to leave this default unless necessary to change. Default: 100
- WAN1ROUTETABLE: This defines the Routing Table for WAN1, it is recommended to leave this default unless necessary to change. Default: 200
- WAN0MARK: This defines the FW Mark used to mark and match traffic for WAN0 in IPTables Rules. Default: 0x80000000
- WAN1MARK: This defines the FW Mark used to mark and match traffic for WAN1 in IPTables Rules. Default: 0x90000000
- WAN0MASK: This defines the FW Mask used to mark and match traffic for WAN0 in IPTables Rules. Default: 0xf0000000
- WAN1MASK: This defines the FW Mask used to mark and match traffic for WAN1 in IPTables Rules. Default: 0xf0000000
- FROMWAN0PRIORITY: This defines the IP Rule Priority for Traffic from WAN0 that are automatically created by Load Balance Mode. It is recommended to leave this default unless necessary to change. Default: 200
- FROMWAN1PRIORITY: This defines the IP Rule Priority for Traffic from WAN1 that are automatically created by Load Balance Mode. It is recommended to leave this default unless necessary to change. Default: 200
- TOWAN0PRIORITY: This defines the IP Rule Priority for Traffic to WAN0 that are automatically created by Load Balance Mode. It is recommended to leave this default unless necessary to change. Default: 400
- TOWAN1PRIORITY: This defines the IP Rule Priority for Traffic to WAN1 that are automatically created by Load Balance Mode. It is recommended to leave this default unless necessary to change. Default: 400
- OVPNWAN0PRIORITY: This defines the OpenVPN Tunnel Priority for WAN0 if OVPNSPLITTUNNEL is 0 (Disabled). Default: 100
- OVPNWAN1PRIORITY: This defines the OpenVPN Tunnel Priority for WAN1 if OVPNSPLITTUNNEL is 0 (Disabled). Default: 200

Run Modes:
- Install Mode: This will install the script and configuration files necessary for it to run. Add the command argument "install" to use this mode.
- Uninstall Mode: This will uninstall the configuration files necessary to stop the script from running. Add the command argument "uninstall" to use this mode.
- Run Mode: This mode is for the script to run in the background via cron job. Add the command argument "run" to use this mode.
- Update Mode: This mode will check to see if there is an update available from the GitHub Repository and update. (v1.3.7 or higher)
- Configuration Mode: This will allow reconfiguration of WAN Failover to update or change settings. Add the command argument "config" to use this mode (v1.4.2 or higher)
- Manual Mode: This will allow you to run the script in a command console. Add the command argument "manual" to use this mode.
- Switch WAN Mode: This will manually switch the Primary WAN. Add the command argument "switchwan" to use this mode.
- Email Configuration Mode: This will enable or disable email notifications using enable or disable parameter. Add command argument "email enable" or "email disable".
- Monitor Mode: This will monitor the log file of the script. Add the command argument "monitor" to use this mode.
- Restart Mode: This will restart the script if it is currently running. Add the command argument "restart" to use this mode. (v1.5.5 or higher)
- Kill Mode: This will kill any running instances of the script. Add the command argument "kill" to use this mode.
- Cron Job Mode: This will create the Cron Jobs necessary for the script to run and also perform log cleaning. Add the command argument "logclean" to use this mode.

Link to Script:
https://raw.githubusercontent.com/Ranger802004/asusmerlin/main/wan-failover.sh

Readme:
https://raw.githubusercontent.com/Ranger802004/asusmerlin/main/wan-failover-readme.txt

Release Notes:
***View the Readme***
 
Last edited:

rlj2

Senior Member
Hello guys, I have attached a script I wrote to replace the built in Failover function from ASUS that is awful. Please let me know if you have any suggestions or questions, thank you. You can set this to run in the background with a cron job or let another script start it like wan-event, also you will see there are several variables you can set from within the script.
 

rlj2

Senior Member
Ill mess with this later, but apparently its failing with the ping command, probably this though
wan0_dns=1.1.1.1 8.8.8.8
wan0_dns1_x=
wan0_dns2_x=


[email protected]:/jffs/scripts# ./wanup
Checking if ./wanup is already running...
BusyBox v1.25.1 (2022-03-25 10:23:25 EDT) multi-call binary.

Usage: ping [OPTIONS] HOST

Send ICMP ECHO_REQUEST packets to network hosts

-4,-6 Force IP or IPv6 name resolution
-c CNT Send only CNT pings
-s SIZE Send SIZE data bytes in packets (default:56)
-t TTL Set TTL
-I IFACE/IP Use interface or IP address as source
-M hint Path MTU Discovery strategy [do|want|dont]
-W SEC Seconds to wait for the first response (default:10)
(after all -c CNT packets are sent)
-w SEC Seconds until ping exits (default:infinite)
(can exit earlier with -c CNT)
-q Quiet, only display output at start
and when finished
-p Pattern to use for payload
 
Last edited:

Ranger802004

Very Senior Member
Ill mess with this later, but apparently its failing with the ping command, probably this though
wan0_dns=1.1.1.1 8.8.8.8
wan0_dns1_x=
wan0_dns2_x=


[email protected]:/jffs/scripts# ./wanup
Checking if ./wanup is already running...
BusyBox v1.25.1 (2022-03-25 10:23:25 EDT) multi-call binary.

Usage: ping [OPTIONS] HOST

Send ICMP ECHO_REQUEST packets to network hosts

-4,-6 Force IP or IPv6 name resolution
-c CNT Send only CNT pings
-s SIZE Send SIZE data bytes in packets (default:56)
-t TTL Set TTL
-I IFACE/IP Use interface or IP address as source
-M hint Path MTU Discovery strategy [do|want|dont]
-W SEC Seconds to wait for the first response (default:10)
(after all -c CNT packets are sent)
-w SEC Seconds until ping exits (default:infinite)
(can exit earlier with -c CNT)
-q Quiet, only display output at start
and when finished
-p Pattern to use for payload
You can change those but whatever IP you pick for each WAN you will need to have a route made for it. DNS servers and gateway already are routed for you over each WAN interface. Also the variables to set are…
WAN0TARGET=
WAN1TARGET=
 

rlj2

Senior Member
You can change those but whatever IP you pick for each WAN you will need to have a route made for it. DNS servers and gateway already are routed for you over each WAN interface. Also the variables to set are…
WAN0TARGET=
WAN1TARGET=
Guess I dont understand, your pinging wan0_dns1_x= for the check, but mine is empty, for wan0 and wan1, so these need set outsite the script?
 
Last edited:

Ranger802004

Very Senior Member
Guess I dont understand, your pinging wan0_dns1_x= for the check, but mine is empty, for wan0 and wan1, so these need set outsite the script?
In the script there is a section for variables to change which you will want to do for your QoS Settings as well.

Look for :
Code:
WAN0TARGET="$(nvram get wan0_dns1_x)"
Change to:
Code:
WAN0TARGET="$(nvram get wan0_dns | awk '{print $1}')"
 

rlj2

Senior Member
In the script there is a section for variables to change which you will want to do for your QoS Settings as well.

Look for :
Code:
WAN0TARGET="$(nvram get wan0_dns1_x)"
Change to:
Code:
WAN0TARGET="$(nvram get wan0_dns | awk '{print $1}')"
Played with it some this mornign, once I made it check the right dns, seems to be working. Fyi, my secondary wan always comes up in Cold Standby. The script doesnt seem to make it go into to hot
standby. I just added service "restart_wan_if 1" to beginning, which makes it hot.
 

Ranger802004

Very Senior Member
Played with it some this mornign, once I made it check the right dns, seems to be working. Fyi, my secondary wan always comes up in Cold Standby. The script doesnt seem to make it go into to hot
standby. I just added service "restart_wan_if 1" to beginning, which makes it hot.
Interesting, I’ll look into that as a check and adding a function for next version.
 

rlj2

Senior Member
Interesting, I’ll look into that as a check and adding a function for next version.
We must have something different on our routers, I have a AX86u running latest merlin version. I just switched the wc from 5 to 1, and then it always thinks the script is running. I had it pop up a grep error also while running, but havent been able to mess with it since. Just giving you my issues, not complaining at all. ty
 

Ranger802004

Very Senior Member
We must have something different on our routers, I have a AX86u running latest merlin version. I just switched the wc from 5 to 1, and then it always thinks the script is running. I had it pop up a grep error also while running, but havent been able to mess with it since. Just giving you my issues, not complaining at all. ty
Yea it will do that if you try and run it manually in console unless you increase that number. What was the grep error you received? No worries, I figured other models would have various things come up differently than my environment.
 

rlj2

Senior Member
Yea it will do that if you try and run it manually in console unless you increase that number. What was the grep error you received? No worries, I figured other models would have various things come up differently than my environment.
 

rlj2

Senior Member
This is when it was switching after I killed my primary line. i fixed the wan-event issue.

##############

Checking if ./wanup is already running...
Switching to wan1
grep: option requires an argument -- 'e'
Usage: grep [OPTION]... PATTERNS [FILE]...
Try 'grep --help' for more information.

Done.

Done.

Done.

Done.
./wanup: line 310: /jffs/scripts/wan-event: not found
 

Ranger802004

Very Senior Member
This is when it was switching after I killed my primary line. i fixed the wan-event issue.

##############

Checking if ./wanup is already running...
Switching to wan1
grep: option requires an argument -- 'e'
Usage: grep [OPTION]... PATTERNS [FILE]...
Try 'grep --help' for more information.

Done.

Done.

Done.

Done.
./wanup: line 310: /jffs/scripts/wan-event: not found
Ah yes, if you don’t have a wan-event script made it will error out, I will make a check for that on next release, a little oversight.
 

rlj2

Senior Member
Ah yes, if you don’t have a wan-event script made it will error out, I will make a check for that on next release, a little oversight.
You think thats what the grep issue was also? Something I can add, but if your working on this. Something handy sending a email when failover kicks in would be nice, somewhere on this forum I wrote a uptime script
that would email, but you can also email your cellular provider and it will send you a text.
 

Ranger802004

Very Senior Member
You think thats what the grep issue was also? Something I can add, but if your working on this. Something handy sending a email when failover kicks in would be nice, somewhere on this forum I wrote a uptime script
that would email, but you can also email your cellular provider and it will send you a text.
I actually have my custom version emailing me, but I didn’t include that in my public version. The grep error is coming from trying to grep without a - parameter, did you add or edit any of the grep commands?
 

rlj2

Senior Member
I actually have my custom version emailing me, but I didn’t include that in my public version. The grep error is coming from trying to grep without a - parameter, did you add or edit any of the grep commands?
I did not change anything but the WAN0TARGET= , and added the
service "restart_wan_if 1", I will probably add a option to change qos or not to variable. But thats when Im bored.
If you already have the email version, mind sending it? Save me having to add it.
 

Ranger802004

Very Senior Member
I did not change anything but the WAN0TARGET= , and added the
service "restart_wan_if 1", I will probably add a option to change qos or not to variable. But thats when Im bored.
If you already have the email version, mind sending it? Save me having to add it.
Send me a copy of your modified script and let me take a look, yea when I get home I’ll send it over, it’s a separate script and my failover script just has a function that calls to send email whenever a switch happens.
 

rlj2

Senior Member
I did not change anything but the WAN0TARGET= , and added the
service "restart_wan_if 1", I will probably add a option to change qos or not to variable. But thats when Im bored.
If you already have the email version, mind sending it? Save me having to add it.
That happened when it switched to wan1, I bet I have another blank nvram setting that needs changed on Wan1. My script is literally exactly yours, I changed the WAN0Target to what you pasted here.
and just commented out wan-event.
 

Ranger802004

Very Senior Member
That happened when it switched to wan1, I bet I have another blank nvram setting that needs changed on Wan1. My script is literally exactly yours, I changed the WAN0Target to what you pasted here.
and just commented out wan-event.
Did you lowercase the variable? It has to match how it is called in the script. WAN0TARGET is how I wrote it.
 

rlj2

Senior Member
Did you lowercase the variable? It has to match how it is called in the script. WAN0TARGET is how I wrote it.
WAN0TARGET="$(nvram get wan0_dns | awk '{print $1}')"
WAN1TARGET="$(nvram get wan1_gateway)"
 

Sign Up For SNBForums Daily Digest

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