К основному контенту

Автоматическое переключение каналов на 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, и ответа мы не получим.
Добавляем маршруты в именованные таблицы маршрутизации:
/ip route
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 !

Комментарии

Популярные сообщения из этого блога

Автообзвон на Asterisk (FreePBX)

Syntax of call files Specify where and how to call Channel : <channel>: Channel to use for the call. CallerID : «name» <number> Caller ID, Please note: It may not work if you do not respect the format: CallerID: «Some Name» <1234> MaxRetries : <number> Number of retries before failing (not including the initial attempt, e.g. 0 = total of 1 attempt to make the call). Default is 0. RetryTime : <number> Seconds between retries, Don't hammer an unavailable phone. Default is 300 (5 min). WaitTime : <number> Seconds to wait for an answer. Default is 45. Account : Set the account code to use. If the call answers, connect it here: Context : <context-name> Context in extensions.conf Extension : <ext> Extension definition in extensions.conf Priority : <priority> Priority of extension to start with Set : Set a variable for use in the extension logic (example: file1=/tmp/to ); in Asterisk 1.0.x use

Настройка записи разговоров freepbx

1. Заходим на Web-интерфейс  2. Выбираем   « Панель пользователя» и вводим логин и пароль для входа(логин и пароль — это внутренний номер абонента). 3. Если правильный логин и пароль, то попадаем в интерфейс пользователя: Дата  — дата звонка; Время  — время звонка; Номер  — отображается телефонный номер   ( а под ним — внутренний номер   ), с которого был произведен звонок; Источник  — указывается внутренний номер; Назначение  — указывается внутренний номер, куда был послан звонок; Длительность  — указывается время в секундах, телефонного разговора; Монитор  — имеет две иконки:  — открывает флеш плеер для проигрывания записи разговора;  — предлагает сохранить запись разговора на жесткий диск. 3. Прослушивание записи разговоров может происходить в двух вариантах: Вариант 1 Выбираете интересующий Вас звонок и нажимаете на иконку  , после чего под строчкой звонка откроется полоска флеш-плеера, где можно будет управлять ходом прослушивания звукового файла: Ва

Запись и обслуживание разговоров в Asterisk FreePBX

Как и многие другие компании мы используем  FreePBX —  графический интерфейс для Астериск. Служба безопасности требует записывать все входящие и исходящие звонки , не проблема все делается просто: Заходим в админку http://sip.domain.local/admin/config.php , далее General Settings и делаем как у казанно у меня на скрине: Вот вроде и все , но если не следить за записями  они забьют все место на масиве. На помощь нам приходит bash =) , пишем скрипт который будет удалять записи старше 14 дней ( для службы безопасности такой срок устраивает) #!/bin/bash # Указываем директорию где расположены файлы RECORDINGS=/var/spool/asterisk/monitor # Указываем период за какой срок удалять файлы записи  RECORDINGEXPIRY=14 # Указываем за какой срок хранить логи LOGEXPIRY=365 # Дата DATE=`date` # Удаляем записи старше $RECORDINGEXPIRY дней find $RECORDINGS -mtime +$RECORDINGEXPIRY -exec rm -rfv > removal-$DATE.log # Удаляем логи старше $LOGEXPRY find . -mtime +$LO