среда, 16 апреля 2014 г.

Mikrotik — автоматическое переключение на резервный канал

 Mikrotik есть встроенная функция обеспечения  отказоустойчивого доступа (check-gateway=ping), но она имеет недостаток: она проверяет доступность шлюза провайдера.  Поэтому с помощью данной функции невозможно определить работоспособность интернета через конкретного провайдера. Для более правильного определения сбоев необходимо писать свои скрипты.
 Итак имеем 2 канала от разных провайдеров:

1. Канал Ehernet включается в первый порт роутера, получает IP по DHCP и поднимает pptp соединение, названное inet1. Это будет основное соединение.
2. Канал ADSL  проходит через DSL модем в режиме моста и втыкается во второй порт роутера, поверх поднимается pppoe соединение, названное inet2. Это будет резервное соединение.
3. Порты 3-5 роутера используются для подключения устройств локальное сети.
Настройка роутера.
При настройке ppp подключений нужно отключить добавление маршрутов по умолчанию, а затем создать статические маршруты разными метриками и подходящими комментариями:
/ip route
add comment=MainGW disabled=no distance=1 dst-address=0.0.0.0/0 gateway=inet1 scope=30 target-scope=10
add comment=RsrvGW disabled=no distance=2 dst-address=0.0.0.0/0 gateway=inet2 scope=30 target-scope=10

Теперь чтобы переключать каналы достаточно изменять параметр distance. Трафик пойдёт через канал с меньшим значением этого параметра.
Скрипты.
Скрипт называется set_global_parameters
#Main interface name
:global MainIf inet1
#Reserve interface name
:global RsrvIf inet2
#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 запускается каждую минуту.

Источник: здесь

Комментариев нет:

Отправка комментария