Резервирование интернета через 3Г модем

Обсуждение оборудования и его настройки
zilaev
Сообщения: 32
Зарегистрирован: 07 мар 2013, 17:55
Контактная информация:

29 май 2013, 12:59

Использую статью:
 http://habrahabr.ru/post/141785/
Конфигурация сети

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 запускается каждую минуту.

На резервный канал через ЮСБ модем переключается. а вот обратно нет.
Правда у меня основной канал со статическим IP без PPP. думаю что дело в этом.т.к. при использовании PPP выданный адрес и является шлюзом, а у меня шлюз забит статикой. как при определении ип адреса основного канала подсунуть ему шлюз, заданный вручную?


Аватара пользователя
simpl3x
Модератор
Сообщения: 1532
Зарегистрирован: 19 апр 2012, 14:03

29 май 2013, 13:23

задайте маршруту какой нибудь комментарий, а потом по коментарию найдите его:

Код: Выделить всё

/ip route get [/ip route find comment="main"] gateway


zilaev
Сообщения: 32
Зарегистрирован: 07 мар 2013, 17:55
Контактная информация:

29 май 2013, 13:36

т.е. я в скрипте define_main_if_ip
:global MainIf
:global MainIfAddress ""
:set MainIfAddress [/ip address get [find interface=$MainIf] address]

заменяю на
:set MainIfAddress [ip route get [/ip route find comment="MainGW"] gateway]
когда у нужного маршрута имя MainGW?


Аватара пользователя
simpl3x
Модератор
Сообщения: 1532
Зарегистрирован: 19 апр 2012, 14:03

29 май 2013, 13:38

да, только не имя, а комментарий. и получаете шлюз у этого маршрута.


zilaev
Сообщения: 32
Зарегистрирован: 07 мар 2013, 17:55
Контактная информация:

29 май 2013, 13:45

да, комментарий.
Нет не работает. пинг не проходит когда на маршруте основного канала метрика меняется на 2
Видимо проблема не в этом.....я тогда не понимаю для чего он есть скрипт определения ип адреса интерфейса....можно пояснить?


Аватара пользователя
simpl3x
Модератор
Сообщения: 1532
Зарегистрирован: 19 апр 2012, 14:03

29 май 2013, 13:57

Код: Выделить всё

Скрипт называется define_main_if_ip
:global MainIf
:global MainIfAddress ""
:set MainIfAddress [/ip address get [find interface=$MainIf] address]


Данный скрипт определяет IP-адрес основного интерфейса для доступа в интернет. Если этот интерфейс отсутствует, то скрипт будет завершаться с ошибкой, а в переменной MainIfAddress будет пустая строка.


суть в том, что у человека там vpn используется. т.е. если подключения нет, нет интерфейса, строка пустая, а дальше он проверяет:

Код: Выделить всё

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]


т.е. если адрес интерфейса НЕ пустая строка, то они пингует ресурсы.


zilaev
Сообщения: 32
Зарегистрирован: 07 мар 2013, 17:55
Контактная информация:

29 май 2013, 15:10

ок. с этим разобрались. Теперь такая беда: при появлении основного канала шлюз остается висеть со статусом unreachable
Хотя линк есть, инет есть на этом проводе
и в логах пишется:
Main internet connection error
Reserve internet connection error
куда копать. покажите в какую сторону:)
 "основной канал упал"
[admin@MikroTik] /system script> run connection_check
HOST SIZE TTL TIME STATUS
8.8.4.4 timeout
8.8.4.4 timeout
8.8.4.4 timeout
sent=3 received=0 packet-loss=100%
HOST SIZE TTL TIME STATUS

HOST SIZE TTL TIME STATUS
87.250.250.203 timeout
87.250.250.203 timeout
87.250.250.203 timeout
sent=3 received=0 packet-loss=100%
HOST SIZE TTL TIME STATUS

HOST SIZE TTL TIME STATUS
8.8.8.8 timeout
8.8.8.8 timeout
8.8.8.8 timeout
sent=3 received=0 packet-loss=100%
HOST SIZE TTL TIME STATUS

HOST SIZE TTL TIME STATUS
8.8.4.4 56 42 932ms
8.8.4.4 56 42
8.8.4.4 56 42
sent=3 received=3 packet-loss=0% min-rtt=286ms
HOST SIZE TTL

HOST SIZE TTL
87.250.250.203 56 47
87.250.250.203 56 47
87.250.250.203 56 47
sent=3 received=3 packet-loss=0% min-rtt=217ms
HOST SIZE TTL

HOST SIZE TTL
8.8.8.8 56 43
8.8.8.8 56 43
8.8.8.8 56 43
sent=3 received=3 packet-loss=0% min-rtt=237ms
HOST SIZE TTL

MainIfInetOk=false
RsrvIfInetOk=true
MainGWDistance=2
RsrvGWDistance=1

 "основной канал поднялся"
[admin@MikroTik] /system script> run connection_check
HOST SIZE TTL TIME STATUS
194.87.0.50 timeout
194.87.0.50 timeout
194.87.0.50 timeout
sent=3 received=0 packet-loss=100%
HOST SIZE TTL TIME STATUS

HOST SIZE TTL TIME STATUS
87.250.250.203 timeout
87.250.250.203 timeout
87.250.250.203 timeout
sent=3 received=0 packet-loss=100%
HOST SIZE TTL TIME STATUS

HOST SIZE TTL TIME STATUS
8.8.8.8 timeout
8.8.8.8 timeout
8.8.8.8 timeout
sent=3 received=0 packet-loss=100%
HOST SIZE TTL TIME STATUS

HOST SIZE TTL TIME STATUS
194.87.0.50 56 48 323ms
194.87.0.50 56 48 223ms
194.87.0.50 56 48 209ms
sent=3 received=3 packet-loss=0% min-rtt=209ms avg-rtt=251ms max-rtt=323ms
HOST SIZE TTL TIME STATUS

HOST SIZE TTL TIME STATUS
87.250.250.203 timeout
87.250.250.203 timeout
87.250.250.203 timeout
sent=3 received=0 packet-loss=100%
HOST SIZE TTL TIME STATUS

HOST SIZE TTL TIME STATUS
8.8.8.8 timeout
8.8.8.8 timeout
8.8.8.8 56 42 423ms
sent=3 received=1 packet-loss=66% min-rtt=423ms avg-rtt=423ms max-rtt=423ms
HOST SIZE TTL TIME STATUS

MainIfInetOk=false
RsrvIfInetOk=false
MainGWDistance=2
RsrvGWDistance=1
Последний раз редактировалось zilaev 30 май 2013, 12:23, всего редактировалось 1 раз.


Аватара пользователя
simpl3x
Модератор
Сообщения: 1532
Зарегистрирован: 19 апр 2012, 14:03

29 май 2013, 15:40

вообще немного странно, если честно:
у вас там где "основной канал" упал:

Код: Выделить всё

MainGWDistance=1
RsrvGWDistance=2


т.е. скрипт подставляет на основной канал меньшую дистанцию, т.е. высший приоритет, т.е. маршрутизацию гонит туда. хотя по логике он упал.
и на оборот, там где он поднял у него выставляет больший путь. тут что то не то со сравнением критериев.
а точно висит unrechable? или синим подсвечено? скрипт distance вообще меняет на маршрутах?


zilaev
Сообщения: 32
Зарегистрирован: 07 мар 2013, 17:55
Контактная информация:

30 май 2013, 12:24

извиняюсь. поправил.
Как пустить пинг через определенный шлюз, не важно какая у него метрика. как через интерфейс я знаю, но в таком случае пинг не проходит.....


Аватара пользователя
simpl3x
Модератор
Сообщения: 1532
Зарегистрирован: 19 апр 2012, 14:03

30 май 2013, 13:03

вообще, насколько я помню, так оно и пускается, указал интерфейс и через него уходит пинг. по этому принципу строятся все скрипты failover
вот например облегченная версия скрипта без всяких умных мыслей:
http://wiki.mikrotik.com/wiki/Failover_Scripting
где то тут на форуме человек показывал еще более "легкую" форму. Везде один и тот же принцип


Ответить