Tmobile backup internet failover and Mikrotik
Internet is all but a necessity today. For a home office it is even more important. I recently set up a TMobile Backup Internet gateway and enabled automatic failover with my Mikrotik home network. The mechanism below allows for automatic failover for all devices on the network to use the backup internet, though there is a approximate minute gap when the ISP goes down.
I wanted the network to automatically fail over. TMobile has a handy Home Internet Backup plan, only $20/mo with autopay, that gets you 100hr/mo + 2x100 hour passes per year.
Setup
- LAN1 on the TMobile (TMO) device is connected directly to my ISP’s router (hence ‘ISP’). This is the TMO ‘probe port’ it uses to detect if the ISP is alive. The port does not otherwise pass traffic.
- LAN2 on the TMO device is connected to my Mikrotik router (aka ‘router’). Note that none of my router ports are switched/bridged, they are all routed.
- The TMO runs DHCP in the 192.168.12.0/24 range. The TMO gateway acts as 192.168.12.1 and serve a dead-simple status UI. None of this appears configurable.
- The TMO is in ‘automatic failover’ mode.
- The Mikrotik router has a port that connects to my 24 port switch.
- The network has a DHCP-supplied default-route to ISP with a distance of 130. The distance is configured in the DHCP Client under ‘default route distance’.
- I created a disabled static default route to the TMO gateway at 192.168.12.1, with comment “5GBackupRoute”, with distance 1.
- I configured the Mikrotik to masquerade connections that exit via the port to which TMO is connected.
- I configured static routes for the two ISP DNS servers destined for ISP.
I then Claude’d a script that runs every 30s and attempts DNS resolution via the ISP DNS servers. If both fail it enables the 5GBackupRoute which causes traffic to be routed out to TMO instead of ISP. The static routes are there to avoid Mikrotik hitting ISP DNS servers via TMO and flap the connection. When ISP fails the DNS resolution fails, the TMO 0/0 route is activated, it has a lower distance than ISP, so traffic is routed to TMO. With masquerading the TMO only sees one device, as it is not aware of any advanced routing options.
Caveats
- The TMO connection is always up, but not ‘enabled’. Up/disabled = 600kbit/s throughput, essentially a snails pace. Up/enabled = 500Mbit down / 25Mbit up depending on time-of-day and usage.
- It takes a minute for TMO to detect the ISP has failed and go to Enabled state. Since the connection is always up one can’t base any logic on whether packets/probes work.
Note
TMO probes for liveness from the ISP. While the documentation does not define how it determins liveness, it appears that it DNS resolves www.google.com from the ISP DHCP-supplied DNS server, reverse-resolves it, then pings it. This seems an unreliable test since nothing guarantees www.google.com will continue to support ping.
Script
The script is loaded with /import file-name=dns-failover.rsc. Be sure to update dnsServers to match your ISP servers.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# DNS-based failover to 5G backup route
# Paste into a RouterOS terminal (v6.x or v7.x).
/system script
add name=dns-failover policy=read,write,test source={
:local testHost "www.google.com"
:local dnsServers {205.171.2.65; 205.171.2.64}
:local routeComment "5GBackupRoute"
# Try each DNS server; success on any one counts as "up"
:local dnsOk false
:foreach srv in=$dnsServers do={
:if (!$dnsOk) do={
:do {
:resolve $testHost server=$srv
:set dnsOk true
} on-error={
:log warning ("dns-failover: lookup via " . $srv . " failed")
}
}
}
# Locate the backup route
:local routeIds [/ip route find comment=$routeComment]
:if ([:len $routeIds] = 0) do={
:log error ("dns-failover: no route with comment " . $routeComment)
:error "route not found"
}
:local isDisabled [/ip route get [:pick $routeIds 0] disabled]
# Only change state (and log) when something actually changes
:if ($dnsOk) do={
:if (!$isDisabled) do={
/ip route set $routeIds disabled=yes
:log info "dns-failover: DNS OK - 5G backup route disabled"
}
} else={
:if ($isDisabled) do={
/ip route set $routeIds disabled=no
:log warning "dns-failover: both DNS servers failed - 5G backup route enabled"
}
}
}
/system scheduler
add name=dns-failover interval=30s on-event="/system script run dns-failover" \
policy=read,write,test start-time=startup