Балансировка двух провайдеров на MikroTik

Балансировка двух интернет-каналов и failover на MikroTik RB952UA: предсказуемо, без “магии”

У клиента небольшой офис (примерно 10–20 рабочих мест), где интернет нужен постоянно: облачная телефония, CRM, видеосвязь, удалённый доступ, обмен файлами. Раньше всё работало через одного провайдера — и это было «нормально» ровно до первого серьёзного обрыва: при аварии на линии вставало всё, включая телефонию и работу сотрудников.

Клиент решил подключить второго провайдера и поставил задачу:

  • Сделать балансировку между двумя WAN-каналами, чтобы использовать суммарную пропускную способность.
  • Сделать автоматическое переключение (failover), чтобы при падении одного провайдера офис не оставался без интернета.
  • Сохранить предсказуемость: чтобы не ломались сайты/сервисы из-за «скачущего» выхода в интернет и асимметричной маршрутизации.
  • По возможности — оставить конфигурацию читаемой и поддерживаемой (комментарии, списки интерфейсов, логика без “магии”).

Оборудование и технические данные

В качестве шлюза использовался MikroTik RB952UA (часто встречается как RB952Ui / линейка hAP), потому что он хорошо закрывает офисные потребности “в одном корпусе”:

  • 5 Ethernet-портов (обычно 10/100, в зависимости от ревизии)
  • Wi-Fi (2.4 ГГц и/или 5 ГГц — зависит от конкретной модели семейства)
  • RouterOS с достаточным набором функций для NAT, firewall, mangle и policy routing
  • Компактный формат и низкое энергопотребление
  • Возможность аккуратно развести WAN/LAN по портам и сразу подключить точки/рабочие места

Для задачи балансировки важны не «гигабитные рекорды», а стабильность маршрутизации и корректная работа firewall/mangle, и MikroTik в этом плане очень удобен.

Схема подключения

Логика была максимально простая:

  • WAN1 (Провайдер #1) → ether1
  • WAN2 (Провайдер #2) → ether2
  • LAN (офис) → bridge из ether3–ether5 + Wi-Fi (если используется)

Примерная схема:

        [ ISP1 ] ---- ether1 (WAN1)
       /

[MikroTik RB952UA]
\
[ ISP2 ] ---- ether2 (WAN2)

LAN: ether3-ether5 + Wi-Fi -> bridge -> офисная сеть

Как мы добьёмся “и балансировки, и предсказуемости”

Если просто сделать два default-route с одинаковой дистанцией, то MikroTik действительно начнёт распределять трафик. Но для офиса это часто заканчивается “странными” проблемами: часть сервисов видит прыгающий внешний IP, где-то рушатся сессии, а ещё появляется асимметричная маршрутизация (пакет ушёл через WAN1, а ответ попытался вернуться через WAN2).

Поэтому используем связку:

  • PCC (Per Connection Classifier) — распределяем соединения, а не пакеты. Один TCP/UDP-сеанс закрепляется за конкретным WAN и дальше не “прыгает”.
  • Маркировка соединений и маршрутов — чтобы ответы на входящие/исходящие сессии уходили тем же WAN.
  • Рекурсивные маршруты + проверка доступности — чтобы failover срабатывал не только при “линк up/down”, но и при реальной недоступности интернета за провайдером.
  • Читаемость — interface lists, комментарии, минимальная “магия”.

Важно: PCC даёт “суммарную полосу” на множестве соединений. Одна большая загрузка (один поток) не станет в 2 раза быстрее — она всё равно будет сидеть на одном WAN.

Подготовка: интерфейсы, bridge, адреса

Ниже — пример конфигурации через терминал RouterOS. Команды подходят для RouterOS v6 и v7 в части mangle/NAT. Для v7 с “routing tables” можно сделать ещё аккуратнее, но логика остаётся той же (в конце дам примечания).

Предположения (подставьте свои значения):

  • LAN: 192.168.88.0/24, gateway 192.168.88.1
  • WAN1: ether1, получает адрес по DHCP или статикой
  • WAN2: ether2, получает адрес по DHCP или статикой
# 1) Bridge для LAN (ether3-ether5 + Wi-Fi по желанию)
# (Если bridge уже есть — пропустите и только проверьте порты)

# /interface bridge add name=br-lan comment="LAN bridge"
# /interface bridge port add bridge=br-lan interface=ether3
# /interface bridge port add bridge=br-lan interface=ether4
# /interface bridge port add bridge=br-lan interface=ether5
# Wi-Fi интерфейсы добавьте сюда же при необходимости

# 2) IP на LAN
/ip address add address=192.168.88.1/24 interface=br-lan comment="LAN gateway"

# 3) Списки интерфейсов — для читаемости правил
/interface list add name=WAN comment="All uplinks"
/interface list add name=LAN comment="Office LAN"

/interface list member add list=WAN interface=ether1 comment="WAN1 ISP1"
/interface list member add list=WAN interface=ether2 comment="WAN2 ISP2"
/interface list member add list=LAN interface=br-lan comment="LAN bridge"

Если провайдеры выдают адреса по DHCP — включите DHCP-клиенты на ether1/ether2. Если адреса статические — задайте /ip address и /ip route к шлюзам провайдеров вручную (ниже это пригодится для рекурсивных маршрутов).

NAT: отдельная “маскара” на оба WAN

Самый простой и читаемый вариант — masquerade по списку интерфейсов WAN:

/ip firewall nat
add chain=srcnat out-interface-list=WAN action=masquerade comment="NAT to both WAN"

Failover “как надо”: рекурсивные маршруты (чтобы ловить падение интернета, а не только линка)

Если использовать только check-gateway на default route через шлюз провайдера, можно не поймать ситуацию, когда “шлюз пингуется, а интернет умер дальше”. Для офиса это как раз самый неприятный сценарий.

Поэтому делаем так:

  • Добавляем маршрут до “тестового IP” через реальный gateway каждого провайдера с check-gateway=ping.
  • Делаем default route рекурсивно через этот “тестовый IP”.

В качестве тестовых IP обычно берут 1.1.1.1 (Cloudflare) и 8.8.8.8 (Google) или любые стабильные адреса. Важно: это должны быть публичные адреса, которые пингуются и доступны “почти всегда”.

# Подставьте GW1/GW2 — шлюзы провайдеров (next-hop), например 10.10.10.1 и 10.20.20.1
# Если WAN получают адрес по DHCP и шлюзы динамические — шлюз можно посмотреть в /ip route или DHCP client.
# В простом офисе часто удобнее закрепить статику на WAN и явно задать GW.

# Тестовые хосты:
# WAN1-test = 1.1.1.1
# WAN2-test = 8.8.8.8

/ip route
add dst-address=1.1.1.1 gateway=GW1 check-gateway=ping scope=10 comment="WAN1 monitor (recursive)"
add dst-address=8.8.8.8 gateway=GW2 check-gateway=ping scope=10 comment="WAN2 monitor (recursive)"

# Основные дефолтные маршруты (общий интернет):
# distance задаёт приоритет: WAN1 основной, WAN2 резервный (или одинаковые — если хотите ECMP без PCC)
add dst-address=0.0.0.0/0 gateway=1.1.1.1 distance=1 target-scope=10 comment="Default via WAN1 (recursive)"
add dst-address=0.0.0.0/0 gateway=8.8.8.8 distance=2 target-scope=10 comment="Default via WAN2 (recursive)"

На этом этапе у вас уже будет “автоматическое переключение” (если WAN1 реально теряет интернет — маршрут через 1.1.1.1 станет невалидным, и трафик уйдёт через WAN2).

Балансировка PCC + симметрия: mangle и policy routing

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

Ключевые принципы:

  • Маркируем connection для исходящих соединений из LAN.
  • Далее по connection-mark ставим routing-mark.
  • Добавляем маршруты с routing-mark (policy routes) — “куда идти трафику с этой меткой”.
  • Отдельно помечаем входящие соединения с каждого WAN — чтобы ответы уходили тем же каналом.

Важно про FastTrack: FastTrack может обходить часть цепочек, из-за чего PCC/маркировки начинают вести себя непредсказуемо. Для стабильности в офисной схеме лучше не использовать FastTrack (или настроить очень аккуратно). Ниже я исхожу из того, что FastTrack отключён.

# Если у вас есть правило fasttrack, временно отключите его:
# /ip firewall filter disable [find where action=fasttrack-connection]

# 1) Входящие соединения: помечаем connection по WAN-интерфейсу
/ip firewall mangle
add chain=prerouting in-interface=ether1 connection-mark=no-mark action=mark-connection new-connection-mark=conn_wan1 passthrough=yes comment="IN: mark connections from WAN1"
add chain=prerouting in-interface=ether2 connection-mark=no-mark action=mark-connection new-connection-mark=conn_wan2 passthrough=yes comment="IN: mark connections from WAN2"

# 2) Исходящие новые соединения из LAN: PCC 50/50
# per-connection-classifier=both-addresses-and-ports — хороший компромисс для офиса:
# - распределяет ровнее
# - одно соединение не прыгает между WAN
add chain=prerouting in-interface=br-lan connection-mark=no-mark dst-address-type=!local \
    per-connection-classifier=both-addresses-and-ports:2/0 action=mark-connection new-connection-mark=conn_wan1 passthrough=yes comment="PCC: new conns to WAN1"
add chain=prerouting in-interface=br-lan connection-mark=no-mark dst-address-type=!local \
    per-connection-classifier=both-addresses-and-ports:2/1 action=mark-connection new-connection-mark=conn_wan2 passthrough=yes comment="PCC: new conns to WAN2"

# 3) По connection-mark задаём routing-mark (policy routing)
/ip firewall mangle
add chain=prerouting in-interface=br-lan connection-mark=conn_wan1 action=mark-routing new-routing-mark=to_wan1 passthrough=no comment="Route-mark LAN via WAN1"
add chain=prerouting in-interface=br-lan connection-mark=conn_wan2 action=mark-routing new-routing-mark=to_wan2 passthrough=no comment="Route-mark LAN via WAN2"

# 4) Ответы на входящие соединения (чтобы не было асимметрии):
# Маркируем роутинг для трафика, который router сам отправляет в ответ (chain=output)
add chain=output connection-mark=conn_wan1 action=mark-routing new-routing-mark=to_wan1 passthrough=no comment="Router replies via WAN1"
add chain=output connection-mark=conn_wan2 action=mark-routing new-routing-mark=to_wan2 passthrough=no comment="Router replies via WAN2"

Теперь добавляем policy-маршруты для меток to_wan1 и to_wan2. Здесь мы используем те же “рекурсивные” шлюзы, чтобы failover работал и внутри policy routing (а не только для “обычного” трафика).

/ip route
add dst-address=0.0.0.0/0 gateway=1.1.1.1 routing-mark=to_wan1 distance=1 target-scope=10 comment="Policy default: to_wan1 (recursive)"
add dst-address=0.0.0.0/0 gateway=8.8.8.8 routing-mark=to_wan2 distance=1 target-scope=10 comment="Policy default: to_wan2 (recursive)"

Что мы получили:

  • Каждое новое соединение из LAN распределяется между WAN1/WAN2 и закрепляется (PCC).
  • Ответы на входящие соединения выходят через тот же WAN, откуда пришли (симметрия).
  • Если у провайдера “умирает интернет”, рекурсивная проверка выключит соответствующий путь, и трафик уйдёт через живой WAN (failover).

Чтобы “не ломались сервисы”: исключения и “липкие” направления

Даже при корректном PCC иногда полезно закрепить некоторые вещи за одним WAN:

  • банки/гос-сервисы и любые ресурсы, которые строго реагируют на смену IP;
  • удалённые VPN-туннели (если есть);
  • IP-телефония/провайдер SIP (часто любит стабильность исходящего адреса).

Делается это через address-list и правило mangle выше PCC: если dst в списке — всегда WAN1 (или WAN2).

# Пример: всё к определённым адресам/подсетям — всегда через WAN1
/ip firewall address-list
add list=sticky_wan1 address=203.0.113.0/24 comment="Example: critical subnet"
add list=sticky_wan1 address=198.51.100.10 comment="Example: critical host"

# Правило ДО PCC (важно!)
/ip firewall mangle
add chain=prerouting in-interface=br-lan dst-address-list=sticky_wan1 connection-mark=no-mark \
    action=mark-connection new-connection-mark=conn_wan1 passthrough=yes comment="Sticky: force WAN1 for critical destinations"

Для доменных имён (например, “crm.example.com”) можно использовать:

  • ручное обновление IP в address-list (если IP статичен),
  • или скрипт/резолв (если хочется автоматизации),
  • или проще: закрепить критичные сервисы за одним провайдером, если это приемлемо организационно.

Минимальный firewall (чтобы не стало хуже)

Если firewall уже настроен — не ломайте “боевую” политику. Ниже — базовый каркас (упрощённый), который обычно есть в офисе:

/ip firewall filter
add chain=input action=accept connection-state=established,related comment="Allow established/related to router"
add chain=input action=drop connection-state=invalid comment="Drop invalid"
add chain=input action=accept in-interface-list=LAN comment="Allow management from LAN"
add chain=input action=drop in-interface-list=WAN comment="Drop input from WAN (router protection)"

Повторюсь: FastTrack лучше отключить, если цель — предсказуемая политика маршрутизации с PCC.

Проверка: как убедиться, что всё работает

  • Проверка распределения: откройте несколько разных сайтов/видео/загрузок с разных ПК — суммарно WAN должны нагружаться.
  • Проверка “липкости”: в /ip firewall connection смотрите, что соединения получают conn_wan1 / conn_wan2 и не меняются в процессе.
  • Failover: отключите кабель WAN1 или “уроните” провайдера (если есть возможность) — интернет должен остаться через WAN2. Потом верните WAN1 — трафик начнёт снова распределяться.

Полезные команды/наблюдение:

# Смотреть маршруты и их статус
/ip route print

# Смотреть маркировку соединений
/ip firewall connection print where connection-mark~"conn_wan"

# Счётчики правил mangle (видно, что правила реально работают)
/ip firewall mangle print stats

Примечания по RouterOS v7

В RouterOS v7 появилась отдельная подсистема маршрутизации (routing tables, routing rules). Логику выше можно реализовать “красивее” через таблицы вместо routing-mark. Но даже если вы оставите вариант с mark-routing, в большинстве офисных сценариев он работает стабильно — главное, чтобы схема была последовательной и проверка доступности провайдера была корректной.

Частые вопросы

Почему одна загрузка не ускоряется в 2 раза?

PCC распределяет соединения. Один поток (например, один HTTP-download) закрепится за одним WAN. Суммарный выигрыш появляется, когда одновременно много разных соединений (пользователи, вкладки, звонки, обновления, облака).

Почему важна симметрия маршрутизации?

Если пакет вышел через WAN1, а ответ ушёл через WAN2 (или наоборот), часть сервисов посчитает это подозрительным: сессии рвутся, SSL/банки/авторизации “капризничают”, VPN может падать. Маркировка входящих соединений и корректные policy-маршруты это предотвращают.

Нужно ли что-то делать с входящими сервисами (порт-форвардинг)?

Если в офисе есть входящие сервисы (например, удалённый доступ на сервер), то для каждого WAN обычно делают отдельные правила dst-nat и понимают, по какому провайдеру люди заходят. При failover “входящий” доступ без внешней динамики (BGP/мульти-WAN с одним IP) автоматически не переедет — это отдельная тема.

Вывод

На RB952UA (и вообще на MikroTik) можно сделать двухпровайдерную схему, которая одновременно даёт и балансировку, и автоматическое переключение, и предсказуемое поведение сервисов. Ключ — распределять соединения (PCC), фиксировать маршрутизацию метками и проверять доступность интернета рекурсивно, а не только “линк поднят/упал”.