Как работают вместе failover и netwatch. Взгляд изнутри.
Почти каждой более-менее подросшей компании начинает хотеться качества коммуникаций. Среди прочего, заказчику часто хочется отказоустойчивый «Dual WAN» и VoIP телефонию. Тоже отказоустойчивую, разумеется. Руководств и статей по каждой теме в отдельности написано много, но внезапно оказалось, что совместить первое и второе получается не у всех.
На Хабре уже есть статья «Mikrotik. Failover. Load Balancing» от vdemchuk. Как оказалось, она послужила для многих источником копипасты кода в маршрутизаторы.
Хорошее, рабочее решение, но SIP-клиенты из LAN, подключающиеся к внешней IP-АТС посредством NAT, при переключении теряли связь. Проблема известная. Связана она с работой Connection tracker, который запоминает имеющиеся соединения вовне, и сохраняет их состояние независимо от других условий.
Понять почему так происходит можно посмотрев на диаграмму packet flow:
Для транзитного трафика процедура обработки connection tracker выполняется всего в одной цепочке — prerouting, (т.е. до роутинга), до выбора маршрута и исходящего интерфейса. На этой стадии еще неизвестно, через какой интерфейс пакет пойдет в Интернет, и отследить src-ip при нескольких Wan-интерфейсах невозможно. Механизм фиксирует установленные соединения уже пост-фактум. Фиксирует и запоминает на время пока через соединение идут пакеты или пока не истечет заданный таймаут.
Описанное поведение характерно не только для маршрутизаторов MikroTik, но и для большинства Linux-based систем выполняющих NAT.
В результате, при обрыве связи через WAN1, поток данных послушно направляется через WAN2, только SOURCE IP прошедших через NAT пакетов остается неизменный — от интерфейса WAN1, т.к. в connection tracker уже есть соответствующая запись. Естественно, ответы на такие пакеты идут на интерфейс WAN1 уже потерявший связь с внешним миром. В итоге, связь как будто есть, но на самом деле её нет. При этом все новые соединения устанавливаются корректно.
Hint: увидеть с каких и на какие адреса делается NAT можно в колонках «Reply Src. Address» и «Reply Dst. Address». Отображение этих колонок включается в таблице «connections» с помощью правой кнопки мыши.
На первый взгляд выход выглядит довольно простым — при переключении сбросить ранее установленные SIP-соединения, чтобы они установились заново, уже с новым SRC-IP. Благо простой скрипт по просторам интернета бродит.
:foreach i in=[/ip firewall connection find dst-address~":5060"] do={ /ip firewall connection remove $i }
Три шага к фейлу
Шаг первый. Копипастеры добросовестно переносят конфиг для Failover recursive routing:
/ip address add address=10.100.1.1/24 interface=ISP1
/ip address add address=10.200.1.1/24 interface=ISP2
# Настроим локальный интерфейс
/ip address add address=10.1.1.1/24 interface=LAN
# скроем за NAT все что выходит из локальной сети
/ip firewall nat add src-address=10.1.1.0/24 action=masquerade chain=srcnat
###Обеспечение failover c более глубоким анализом канала###
#с помощью параметра scope укажем рекурсивные пути к узлам 8.8.8.8 и 8.8.4.4
/ip route add dst-address=8.8.8.8 gateway=10.100.1.254 scope=10
/ip route add dst-address=8.8.4.4 gateway=10.200.1.254 scope=10
# укажем 2 default gateway через узлы путь к которым указан рекурсивно
/ip route add dst-address=0.0.0.0/0 gateway=8.8.8.8 distance=1 check-gateway=ping
/ip route add dst-address=0.0.0.0/0 gateway=8.8.4.4 distance=2 check-gateway=ping
Шаг второй. Отследить событие переключения. Чем? "/tool netwatch", естественно! Попытка отследить падение шлюза WAN1 обычно выглядит так:
add comment=«Check Main Link via 8.8.8.8» host=8.8.8.8 timeout=500ms /
down-script=":log warning («WAN1 DOWN»)
:foreach i in=[/ip firewall connection find dst-address~":5060"] do={
:log warning («clear-SIP-connections: clearing connection src-address:$[/ip firewall connection get $i src-address] dst-address:$[/ip firewall connection get $i dst-address]»)
/ip firewall connection remove $i}"
up-script=":log warning («WAN1 UP»)
:foreach i in=[/ip firewall connection find dst-address~":5060"] do={
:log warning («clear-SIP-connections: clearing connection src-address:$[/ip firewall connection get $i src-address] dst-address:$[/ip firewall connection get $i dst-address]»)
/ip firewall connection remove $i}"
Шаг третий. Проверка.
Админ гасит первый аплинк WAN1 и вручную запускает скрипт. SIP-клиенты переподключились. Работает? Работает!
Админ включает обратно WAN1 и вручную запускает скрипт. SIP-клиенты переподключились. Работает? Работает!
Fail
В реальной обстановке такой конфиг работать отказывается. Неоднократное повторение шага №3 приводит админа в состояние озлобления и мы слышим «Не работает ваш микротик!».
Разбор полётов
Всё дело в непонимании того, как происходит работа утилиты Netwatch. Применительно в отношении именно рекурсивного роутинга, утилита просто пингует заданный хост согласно основной таблице маршрутизации, используя активные маршруты.
Проведем эксперимент. Отключим основной канал WAN1 и посмотрим и интерфейс /tool netwatch. Мы увидим, что хост 8.8.8.8 по-прежнему имеет состояние UP.
Для сравнения опция check-gateway=ping, работает для каждого маршрута в отдельности в т.ч. рекурсивно, и делает сам маршрут активным либо НЕактивным.
Netwatch использует уже активные на данный момент маршруты. Когда что-либо происходит на линке до шлюза провайдера ISP1 (WAN1), маршрут до 8.8.8.8 через WAN1 становится неактивным, и netwatch игнорирует его, отправляя пакеты в новый default route. Failover играет злую шутку, и netwatch считает, что всё в порядке.
Второй вариант поведения netwatch, это двойное срабатывание. Механизм его таков: если пинги от netwatch попадут в таймаут check-gateway, то на один цикл проверки хост будет признан DOWN. Сработает скрипт переключения канала. SIP-соединения корректно перейдут на новый линк. Работает? Не совсем.
Скоро таблица маршрутизации перестроится, хост 8.8.8.8 получит статус UP, вновь сработает скрипт сброса SIP-соединений. Соединения второй раз переустановятся через WAN2.
В результате, при возвращении в строй ISP1 и переходе рабочего трафика на WAN1, SIP-соединения так и останутся висеть через ISP2 (WAN2). Чревато это тем, что при проблемах у на запасном канале система этого не заметит и телефонной связи не станет.
Решение
Для того, чтобы трафик на используемый для мониторинга хост 8.8.8.8 не заворачивался на ISP2, нам нужно иметь запасной маршрут до 8.8.8.8. На случай падения ISP1, создаем резервный маршрут с большим значением distance, например distance=10 и type=blackhole. Он и станет активным при пропадании линка до WAN1 Gateway:
/ip route add distance=10 dst-address=8.8.8.8 type=blackhole
В итоге имеем дополнение конфига всего лишь одной строкой:
/ip address add address=10.100.1.1/24 interface=ISP1
/ip address add address=10.200.1.1/24 interface=ISP2
# Настроим локальный интерфейс
/ip address add address=10.1.1.1/24 interface=LAN
# скроем за NAT все что выходит из локальной сети
/ip firewall nat add src-address=10.1.1.0/24 action=masquerade chain=srcnat
###Обеспечение failover c более глубоким анализом канала###
#с помощью параметра scope укажем рекурсивные пути к узлам 8.8.8.8 и 8.8.4.4
/ip route add dst-address=8.8.8.8 gateway=10.100.1.254 scope=10
/ip route add distance=10 dst-address=8.8.8.8 type=blackhole
/ip route add dst-address=8.8.4.4 gateway=10.200.1.254 scope=10
# укажем 2 default gateway через узлы путь к которым указан рекурсивно
/ip route add dst-address=0.0.0.0/0 gateway=8.8.8.8 distance=1 check-gateway=ping
/ip route add dst-address=0.0.0.0/0 gateway=8.8.4.4 distance=2 check-gateway=ping
Данная ситуация характерна именно при падении последней мили, когда шлюз ISP1 становится недоступным. Либо при использовании туннелей, которые более подвержены падениям в силу цепной зависимости.
Надеюсь, статья поможет вам избежать подобных ошибок. Выбирайте свежие мануалы. Будьте в курсе, и всё у вас «взлетит».
Комментарии (25)
m0Ray
08.01.2017 22:14+2Я делал проще. Прописывал явные маршруты до шлюзов провайдеров, с указанием, через какой интефейс их направлять, и пинговал эти шлюзы.
А ещё в большинстве конфигураций можно не использовать NetWatch — у маршрута есть параметр check-gateway, а дальше — метрики и mangle.dobergroup
09.01.2017 09:21и пинговал эти шлюзы.
Шлюз пинговать все-таки не надежно, шлюз то может отвечать, а вот дальше маршрут сломаетсяm0Ray
09.01.2017 13:05Тогда я выбирал иной объект для пингов, например, узел магистрального провайдера, к которому подключен местный, или ещё что-нибудь в два, максимум три хопа.
Но такое — редкость, бывает только у совсем уж криворуких провайдеров.
Были, правда, случаи, когда провайдер отключал клиента за неуплату, но в таком случае провайдер менял параметры выдаваемых по PPP адресов и нужный шлюз всё-таки оказывался недоступен.
Erelecano
09.01.2017 17:50Таки пинговать Google Public DNS, как это предлагается по дефолту в OpenWRT(по крайней мере в той ревизии, что я собирал для своей домашней железки) и по условию недоступности переключать канал.
nkusnetsov
09.01.2017 09:28У дефолтных маршрутов как раз указана опция check-gateway.
/ip route add dst-address=0.0.0.0/0 gateway=8.8.8.8 distance=1 check-gateway=ping
Это помогает активировать/деактивировать сам маршрут.
Netwatch этого не понимает. Он пользутестя результатом — перестроенным на запасной маршрутом.
Насколько знаю, в feature request к MikroTik'у давно висит запрос явно указывать интерфейс, с которого будет пинговать NetWattch. Вот, только когда они это реализуют — неизвестно.m0Ray
09.01.2017 13:14Но ведь если деактивирован маршрут, можно почти всё порешать при помощи метрик и «подкрашивания» пакетов в mangle, разве нет?
У меня был случай: две дружественных конторы, два провайдера, один микротик между ними всеми. Одна контора пользуется одним линком, вторая другим, но в случае чего каждая контора автоматически переключается на пользование соседскими интернетами. Вообще без единого скрипта всё сделано.
Ну, кроме немедленного разрыва всех SIP-соединений, к примеру, и то есть варианты…
Мне в голову не приходило руками рвать SIP-сессии, кстати. Насколько мне известно, они через несколько секунд рвутся сами по таймауту. Вот только не помню, через сколько.nkusnetsov
09.01.2017 15:11«Подкрашивание» пакетов фаерволом, во-первых кушает ресурсы и может требовать отдельной таблицы роутинга. Во-вторых это еще одна область настройки, что в случае смены правил может привести к неочевидным сбоям, а так всё в одном разделе "/ip route" настроено и никуда более лазать не нужно. В третьих, модификация от базовой, описанной в статье минимальна — +1 строка конфига (1 доп.маршрут).
m0Ray
09.01.2017 15:45Не заметил, чтобы загрузка процессора или задержка прохождения пакетов сильно менялась при подкрашивании. Разумеется, кушает, но не сказал бы, что катастрофически много.
Отдельной таблицы роутинга не надо. Тут скорее можно рассматривать ситуацию под таким углом: каждый «цвет» сам по себе отдельная таблица роутинга.
«Модификация от базовой», хех… Вы говорите так, будто этот способ единственно канонiчный и кошеrный. Микротик зачастую позволяет решить одну и ту же задачу разными способами, на вкус и цвет. Мне вот лично нравится думать роутингом, а не скриптом, и это тоже работает.
А бездумной копипастой я ещё в детстве заниматься бросил. Когда выяснилось, что батина версия «Радио-86РК» не совсем клон и не во всех местах с ним совместима, и код из журнала надо понимать и корректировать под свои нужды, а не тупо копировать…
P.S. И да, на микротиках я использую winbox и вебморду, у меня так получается быстрее, чем в консоли.
Nengchak
09.01.2017 04:38+1А можно еще пинговать через определенный интерфейс, т.е. я такое реализовывал через крон, раз в 5 сек запускал скрипт.
nkusnetsov
09.01.2017 09:30Можно. К сожалению, далеко не все владеют навыком написания скриптов к микротику. Постоянно встречаю деятелей, которым настройка оборудования сложнее домашнего TP-Linka создает проблемы. От микротика эти люди вообще впадают в шок или истерику. Куда уж им в скрипте результаты анализировать и обрабатывать.
Nengchak
09.01.2017 13:02Ну если человек взял мтик, значит он о нем наслышан. И по крайней мере сможет написать скрипт.
PS: Язык то легкий.nkusnetsov
09.01.2017 15:02Ха. У нас в операторах связи такие «спецы» работают, что аж страшно за отрасль реально.
Чел на НАГе с 13(!) летним стажем со статусом «VIP» морозит:
несмешной текст вообщеВ копилку сисадмина. Мокротик настроить нормально можно только после 5 сбросов в заводские настройки. Инет в настройке мокротика не помогает даже в типовых случаях, ибо из пяти инструкций — ни одна на другую не похожа. Если вы сумели настроить мокротик с 4-го раза — вы клон Сааба, а если с первого, то вы прадедушка Сааба :)
Просто на неделе притащили микротик для настройки в типовом режиме бытового роутера. Я сразу послал клиента в пешее эротическое, а техдир — закусился. Гимнастика его мозга продолжалась 3 дня, из них — два выходных дома :) Но он — победил адское поделие :)Nengchak
09.01.2017 15:33Ну, у каждого своя узкая специализация =) но да, мтик весьма и весьма легок в настройке
m0Ray
09.01.2017 16:28Вывод: чтение документации ведёт к тому, чтобы стать прадедушкой Сааба (хоть я и не знаю, кто это такой).
Прежде чем купить свой первый микротик, я перелопатил документацию. Точнее, чтение документации привело к тому, что я его себе захотел. Нет, вот так: ЗАХОТЕЛ.
А теперь в микротиках есть ещё и quick set, не разобраться в этом — уже признак профнепригодности.nkusnetsov
09.01.2017 18:51Увы, в отличие от Вас, есть граждане которые считают, что «вот сиско надо изучать, а всё остальное я и сам знаю». Потом напоровшись на грабли собственного незнания граждане кричат, что «микротик не работает, надо было брать сиско».
Касательно QuickSet — он предназначен исключительно для стартового, базового конфигурирования. Если в микротике уже прописана какая-то работающая сложная конфигурация, QuickSet для дополнения параметров использовать нельзя, т.к. он может тупо накатить свои параметры без учета уже имеющихся.m0Ray
09.01.2017 19:07Quick Set — это как раз для типичной настройки бытового роутера, как надо было админу, которого вы цитировали. «Из коробки» он вообще первым вылазит в любой интерфейс, что в консоль, что в winbox, что в вебморду. И в графических интерфейсах это первая кнопка. Как можно этого всего не заметить и возиться три дня с этой задачей — уму непостижимо. Дело на пару минут максимум.
Конечно же, использовать Quick Set для более сложных задач не надо, он и не предназначен для этого. Его предназначение — быстро «взлететь», дать нервным юзерам хоть какой-то интернет и добраться до сайта с документацией, чтобы не спеша её воскурить. Ибо Толстых Книжек к этим роутерам не дают (да и надо ли?)
copenhagen72
09.01.2017 18:30А откуда вообще нужно брать информацию по настройке микротика? В русских интернетах информации мало, и «из пяти инструкций — ни одна на другую не похожа». С сетях не спец, но дома стоит микротик.
Как я понял в данном варианте конфигурации, если пакеты ISP1 теряет через раз, то канал подключения будет скакать туда-сюда хаотично?nkusnetsov
09.01.2017 18:44+1Оборудование MikroTik базируется на Linux. Если есть понимание того, как реализована работа Ethernet + IP в Linux-Based системах, то ничего особенно сложного в настройке MikroTik нет. Официальная вики достаточно бодро обновляется, там же есть «examples».
Также есть community в соцсетях и форумы. На том же forum.nag.ru есть целых два раздела посвященных исключительно mikrotik.
Как я понял в данном варианте конфигурации, если пакеты ISP1 теряет через раз, то канал подключения будет скакать туда-сюда хаотично?
Не слишком хаотично. Есть чёткий критерий, по которому оценивается доступность канала. Этот критерий используется при «легком конфигурировании одним крыжиком»:
If no response from gateway is received for 10 seconds, request times out. After two timeouts gateway is considered unreachable.
Если хочется оценивать доступность канала по-другому — никто не мешает написать скрипт.
m0Ray
09.01.2017 18:59| А откуда вообще нужно брать информацию по настройке микротика?
Из документации и головы (если она есть).
Тут уже уже упоминали… Один мой коллега, посмотрев на микротик, с напускной горечью воскликнул: «Ну нельзя же делать такой простой и наглядный интерфейс к iptables! Его же любой тупица освоит и мы без работы останемся!»
То есть да, надо просто представлять себе, как работает линуксовый iptables и стек IP (маршрутизация, NAT и всё такое). Это, я считаю, базовые знания для сетевого админа. И этого уже достаточно, чтобы правильно настроить микротик в 95% случаев: термины там используются общепринятые. В остальных случаях надо залезть в документацию и посмотреть, как реализован тот или иной механизм в микротике.
Копипастить же конфиги, не понимая, что делается — это, знаете ли… В смежной области таких «админов» называют «скрипт-кидди». И для них в публикуемые скрипты и программки часто вставляют какие-нибудь невинные шутки типа «патча Бармина».
Общий принцип таков: посмотрел на образец конфигурации роутера — и написал свою. В случае с микротиком — вообще сводится к «натыкал мышкой», ибо winbox и вебморда. Надо просто понять, что ты хочешь делать с потоком пакетов, и знать, какие инструменты для этого есть в микротике — а они все как на ладони в менюшке. Иногда, конечно, попадаются пункты вроде «Torch» или «RoMON», о которых сразу не скажешь, что это такое — но вот это и есть те самые 5%, о которых можно справиться в документации.nkusnetsov
09.01.2017 19:32«Ну нельзя же делать такой простой и наглядный интерфейс к iptables! Его же любой тупица освоит и мы без работы останемся!»
То есть да, надо просто представлять себе, как работает линуксовый iptables и стек IP (маршрутизация, NAT и всё такое)
Я Вам больше скажу. Шапочно знаком с несколькими админами в небольших предприятиях, которые начинали с роутеров на винде [+керио | +иса] и переходили на линукс через микротик, ибо там логика уже линуксовая, а интерфейс наглядно-виндовый. У тех из них, с кем общался главная претензия оказывалась как раз к линуксовой консоли, за «отсутствие наглядности как в винбоксе». Бывает и такое, да…m0Ray
09.01.2017 20:18Ну, за наглядностью в линуксе тоже ходить далеко не надо — всяческих «визуальных конструкторов файрволлов» в линуксовом мире как минимум больше одного, а в приличные дистрибутивы они ещё и органично встроены (в OpenSuSE имеется служба SuSEFirewall и соответствующий плагин в панель YaST). Для управления нюансами IP-протокола вполне годится NetworkManager, но если он по какой-либо причине неприемлем, в приличных дистрибутивах имеются и свои средства (в той же OpenSuSE — служба wicked и опять же плагин в панель управления YaST). Кстати, если на сервере нет графики (а вообще кому она нужна на сервере?) YaST можно использовать с не меньшей наглядностью в консоли, он имеет ncurses-интерфейс.
Хотя, конечно, интерфейс winbox более удобен и детален, да и в микротиках вообще есть инструменты, которым до сих пор нет аналогов в других системах (EoIP, к примеру), но на то он и RouterOS. Не всякий микротик можно заменить линуксбоксом. Но — те самые 95%. Хотя для этого всё же надо иметь особые причины — RouterOS сам по себе недорог и имеет версию для x86, да и роутеры у микротиков вполне себя оправдывают по цене.
Однако навскидку знаю один именно такой случай из своей практики — Asterisk весьма тяжело и нехорошо просовывать через NAT, а айпишник только один.nkusnetsov
09.01.2017 20:37С asterisk, вроде упростили. Для прохода через nat сделали pjsip. Но я его еще не пробовал применять пока. Небыло необходимости.
m0Ray
09.01.2017 21:13Уж не знаю, что там упростили, но RTP по прежнему надо транслировать на 7-м уровне, иначе голос не ходит (с сигнализацией-то всё ровно). А эта штука как раз в микротиках и отсутствует.
Я имею в виду ситуацию, когда и сервер, и клиент за NAT.
В некотором роде несправедливо сие, ибо ALG для SIP/RTP даже в позорнейших D-Link-ах есть. Поэтому приходится для внешних клиентов вывешивать Asterisk в белые адреса непосредственно.
FessAectan
А ещё можно как у меня сделать — https://m.habrahabr.ru/post/271747/