Mikrotik dual ISP setup
This is a guide on how to setup a failover ISP for your Mikrotik router. With this setup, the router should seamlessly transition from main ISP to the failover when the main ISP becomes unavailable. There should be no downtime for the user.
This article is an expansion over the official documentation, which is a bit lacking in detail.
Setup
Let's say we have two ISP connections:
- ISP1 - PPPoE connection on interface pppoe-out1
- ISP2 - ethernet connection to an LTE router
In this example, a separate bridge to the LTE router was created and a DHCP client assigned to it.
First, make sure both the pppoe client and the dhcp client don't setup default routes.
PPP -> pppoe-out1 -> Dial Out -> uncheck Add Default Route
IP -> DHCP Client -> (bridge name) -> set Add Default Route to no
For this setup to work, we need some external IP addresses that the router can ping with the gateway ping option.
Public DNS servers are good candidates, but check if they can be pinged first. Note that they are not actually used for DNS.
Let's pick the OpenDNS and Quad9 servers:
OpenDNS (A)
208.67.222.222
208.67.220.220
Quad9 (B)
9.9.9.9
9.9.9.10
We are going to create routes to these hosts via gateway1
(pppoe-out1 gateway 10.0.0.1) and gateway2
(failover router IP 10.21.12.1).
/ip route add dst-address=208.67.222.222 gateway=10.0.0.1 scope=10 comment="PPPOE-A"
/ip route add dst-address=9.9.9.9 gateway=10.0.0.1 scope=10 comment="PPPOE-B"
/ip route add dst-address=208.67.220.220 gateway=10.21.12.1 scope=10
/ip route add dst-address=9.9.9.10 gateway=10.21.12.1 scope=10
Note that we added two comments for the pppoe routes, which will come in handy later.
Virtual Hops
Next step is to add "virtual hops" to these routes. These are some random IP addresses that will be used as gateway for our routes. The point is that the router will recursively resolve routes until it reaches one ISP or the other, depending on their availability or distance metric that we will set.
Choose two random addresses for the virtual hops, making sure they don't conflict with anything in your local network:
- Virtual hop1: 10.1.1.1
- Virtual hop2: 10.2.2.2
Let's now add the routes:
/ip route add dst-address=10.1.1.1 gateway=208.67.222.222 scope=10 target-scope=10 check-gateway=ping
/ip route add dst-address=10.1.1.1 gateway=9.9.9.9 scope=10 target-scope=10 check-gateway=ping
/ip route add dst-address=10.2.2.2 gateway=208.67.220.220 scope=10 target-scope=10 check-gateway=ping
/ip route add dst-address=10.2.2.2 gateway=9.9.9.10 scope=10 target-scope=10 check-gateway=ping
The final step is to add default routes through the two virtual hops.
/ip route add distance=1 gateway=10.1.1.1
/ip route add distance=2 gateway=10.2.2.2
Now, make sure everything is OK:
Check /ip route
and see if the default routes (the routes to 0.0.0.0/0
) show something like:
recursive via 10.0.0.1 pppoe-out1
The default route with distance 1 should be active while the one with distance 2 should not be (inactive routes are shown in blue).
Try disabling one of the interfaces (pppoe-out1 or failover bridge) or better, unplug the network cable and see if the other route becomes active.
Quirks
In this example we used 10.0.0.1
as the pppoe gateway, but this is likely to be a dynamic value set by the PPPoE server. To use it in our setup, we need a script to update the routes when the pppoe gateway changes.
To do this, create a custom pppoe profile:
PPP -> Profiles -> Add
Then navigate to Scripts
and add the following code in the On Up
section:
:local newgw [/ip address get [find interface="pppoe-out1"] network];
/ip route set [find comment="PPPOE-A"] gateway=$newgw;
/ip route set [find comment="PPPOE-B"] gateway=$newgw;
In this script, we used the comments we set earlier to identify the two routes where we need to update the gateway.
The only remaining thing is to replace the default profile on the pppoe interface with the one we created:
PPP -> Interface -> pppoe-out1 -> Profile: myprofile
Email notifications
A nice-to-have would be to get notified when the primary ISP goes down and the failover kicks in. This can be achieved through scripting.
First, make sure the router can send emails.
/tool e-mail
If your getting a timeout error when trying to Send email, you may want to try to connect to the email server via telnet.
/system telnet 1.2.3.4 25
If connection doesn't work most likely you need to allow input to the router on port 25.
Next step would be to setup a schedule to run a script on a regular basis, checking if the primary ISP is active.
/system scheduler
:local metric;
:set metric [/ip route get [find dst-address=0.0.0.0/0 active=yes] distance];
:if ($metric = 2) do={ /tool e-mail send to="hi@mihai.fm" subject="Internet connection drop" body="Failover kicked in" };
The script uses the route distance we set earlier. If the default route (0.0.0.0/0) has a distance of 2, it means that the
failover ISP has kicked in, so we need to send an email.
The scheduler script needs the following permissions: read, write, policy, test.
I set mine to run at a one hour interval.
Comments