Stabilny Internet jest coraz ważniejszy, zwłaszcza w czasie COVID19, kiedy znaczna cześć społeczeństwa musi pracować zdalnie. Jednam z działań zapewniającym dostęp do Internetu jest zakup łącza u drugiego operatora, wiele osób decyduje się wybrać tutaj dostęp w postaci łącza LTE.
Pomysłów jak obsługiwać drugie łącze, które jest z zasady ma być tylko zapasowe było już wiele. Niestety, żadne rozwiązanie nie spełniło moich oczekiwać, choć wszystkie „działały”.
W szukaniu inspiracji trafiłem na artykuł opublikowany na łamach Server Management autorstwa Timo Puistaja z 2017 roku. Opisany sposób wykrywania łącza poprzez wydłużanie i manipulacje routingiem okazał się dosyć sprawny, jednak nie potrafił wykrywać awarii łącza kiedy występują utraty pakietów lub drastyczny wzrost czasu przesyłania pakietów przez główne łącze. Postawiłem rozbudować ten pomysł o wszystkie moje potrzeby.
Zasada działania opiera się na wykorzystaniu działania narzędzia Netwatch zaimplementowanego w MikroTik RouterOS ze wsparciem skryptów oraz dodatkowej weryfikacji poprzez wydłużenie trasy routingu i sprawdzanie dostępności bramy domyślnej.
/system script
add dont-require-permissions=no name=NetWatch-check owner=admin policy=\
reboot,read,write,policy,test source="#Tutaj mozesz zmienic wartosc\r\
\n# ilosc czasu w minutach jak dlugo lacze BACKUP bedzie preferowane\r\
\n# zanim sprawdzimy czy lacze glowne dziala prawidlowo\r\
\n#\r\
\n:global nwwait 15;\r\
\n# pozostaw bez zmian\r\
\n:global nwgw2;\r\
\n:tonum nwgw2;\r\
\n:local nwstatus;\r\
\n:local nwgwstatus;\r\
\nset nwgwstatus ([/tool netwatch get value-name=status [find comment=\
\"NetWatch\"]]);\r\
\nset nwstatus ([/ip route get value-name=distance number=[/ip route f\
ind comment=\"BACKUP\"]]);\r\
\n:if (\$nwstatus = \"6\") do={\r\
\nset nwgw2 (nwgw2 + 1)\r\
\n}\r\
\n:if ((\$nwgw2 > \$nwwait) and (\$nwgwstatus = \"up\")) do={ :log err\
or \"Master GW: OK\"\r\
\n/ip route set [find comment=\"BACKUP\"] distance=66;\r\
\nset nwgw2 (0)\r\
\n}\r\
\n"
add dont-require-permissions=no name=NetWatch owner=admin policy=\
reboot,read,write,test source="/log error \"Master GW: PROBLEM\"\r\
\n/ip route set [find comment=\"BACKUP\"] distance=6\r\
\n\r\
\n"
add dont-require-permissions=no name=NetWatch-init owner=admin policy=\
ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
source="#ilosc sprawdzen zanim lacze sie przelaczy\r\
\n:global nwwait 20;\r\
\n"
NetWatch - skrypt uruchamiany w przypadku awarii głównego łącza
NetWatch-check - skrypt uruchamiany czasowo weryfikujący przełączanie się z powrotem na łącze główne, w tym skrypcie możemy zdefiniować jak długo łącze BACKUP od czasu przełączenia pozostanie łączem wiodącym zanim sprawdzimy czy łącze główne działa już prawidłowo. W domyślnej sytuacji jest to 15 minut.
Kolejnym krokiem jest zdefiniowanie czasowego uruchamiania skryptów.
/system scheduler
add interval=1m name=NetWatch on-event=\
"/system script run NetWatch-check\r\
\n" policy=\
ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon \
start-date=apr/11/2020 start-time=17:31:44
Czas skonfigurować narzędzie Netwatch Mikrotika. w miejsce A.B.C.D należy podać adres domyślny bramy głównego łącza. Wartość timeout możemy określać jak czułe będzie wykrywanie awarii łącza głównego.
/tool netwatch
add comment=NetWatch down-script="/system script run NetWatch\r\
\n" host=A.B.C.D interval=5s timeout=100ms
Na koniec należy skonfigurować routing, wykorzystujemy tutaj sztuczkę z wydłużoną trasą routingu i sprawdzaniem dostępności bramy domyślnej. W miejsce A.B.C.D należy podać adres domyślny bramy głównego łącza, a w miejsce E.F.G.H należy podać adres domyślny bramy łącze zapasowego BACKUP.
/ip route
add comment=MASTER distance=10 gateway=10.255.66.1
add comment=BACKUP distance=66 gateway=10.255.67.1
add check-gateway=ping distance=1 dst-address=10.255.66.1/32 gateway=\
208.67.220.220 scope=10
add check-gateway=ping distance=1 dst-address=10.255.66.1/32 gateway=\
8.8.8.8 scope=10
add check-gateway=ping distance=1 dst-address=10.255.67.1/32 gateway=\
208.67.222.222 scope=10
add check-gateway=ping distance=1 dst-address=10.255.67.1/32 gateway=\
8.8.4.4 scope=10
add distance=1 dst-address=8.8.4.4/32 gateway=E.F.G.H scope=10
add distance=1 dst-address=8.8.8.8/32 gateway=A.B.C.D scope=10
add distance=1 dst-address=208.67.220.220/32 gateway=A.B.C.D scope=10
add distance=1 dst-address=208.67.222.222/32 gateway=E.F.G.H scope=10
Wykorzystujemy popularne adres ip usług dns Google (8.8.8.8, 8.8.4.4) i OpenDNS (208.67.220.220, 208.67.222.222), które sprawdzamy czy są osiągalne przez łącze danego operatora. Jeśli są dostępne to uaktywnia się brama domyślna dla danego łącza.
W powyższym rozwiązaniu użyliśmy podwójnej weryfikacji poprawnego działania łącza internetowego, raz poprzez sprawdzanie bramy domyślnej głównego łącza oraz dodatkowo sprawdzania dostępności hostów "daleko w internecie" osiąganych z konkretnych łączy.
Rozwiązanie to ma pewne ograniczenie, w przypadku kiedy jeden z operatorów przy renegocjacji połączenia zmienia parametr bramy domyślnej nie jesteśmy w stanie tego skonfigurować bezpośrednio.
W takim przypadku należy użyć osobny router dla tego połączenia jak w schematach poniżej i jego wskazać jako bramę połączenia.
Jestem przekonany, że rozwiązanie można poprawić i dalej rozbudować, skrypty które przygotowałem można inaczej napisać przy utrzymaniu głównej zasady działania rozwiązania.
W ramach dalszej dyskusji w tym temacie zapraszamy na nasze FORUM, gdzie można podzielić się z całą wspólnotą swoją konfiguracją oraz uwagami w tym temacie.
Autor:
Wojciech Repiński