В недавнем прошлом в связи с переходом с ADSL на Ethernet представилась отличная возможность попробовать оборудование от Mikrotik. В связи с чем был куплен роутер RB750GL. Железка оказалась превосходной как внешне, так и с точки зрения функционала и надёжности.
В итоге у меня осталось оба канала и было решено настроить резервирование с автоматическим переключением. Стандартные средства переключения шлюзов не покрывают всё многообразие сбоев, поэтому нужно писать свои скрипты.
Конфигурация сети
1. Канал Ehernet от NLink втыкается в первый порт роутера, получает IP по DHCP и поднимает pptp соединение, названное nlink. Это будет основное соединение.
2. Канал ADSL от провайдера Домолинк проходит через DLink-2500 в режиме моста и втыкается во второй порт роутера, поверх поднимается pppoe соединение, названное domolink. Это будет резервное соединение.
3. Порты 3-5 роутера используются для подключения устройств локальное сети.
Настройки роутера
Настройка подключений и маскарадинга для компьютеров локальное сети является тривиальной и детально описана в официальной вики.
При настройке ppp подключений нужно отключить добавление маршрутов по умолчанию, а затем создать статические маршруты разными метриками и подходящими комментариями:
/ip route
add comment=MainGW disabled=no distance=1 dst-address=0.0.0.0/0 gateway=nlink scope=30 target-scope=10
add comment=RsrvGW disabled=no distance=2 dst-address=0.0.0.0/0 gateway=domolink scope=30 target-scope=10
Теперь чтобы переключать каналы достаточно изменять параметр distance. Трафик пойдёт через канал с меньшим значением этого параметра.
Скрипты
Установка глобальных параметров при запуске роутера
Скрипт называется set_global_parameters
#Main interface name
:global MainIf nlink
#Reserve interface name
:global RsrvIf domolink
#Main interface ip address
:global MainIfAddress ""
#Reserve interface ip address
:global RsrvIfAddress ""
Определение IP-адресов интерфейсов
Определение IP-адреса основного интерфейса
Скрипт называется define_main_if_ip
:global MainIf
:global MainIfAddress ""
:set MainIfAddress [/ip address get [find interface=$MainIf] address]
Данный скрипт определяет IP-адрес основного интерфейса для доступа в интернет. Если этот интерфейс отсутствует, то скрипт будет завершаться с ошибкой, а в переменной MainIfAddress будет пустая строка.
Определение IP-адреса резервного интерфейса
Скрипт называется define_reserved_if_ip
:global RsrvIf
:global RsrvIfAddress ""
:set RsrvIfAddress [/ip address get [find interface=$RsrvIf] address]
Определение этих адресов вынесено в отдельные скрипты, т.к. эти значения я использую ещё в ряде скриптов на роутере (например, обновление записей в DynDNS), а пользовательские функции тут создавать нельзя. Следует заметить, что напрямую команды определения адресов нельзя использовать в других скриптах, т.к. в случае проблем с интерфейсом они генерируют ошибку и приводят к завершению скрипта.
Переключение каналов
Скрипт называется connection_check
:global MainIf
:global RsrvIf
:global MainIfAddress
:global RsrvIfAddress
:local PingCount 3
#www.ru
:local PingTarget1 194.87.0.50
#ya.ru
:local PingTarget2 87.250.250.203
#google dns
:local PingTarget3 8.8.8.8
#Check main internet connection
:local MainIfInetOk false;
if ($MainIfAddress="") do={delay 5}
if ($MainIfAddress!="") do={
:local PingResult1 [/ping $PingTarget1 count=$PingCount interface=$MainIf]
:local PingResult2 [/ping $PingTarget2 count=$PingCount interface=$MainIf]
:local PingResult3 [/ping $PingTarget3 count=$PingCount interface=$MainIf]
:set MainIfInetOk (($PingResult1 + $PingResult2 + $PingResult3) >= (2 * $PingCount))
}
#Check reserved internet connection
:local RsrvIfInetOk false;
if ($RsrvIfAddress="") do={delay 5}
if ($RsrvIfAddress!="") do={
:local PingResult1 [/ping $PingTarget1 count=$PingCount interface=$RsrvIf]
:local PingResult2 [/ping $PingTarget2 count=$PingCount interface=$RsrvIf]
:local PingResult3 [/ping $PingTarget3 count=$PingCount interface=$RsrvIf]
:set RsrvIfInetOk (($PingResult1 + $PingResult2 + $PingResult3) >= (2 * $PingCount))
}
:put "MainIfInetOk=$MainIfInetOk"
:put "RsrvIfInetOk=$RsrvIfInetOk"
if (!$MainIfInetOk) do={
/log error "Main internet connection error"
}
if (!$RsrvIfInetOk) do={
/log error "Reserve internet connection error"
}
:local MainGWDistance [/ip route get [find comment="MainGW"] distance]
:local RsrvGWDistance [/ip route get [find comment="RsrvGW"] distance]
:put "MainGWDistance=$MainGWDistance"
:put "RsrvGWDistance=$RsrvGWDistance"
#SetUp gateways
if ($MainIfInetOk && ($MainGWDistance >= $RsrvGWDistance)) do={
/ip route set [find comment="MainGW"] distance=1
/ip route set [find comment="RsrvGW"] distance=2
/log info "Switch to main internet connection"
}
if (!$MainIfInetOk && $RsrvIfInetOk && ($MainGWDistance <= $RsrvGWDistance)) do={
/ip route set [find comment="MainGW"] distance=2
/ip route set [find comment="RsrvGW"] distance=1
/log warning "Switch to reserve internet connection"
}
Обратите внимание на пинг через конкретный интерфейс, а так же на критерий признания канала неисправным. Я пингую три разных узла и считаю, что интернет на данном интерфейсе не работает, если приходит меньше 2/3 ответов.
Планировщик
1. Скрипт set_global_parameters запускается один раз при запуске роутера.
2. Скрипты определения IP-адресов запускаются каждые 27 секунд. Такое значение выбрано чтобы минимизировать количество одновременных запусков с основным скриптом.
3. Скрипт connection_check запускается каждую минуту.
Выводы
Полученное решение при минимуме затрат существенно повысило надёжность моей домашней сети и успешно справляется с самыми изощрёнными сбоями местных провайдеров, при этом оно в достаточной степени защищено от сбоев внешних узлов сети.






























Furukawa
Grandway
V-Solution
Ubiquiti Networks
D-Link
Mikrotik
TP-Link
Edge-core
BDCOM
Jirous
Ok-net
Cambium Networks
Tenda
ZTE
Huawei
Ripley
Fujikura
DVP
Jilong
Одескабель
Netis
FiberField
Totolink
Grandstream
Yokogawa
Mimosa
OpenVox
Hikvision
Keenetic
Ютекс
Signal Fire
Utepo
Dahua
ONV
Prolum
ATcom
Ritar
Zyxel
Ruijie
APC
Fibaro
Merlion
Mercusys
MULTITEST
Reolink
ЗЗКМ
GEAR
ATIS
CSV
Full Energy
Авторизуйтесь, чтобы добавить отзыв