На связи удалённо · офис завтра с 09:00

Сети

Интернет есть, но его нет: провайдер, который врал зелёной лампочкой

Оптика горела зелёным, шлюз пинговался, а интернета не было. Научили MikroTik проверять сам интернет и за секунды уходить на резервный LTE.

У заказчика два офиса, между ними VPN-туннель, по туннелю синхронизируются базы. Основной канал — оптика от провайдера, резервный — LTE-модем. Отказоустойчивость, всё как в учебнике.

И раз в неделю-две — одна и та же картина. Оптика горит зелёным. Шлюз провайдера пингуется. Роутер уверен, что всё прекрасно, и продолжает отправлять трафик в основной канал. А трафик где-то в глубине сети провайдера уходит в чёрную дыру: сайты не открываются, туннель висит, базы не синхронизируются. Резервный LTE-канал при этом спокойно ждёт, потому что никто не сказал ему, что пора работать.

Почему стандартная проверка не работает

У MikroTik у маршрута есть параметр check-gateway=ping: роутер пингует шлюз и, если шлюз не отвечает, отключает маршрут. Это ловит обрыв кабеля, выключенное оборудование провайдера, отвалившийся линк.

Но в нашем случае шлюз провайдера отвечал. Он стоит в двух шагах от нас, и с ним всё в порядке. Проблема была дальше, внутри сети провайдера, куда проверка «пингуем шлюз» не заглядывает. Роутер видит живого соседа и не догадывается, что дальше соседа дороги нет.

Рекурсивная маршрутизация: проверяем не соседа, а интернет

Решение — проверять доступность не шлюза, а чего-то далёкого в интернете, причём строго через основной канал. В MikroTik это делается приёмом, который называется рекурсивной маршрутизацией.

Идея в двух строчках. Первая: «до адреса 8.8.8.8 иди только через шлюз основного провайдера». Вторая: «маршрут по умолчанию идёт через 8.8.8.8, проверяй его пингом». Если 8.8.8.8 перестаёт отвечать через основной канал, маршрут по умолчанию отключается, и трафик уходит в резерв.

/ip route
# проверочные адреса — строго через основного провайдера
add dst-address=8.8.8.8/32 gateway=<ШЛЮЗ_ПРОВАЙДЕРА> scope=10 comment="probe1 ISP1"
add dst-address=1.1.1.1/32 gateway=<ШЛЮЗ_ПРОВАЙДЕРА> scope=10 comment="probe2 ISP1"

# основной маршрут — «через» проверочные адреса
add dst-address=0.0.0.0/0 gateway=8.8.8.8 target-scope=11 check-gateway=ping \
    distance=1 comment="ISP1_MAIN"
add dst-address=0.0.0.0/0 gateway=1.1.1.1 target-scope=11 check-gateway=ping \
    distance=1 comment="ISP1_MAIN"

# резерв
add dst-address=0.0.0.0/0 gateway=lte1 distance=2 comment="LTE_BACKUP"

Пара scope=10 и target-scope=11 — это то, что разрешает роутеру искать шлюз 8.8.8.8 через другой маршрут, то есть рекурсивно. Без этого MikroTik просто не поймёт, как добраться до «шлюза», который находится не в соседней сети.

Почему проверочных адресов два? Один адрес — это риск ложного переключения: Google тоже иногда отвечает на пинг с задержкой или ограничивает его. Два независимых адреса (Google и Cloudflare) означают, что для переключения на резерв должны «умереть» оба, а это уже действительно проблема провайдера, а не их.

Подвох номер два: переключились, а ничего не работает

Маршрут переключился за секунды. А пользователи ещё минуту-две сидят без интернета, и VPN-туннель не поднимается. Почему?

Из-за таблицы соединений. Роутер помнит каждое активное соединение: кто с кем, через какой адрес, с какой подменой адресов (NAT). Уже открытые соединения продолжают жить по старым записям — с адресом основного провайдера, через канал, который не работает. Новые маршруты на них не влияют. Соединения умрут сами, но только по таймауту, а он у некоторых записей очень долгий.

Самое коварное: MikroTik умеет сам чистить такие записи, но только когда интерфейс провайдера падает. Здесь интерфейс не падал — оптика горела зелёным. Значит, чистить нужно самим.

Скрипт-спасатель

Для этого используется Netwatch — встроенный в RouterOS сторож, который пингует адрес и запускает скрипт при изменении состояния. Пингуем тот же проверочный адрес: благодаря маршруту /32 пинг идёт строго через основной канал. Но один молчащий адрес — ещё не авария: Google мог просто ограничить пинг. Поэтому скрипт сначала ждёт до 30 секунд, пока check-gateway погасит маршруты ISP1_MAIN, и только если неактивны оба — удаляет записи о соединениях, чтобы всё переподключилось уже через резерв, и сообщает в Telegram:

/tool netwatch
add host=8.8.8.8 type=icmp interval=10s timeout=1s comment="ISP1 watch" \
    down-script={
        # один молчащий адрес — ещё не авария: ждём, пока check-gateway погасит оба основных маршрута
        :local tries 0
        :while (([:len [/ip route find where comment="ISP1_MAIN" and active]] > 0) && ($tries < 6)) do={
            :delay 5s
            :set tries ($tries + 1)
        }
        :if ([:len [/ip route find where comment="ISP1_MAIN" and active]] = 0) do={
            :log warning "ISP1: интернет пропал при живом линке, уходим на LTE"
            /ip firewall connection remove [find]
            /tool fetch url="https://api.telegram.org/bot<ТОКЕН>/sendMessage" \
                http-method=post http-header-field="Content-Type: application/json" \
                http-data="{\"chat_id\":\"<ID_ЧАТА>\",\"text\":\"ISP1 упал, работаем через LTE\"}" \
                keep-result=no
        } else={
            :log info "ISP1: 8.8.8.8 молчит, но основной маршрут жив — ничего не сбрасываем"
        }
    } \
    up-script={
        :log warning "ISP1: интернет вернулся, переходим обратно"
        /ip firewall connection remove [find]
    }

Сообщение в Telegram уйдёт уже через резервный канал — к моменту запуска скрипта трафик туда переключён. А при возвращении основного канала соединения снова сбрасываются, чтобы всё вернулось на оптику, а не продолжало расходовать трафик LTE.

Почему мы не выключаем connection tracking

В интернете часто встречается другой вариант сброса: выключить отслеживание соединений и через секунду включить снова (connection tracking set enabled=no, потом yes). Мы сами какое-то время так делали. Это работает, таблица действительно очищается. Но в эту секунду весь межсетевой экран, опирающийся на состояние соединений, перестаёт понимать, какие пакеты свои, а какие чужие. Правила вида «разрешить установленные соединения» и «запретить невалидные» на секунду работают вслепую. На роутере, который смотрит в интернет, лучше без таких секунд.

Команда /ip firewall connection remove [find] делает то же, что нужно, — очищает таблицу, — но межсетевой экран при этом продолжает работать. Локальные сессии внутри офиса при этом не рвутся: роутер подхватывает их заново по первому же пакету.

Как проверить, не дожидаясь аварии

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

/ip firewall filter
add chain=output protocol=icmp dst-address=8.8.8.8 action=drop \
    comment="TEST failover" place-before=0
add chain=output protocol=icmp dst-address=1.1.1.1 action=drop \
    comment="TEST failover" place-before=0

Через несколько секунд маршрут переключится, придёт сообщение в Telegram, а пользователи продолжат работать через LTE. После проверки правила удаляются:

/ip firewall filter remove [find comment="TEST failover"]

Мы делаем такую проверку после каждой настройки и раз в квартал на работающих объектах. Резервный канал, который ни разу не проверяли, — это не резерв, а надежда.

Что получилось

Теперь, когда у провайдера что-то ломается в глубине сети, офис переходит на LTE за 10–20 секунд. Большинство пользователей замечают это разве что по чуть более медленной загрузке тяжёлых файлов. VPN-туннель поднимается через резерв, синхронизация баз продолжается. А мы узнаём о проблеме из Telegram раньше, чем кто-то успевает позвонить.

Что из этого вынести

Зелёная лампочка на оборудовании провайдера означает только то, что свет дошёл до соседнего устройства. Чтобы резервный канал действительно спасал, роутер должен проверять доступность интернета, а не соседа, а после переключения — сбрасывать старые соединения. И самое важное: переключение нужно проверить заранее, пока всё работает. Настройку резервирования каналов, VPN между офисами и мониторинг мы делаем для клиентов на абонентском обслуживании и как отдельные работы.

Ещё проекты

Сети

Wi-Fi в здании на 16 000 м²: почему «поставьте мощнее» не значит «лучше»

Организация: четыре этажа, около 16 000 м², больше ста сотрудников, порядка 120 пользовательских ноутбуков и два компьютерных зала. Wi-Fi есть — 52 точки доступа на отдельном контроллере, — но в части кабинетов «интернет не ловит», а на мероприятиях в зале связь падает совсем.

Позвонить

Сайт использует cookie: для работы форм, отзывов с Яндекс.Карт и Яндекс.Метрики — чтобы понимать, что улучшить. Подробнее