programación

Mikrotik script failover con 2 ISPs.

por Lógico (@LogicoDev)
5 de Octubre, 2018 ⏱ 11:00 PM

Si tenes un router Mikrotik y andas buscando una manera de asegurarte la conectividad a internet, entonces esta artículo es para vos.

Imágen de portada

A veces tenemos en nuestro trabajo la necesidad de tener servicio de internet de manera constante. Si bien los ISPs aseguran una tasa alta de uptime, en la practica, sabemos que muchas cosas pueden salir mal y es normal que se interrumpa el servicio en cualquier momento. Por eso, un buen curso de acción es contar con un segundo proveedor de servicios que cubra al otro en caso de cortes. Y acá nos encontramos con el problema de como implementar esto de manera cómoda, porque tener una persona para que cambie el cable cada vez que se cae el ISP no es nada práctico. Entra Mikrotik al rescate. Estos routers administrables son económicos, confiables y con un poco de magia de la programación podemos automatizar esta tarea.

El script que programamos está basado en el failover script de la wiki de Mikrotik, pero logramos simplificarlo para que sea de facil implementación. La lógica es la siguiente:

Imagen

Implementación

Para implementar el script hay que seguir los siguientes pasos:

  • Ir a System -> Scheduler -> Add New.
  • Darle el nombre FailOver o el nombre que quieras.
  • Start Time cambiar a startup
  • Interval a 00:00:05 (se ejecuta cada 5 segundos) o en función de la carga que tenga el router amentar el tiempo de chequeo.
  • En el cuadro de texto pegar el código.
  • Editar los valores de las variables al caso particular de la red.
  • Una vez realizados los cambios, tildar la opción "Enable" y luego click en "OK".
# Mikrotik Failover script, ver 1.0.3
# Auth: Lógico Software (@logico-dev)
# Date: 2018-10-06
# Based on: https://wiki.mikrotik.com/wiki/Failover_Scripting by Tomas Kirnak
# Released under MIT License (MIT)
# Copyright (c) 2018 Lógico Software <hi@logico.com.ar>

# Please fill the WAN interface names
:local InterfaceISP1 ETH_ISP1
:local InterfaceISP2 ETH_ISP2

# Please fill the gateway IPs (or interface names in case of PPP)
:local GatewayISP1 192.168.1.1
:local GatewayISP2 172.16.1.1

# Please fill the ping check host - currently: google dns
:local PingTarget 8.8.8.8

# Please fill how many ping failures are allowed before fail-over happends
:local FailTreshold 3

# Declare the global variables
:global PingFailCountISP1
:global LastPingOk

# This inicializes the PingFailCount variables, in case this is the 1st time the script has ran
:if ([:typeof $PingFailCountISP1] = "nothing") do={:set PingFailCountISP1 0}
:if ([:typeof $LastPingOk] = "nothing") do={:set LastPingOk 1}

# This variable will be used to keep results of individual ping attempts
:local PingResult



# Check ISP1
:set PingResult [ping $PingTarget count=1 interface=$InterfaceISP1]
:put $PingResult


:if ($PingResult = 0) do={
    :if ($LastPingOk = 1) do={        
        :set PingFailCountISP1 ($PingFailCountISP1 + 1)

        :if ($PingFailCountISP1 > 1) do={
		:if ($PingFailCountISP1 > $FailTreshold) do={

			:foreach i in=[/ip route find gateway=$GatewayISP1 && static] do=\
				{/ip route set $i distance=2}
                        :foreach i in=[/ip route find gateway=$GatewayISP2 && static] do=\
				{/ip route set $i distance=1}
			:log warning "ISP1 Down - Changing to ISP2."
                        :set LastPingOk 0

		}
	}
    } else={
        :set PingFailCountISP1 4
    }

	
} else={
    :if ($LastPingOk = 0) do={
        :set PingFailCountISP1 ($PingFailCountISP1 - 1)
        :if ($PingFailCountISP1 = 1) do={
			:foreach i in=[/ip route find gateway=$GatewayISP1 && static] do=\
				{/ip route set $i distance=1}
                        :foreach i in=[/ip route find gateway=$GatewayISP2 && static] do=\
				{/ip route set $i distance=2}
			:log warning "ISP1 is back"
                        :set PingFailCountISP1 ($PingFailCountISP1 - 1)
                        :set LastPingOk 1
	}
    } else={
        :set PingFailCountISP1 0
    }
}

Si tenes alguna duda, dejala en la caja de comentarios y esperamos que este script les sea de utilidad.

Portada

unsplash-logoThomas Jensen