Короткий ответ
Два маршрута 0.0.0.0/0 с одинаковым distance — ECMP. RouterOS при включённом connection tracking балансирует по соединениям, не по пакетам внутри TCP. Пер-пакетный баланс на NAT-файрволе даёт асимметрию и «сайты через раз». Неравномерные каналы (100 Мбит + 20 Мбит) ECMP не взвесит справедливо — тяжёлые потоки случайно сядут на тонкий WAN.
Если нужен резерв, а не баланс — разный distance (failover). Если нужен «этот VLAN на ISP2» — policy routing, не второй default.
Симптомы и как отличить
Оба WAN в /ip route print с A и одним distance. Канал1 90%, канал2 5%. Или HTTPS зависает, ping стабилен.
| Цель | Инструмент |
|---|---|
| Резерв | distance 1/2 |
| Баланс исходящих сессий | ECMP или PCC |
| Жёсткая привязка | mangle + table |
| Симметричный ответ на входящие | mark по in-interface |
Возможные причины
- Путают failover и ECMP.
- NAT только на одном интерфейсе: половина сессий без srcnat.
- FastTrack + ECMP: редкие сюрпризы с marks.
- PCC настроен, ECMP default всё ещё есть — двойной баланс.
- Входящий dstnat на WAN1, ответ ушёл в WAN2.
- Бандлы разной стоимости без весов (в ROS простые равные ECMP).
Диагностика
/ip route print detail
/ip firewall nat print
/ip firewall connection print count-only
/interface print statsДва dst-address=0.0.0.0/0 с distance=1 gateway разные — ECMP. Снимите stats RX/TX за интервал теста.
Проверка асимметрии: с ПК HTTPS, в connections смотрите reply-dst-address / интерфейсы. Ответ не тем WAN — вот почему «ломается».
PCC:
/ip firewall mangle print where per-connection-classifierЕсли PCC есть и ECMP есть — решите, кто главный.
Решение
Сценарий A. Хотели failover, получили ECMP
Поставьте distance=2 на backup. Второй перестанет быть active, пока жив primary.
Сценарий B. Хотели баланс, HTTPS сыпется
- Masquerade на оба WAN (
out-interface-list=WAN). - Оставьте tracking включённым (не per-packet).
- Не балансируйте в ECMP линки с разным NAT-поведением (один публичный, второй CGNAT) без понимания входящих.
Сценарий C. PCC вместо голого ECMP
PCC в mangle (оба адреса и порты) + mark-routing в две таблицы с default. Это контролируемее ECMP equal-cost: можно исключить сети, не класть UDP DNS в баланс и т.д. Не копируйте «PCC 2 линии» скрипты целиком: вычищайте FastTrack-исключения и LAN-to-LAN (dst-address=192.168.88.0/24 не маркировать).
Типичный classifier:
/ip firewall mangle
add chain=prerouting dst-address-type=!local in-interface-list=LAN per-connection-classifier=both-addresses-and-ports:2/0 action=mark-connection new-connection-mark=wan1
add chain=prerouting dst-address-type=!local in-interface-list=LAN per-connection-classifier=both-addresses-and-ports:2/1 action=mark-connection new-connection-mark=wan2Дальше mark-routing и две FIB-таблицы, как в policy routing.
Сценарий D. Входящие на оба белых IP
connection-mark на prerouting in-interface=ether1 / ether2, ответные mark-routing в ту же сторону. Иначе ECMP outgoing сломает dstnat.
Как проверить, что проблема устранена
Длительные загрузки идут целиком одним WAN (ожидаемо). Много мелких сессий распределяются. Сайты стабильны. Для failover-сценария второй default не active одновременно. VoIP двусторонний.
Сравните 203.0.113.10 vs второй публичный на what-is-my-ip с двух ПК — могут отличаться при балансе; это норма, если оба NAT верны.
Если не помогло
- Один провайдер режет TTL/P2P — «неравномерно» не лечится ECMP.
- Нужна агрегация 2×канал как один IP — это не ECMP, а bonding/провайдерский MLPPP, на независимых ISP невозможно.
- VPN хаб видит смену IP сессии — исключите VPN из баланса (FastTrack/VPN + policy).
Профилактика
- Явная цель: failover XOR balance XOR policy.
- Оба WAN в NAT list.
- Мониторинг по интерфейсам и по качеству, не только сумме.
- Не держать detect-internet вместе с ручным ECMP без понимания.
Неравные каналы, sticky IP и что не умеет простой ECMP
Два default с distance=1 делят новые соединения, не байты внутри слона. Поток на 400 Мбит сядет на один WAN целиком — график «неравный» при 500+100 Мбит каналах неизбежен. Weighted ECMP как у крупных маршрутизаторов на SOHO не ждите; для 70/30 берите PCC с неравным числом корзин и две таблицы, затем измерьте, а не верьте формуле.
Банки и личные кабинеты с привязкой к IP страдают от смены 203.0.113.10 на второй адрес. Такие хосты вынесите в address-list и policy routing на один ISP, остальное пусть балансируется.
UDP 500/4500 и WG listen-port исключите из PCC: иначе IKE/handshake прыгает между WAN и туннель «моргает». DNS UDP тоже лучше sticky или вообще через кэш роутера, чтобы не ловить странные SERVFAIL.
Входящий dstnat на WAN1 при ECMP исходящих без connection-mark по in-interface даёт односторонний TCP. Сначала нарисуйте, нужны ли входящие на оба белых IP. Если нет — не балансируйте, сделайте failover с разным distance.
FAQ
ROS 7 умеет weighted ECMP?
Не рассчитывайте на полноценные веса как у Cisco на SOHO. Для неравных каналов лучше policy/PCC с долей classifier (2/0, 2/1 неравномерно не сделать идеально; берут 3/0 3/1 3/2 и два mark на толстый). Проверяйте фактический match.
Per-packet load balancing включить где?
В классическом ROS для IP routing при tracking это не ваш друг за NAT. Не ищите «галочку per-packet» как решение HTTPS.
Почему ping 1.1.1.1 всегда ISP1?
Мало потоков. Один dst+src ICMP может липнуть. Смотрите много TCP.
Нужен ли same NAT IP?
Невозможен с двумя ISP. Баланс = два внешних адреса. Сессии к банкам с привязкой IP будут страдать — таких хостов выносите в policy на один WAN.
ECMP и WireGuard endpoint?
Endpoint должен быть стабилен. Не балансируйте пакеты IKE/WG по двум WAN без sticky. Исключайте UDP 13231/500/4500 из PCC.
Почему after failover с ECMP часть сессий «залипла» в мёртвый WAN?
Conntrack помнит выход. Пока соединение established, ECMP новое не перекладывает. После падения gateway нужен check-gateway, чтобы маршрут исчез, плюс разрыв старых connection или ожидание timeout. Чистый failover с distance 1/2 предсказуемее «ECMP + надежда». Не равняйте два default, если хотели резерв. После возврата primary старые сессии могут остаться на backup до естественного закрытия — для NAT это смена внешнего IP.