Dual WAN fail over settings with MikroTik

Basic idea is that we always use our primary ISP, but when it’s offline automatically switch to the secondary / backup ISP. No load balance, only fail over.

Naming method:
WAN1, WAN2 – phisical interfaces on the router for the internet connections
ISP1, ISP2 – Name of the ISP, eg. Telekom, UPC, etc..
192.168.X.254 – routers’ addresses X=1 for WAN1, X=2 for WAN2

First we need to check both connections are up. For this method I’ll use ping OpenDNS server addresses; via ISP1 208.67.222.222 and via ISP2 208.220.220. Create 2 static routes for the servers on different paths:

/ip route add dst-address="208.67.222.222" gateway="192.168.1.254" comment="Net check via ISP1" 
/ip route add dst-address="208.67.220.220" gateway="192.168.2.254" comment="Net check via ISP2"

Now we need create 2 firewall rules on the forward chain, where I drop the connections where it should not be on. It’s necessary because routing options not enough, it will use default route if static fails, and can you get
false positive results from the pinging.

/ip firewall filer add chain=forward action=drop dst-address=" 
208.67.222.222" out-interface="WAN2" comment="Reachable only via ISP1"
/ip firewall filer add chain=forward action=drop dst-address="
208.67.220.220" out-interface="WAN1" comment="Reachable only via ISP2"

Now I’ll make a script called “ISP_state_check”. It will monitor which ISP is up and which is not. If the primary is online there is noting to do, but when it’s not and the secondary is online, then switch to it.

:local message;
:set message "Net check state: ";

:if ([/ping 208.67.222.222 count=5 interface=WAN1]=0) do={
:set message ($message ."ISP1 is DOWN and ");
} else={
:set message ($message ."ISP1 is UP and ");
}

:if ([/ping 208.67.220.220 count=5 interface=WAN2]=0) do={
:set message ($message ."ISP2 is DOWN");
} else={
:set message ($message ."ISP2 is UP");
}
:log info ($message);

:local defGW;
:if ([/ip route get [/ip route find where dst-address="0.0.0.0/0"] gateway]="192.168.1.254") do={
:log info ("Default GW: ISP1");
:set defGW "WAN1";
}
:if ([/ip route get [/ip route find where dst-address="0.0.0.0/0"] gateway]="192.168.2.254") do={
:log info ("Default GW: ISP2");
:set defGW "WAN2";
}

:log info ("Checking via default gateway: " . $defGW . " " . [/ip route get [/ip route find where dst-address="0.0.0.0/0"] gateway]);
:if ([/ping 8.8.8.8 count=3 interface=$defGW]=0) do={
:log info ("Cannot ping Google, switching ISP");
/system script run ISP_switcher
} else={
:log info ("Everything seems fine, nothing to do here..");
}

Then we can create the “ISP_switcher” script, which will check the actual active gateway, and switch it to the other

:local i;
:local defGateway;

:set i [/ip route find where dst-address="0.0.0.0/0"]
:set defGateway [/ip route get $i gateway];

:log info ($defGateway);
:if ($defGateway="192.168.2.254") do={
:log info ("Active ISP: ISP2, checking ping via ISP1");
:if ([/ping 208.67.222.222 count=5 interface=WAN1]=0) do={
:log info ("ISP1 is DOWN, cannot switch default gateway");
} else={
:log info ("ISP1 is UP, switching default gateway");
/ip route set [/ip route find dst-address=0.0.0.0/0] gateway=192.168.1.254
/interface disable WAN2
:delay 8s
/interface enable WAN2
}
}

:if ($defGateway="192.168.1.254") do={
:log info ("Active ISP: ISP1, checking ping via ISP2");
:if ([/ping 208.67.220.220 count=5 interface=WAN2]=0) do={
:log info ("ISP2 is DOWN, cannot switch default gateway");
} else={
:log info ("ISP2 is UP, switching default gateway");
/tool e-mail send to=your@mail.com subject="ISP1 is down" body="Your main ISP went away, ISP switched to backup. Happy troubleshooting"
/ip route set [/ip route find dst-address=0.0.0.0/0] gateway=192.168.2.254
/interface disable WAN1
:delay 8s
/interface enable WAN1
}
}

Final step is making a scheduled task with a 30 sec interval, and run the “/system script run ISP_state_check”.