Автоматическое переключение каналов на MikroTik RouterOS
Встроенная в MikroTik RouterOS функция
обеспечения отказоустойчивости доступа в Интернет(имеется ввиду check-gateway=ping),
имеет огромный недостаток: она проверяет доступность шлюза провайдера,
а не доступность сети Интернет через этого провайдера.
Подобное решение для Linux я уже описывал, и это можно
сказать его «порт» на RouterOS
Имеем 3 канала в Интернет и один в локальную сеть(тут называется DMZ):
/ip address
add address=172.16.16.2/24 broadcast=172.16.16.255 comment=DMZ disabled=no
\
interface=ether1-dmz network=172.16.16.0
add address=80.X.255.130/26 broadcast=80.X.255.191 comment=RialKom
\
disabled=no interface=ether3-rialkom network=80.X.255.128
add address=212.152.X.55/26 broadcast=212.152.X.63 comment=Inet
disabled=\
no interface=ether5-inet network=212.152.X.0
add address=62.X.7.242/29 broadcast=62.X.7.247 comment=Beeline \
disabled=no interface=ether4-beeline network=62.X.7.240 |
Основные маршруты, которые мы и будем переключать:
/ip route
add comment=GW_1 disabled=no distance=1 dst-address=0.0.0.0/0 gateway=\
80.X.255.129 scope=30 target-scope=10
add comment=GW_2 disabled=no distance=2 dst-address=0.0.0.0/0 gateway=\
62.X.7.241 scope=30 target-scope=10
add comment=GW_3 disabled=no distance=3 dst-address=0.0.0.0/0 gateway=\
212.152.X.1 scope=30 target-scope=10 |
Клиенты должны маскарадиться:
/ip firewall nat
add action=masquerade chain=srcnat comment="" disabled=no
src-address=172.16.16.0/24 |
Сам скрипт, называется CheckINET:
###################################################################
#Name: CheckINET
#Version: 1.0.1
#Created: Andrey Orlov
#Email: tangarus(a)gmail.com
#Web: http://www.tangarus.ru/
#Date: 10.2009
#Description:Автоматическое переключение каналов на RouterOS
####################################################################
#set variables
:local PingCount 3
# www.ya.ru
:local IPToPing 77.88.21.8
:local SrcAddrA 80.X.255.130
:local SrcAddrB 62.X.7.242
:local SrcAddrC 212.152.X.55
#ping gateways with src
:local pingresultA [/ping $IPToPing count=$PingCount src-address=$SrcAddrA]
:local pingresultB [/ping $IPToPing count=$PingCount src-address=$SrcAddrB]
#if link_A is DOWN and link_B is UP then:
:if (($pingresultA=0) && ($pingresultB=$PingCount)) do={
:if ((([/ip route get [find comment="GW_2"] distance]=1)&&([/ip
route get [find comment="GW_1"] distance]=2)&&([/ip
route get [find comment="GW_3"] distance]=3))=false) do={
:log warning "set routes to B"
/ip route set [find comment="GW_2"] distance=1
/ip route set [find comment="GW_1"] distance=2
/ip route set [find comment="GW_3"] distance=3
}
}
#if link_A is UP and link_B is DOWN then:
:if (($pingresultA=$PingCount) && ($pingresultB=0)) do={
:if ((([/ip route get [find comment="GW_2"] distance]=2)&&([/ip
route get [find comment="GW_1"] distance]=1)&&([/ip
route get [find comment="GW_3"] distance]=3))=false) do={
:log warning "Set routes to A"
/ip route set [find comment="GW_1"] distance=1
/ip route set [find comment="GW_2"] distance=2
/ip route set [find comment="GW_3"] distance=3
}
}
#if link_A is DOWN and link_B is DOWN:
:if (($pingresultA=0) && ($pingresultB=0)) do={
:if ((([/ip route get [find comment="GW_2"] distance]=3)&&([/ip
route get [find comment="GW_1"] distance]=2)&&([/ip
route get [find comment="GW_3"] distance]=1))=false) do={
:log warning "Set routes to C"
/ip route set [find comment="GW_3"] distance=1
/ip route set [find comment="GW_1"] distance=2
/ip route set [find comment="GW_2"] distance=3
}
}
# Link A or Link B both are UP:
:if (($pingresultA=$PingCount) && ($pingresultB=$PingCount))
do={
:if ((([/ip route get [find comment="GW_2"] distance]=2)&&([/ip
route get [find comment="GW_1"] distance]=1)&&([/ip
route get [find comment="GW_3"] distance]=3))=false) do={
:log warning "Set routes to A"
/ip route set [find comment="GW_1"] distance=1
/ip route set [find comment="GW_2"] distance=2
/ip route set [find comment="GW_3"] distance=3
}
} |
выполняем его раз в 30 секунд:
/system scheduler
add comment="" disabled=no interval=30s name=CheckINET
on-event="/system script run CheckINET" policy=\
reboot,read,write,policy,test,password,sniff,sensitive start-date=jan/01/1970
start-time=00:00:00 |
Казалось-бы всё, но есть один подводный камень: сейчас
выполняя пинг /ping www.ya.ru src-address=212.152.X.55, RouterOS не
будет обращать внимания на параметр 212.152.X.55 если этот шлюз недоступен.
Т.е. если он доступен то пакеты будут идти чрез него, но если нет, то
через текущий default gw.
Чтобы избежать этого, необходимо помечать соединения на входе интерфейса
соответствующей routing mark.
Параллельно это решит проблему «отвечать на тот интерфейс, на который
пришел запрос»: сейчас пингуя интерфейс №2 ответы пойдут через интерфейс
которому принадлежит default gw, и ответа мы не получим.
Добавляем маршруты в именованные таблицы маршрутизации:
add comment="" disabled=no distance=1
dst-address=0.0.0.0/0 gateway=\
80.X.255.129 routing-mark=rialkom scope=30 target-scope=10
add comment="" disabled=no distance=1 dst-address=0.0.0.0/0
gateway=\
62.X.7.241 routing-mark=beeline scope=30 target-scope=10
add comment="" disabled=no distance=1 dst-address=0.0.0.0/0
gateway=\
212.152.X.1 routing-mark=inet scope=30 target-scope=10 |
Правила маршрутазиции:
/ip route rule
add action=lookup comment="" disabled=no src-address=212.152.X.55/32
\
table=inet
add action=lookup comment="" disabled=no src-address=62.X.7.242/32
table=\
beeline
add action=lookup comment="" disabled=no src-address=80.X.255.130/32
\
table=rialkom |
эти правила нужны, чтобы из внутренней сети были всегда (в не зависимости
от текущего рабочего канала) доступны сети провайдеров, я использую
для мониторинга:
/ip route rule
add action=lookup comment="" disabled=no dst-address=62.X.7.240/29
table=\
beeline
add action=lookup comment="" disabled=no dst-address=80.X.255.128/26
\
table=rialkom
add action=lookup comment="" disabled=no dst-address=212.152.X.0/26
table=\
inet |
Обращаю внимание: routing-mark которые видны через
WinBOX в MANGLE, это таблицы маршрутизации из /ip route (routing-table)
и routing-mark'и, а routing-table там напрямую использовать нельзя!
Т.е. там по непонятным причинам отображаються как routing-mark, так
и routing-table.
(UPD: А вот на другом роутере работает и так и так... Хм...)
Нужно их сопоставить:
/ip route rule
add action=lookup comment="" disabled=no routing-mark=rialkom
table=rialkom
add action=lookup comment="" disabled=no routing-mark=beeline
table=beeline
add action=lookup comment="" disabled=no routing-mark=inet
table=inet |
Помечаем белый краской спинки пакетиков:
/ip firewall mangle
add action=mark-routing chain=output comment="Local answer
to correct if" disabled=no new-routing-mark=beeline \
passthrough=yes src-address=62.X.7.242
add action=mark-routing chain=output comment="Local answer
to correct if" disabled=no new-routing-mark=inet passthrough=\
yes src-address=212.152.X.55
add action=mark-routing chain=output comment="Local answer
to correct if" disabled=no new-routing-mark=rialkom \
passthrough=yes src-address=80.X.255.130 |
Всё!
Автор:TangaRUS
|