MTCNA

в Городе Санкт-Петербург

Первый день 2019-05-27

Записаться

RouterOS - MultiWan

Я настоятельно рекомендую сначала прочитать, далее вникнуть, потом понять и только после того как у вас вся картина будет нарисована в голове приступить к настройке.

Настройка нескольких провайдеров в RouterOS.

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

Если оператор нам выдал ip адрес 1.1.1.2, то мы должны обеспечить выход через этого провайдера именно с таким ip адресом, а не с каким либо другим.

Не будем ходить вокруг да около, а сразу приступим к настройке.

Для начала определим вводные данные.

Первый провайдер:

  • Интерфейс ether1
  • IP:88.88.88.2/29 Gateway: 88.88.88.1, а также данный провайдер отдаёт ещё один префикс на том же интерфейсе IP:99.99.99.2/24 Gateway: 99.99.99.1
  • DSN сервера 2.2.2.2 и 3.3.3.2

Второй провайдер:

  • Интерфейс ether2
  • IP:44.44.44.2/29 Gateway: 44.44.44.1
  • DSN сервера 7.7.7.2 и 6.6.6.2

Локальная сеть:

  • Ether3 - IP:172.20.17.1/24 - локальная сеть компьютеров
  • Ether4 - IP:172.20.18.1/24 - локальная сеть для серверов

Настройка IP адресации

Настроим IP адреса, согласно выданным настройкам от провайдеров.

/ip address
add interface=ether1 address=88.88.88.2/29 comment="ISP1"
add interface=ether1 address=99.99.99.2/24 comment="ISP1"
add interface=ether2 address=44.44.44.2/24 comment="ISP2"
add interface=ether3 address=172.20.17.1/24 comment="Local Network Computers"
add interface=ether4 address=172.20.18.1/24 comment="Local Network Servers"

Я думаю бессмысленно как-то дополнять данные настройки.

Маркировка соединений от провайдера

Вы наверное помните, а если и нет, то стоит напомнить, что любой пакет который приходит на маршрутизатор попадает в цепочку prerouting и не важно куда он дальше попадёт forward или Input.

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

С начала настроим, а далее разберём что сделали.

/ip firewall mangle
add chain=prerouting in-interface=ether1 dst-address=88.88.88.0/29 connection-state=new action=mark-connection new-connection-mark=Next-Hop/88.88.88.1 passthrough=no
add chain=prerouting in-interface=ether1 dst-address=99.99.99.0/24 connection-state=new action=mark-connection new-connection-mark=Next-Hop/99.99.99.1 passthrough=no
add chain=prerouting in-interface=ether2 dst-address=44.44.44.0/24 connection-state=new action=mark-connection new-connection-mark=Next-Hop/44.44.44.1 passthrough=no

Разберём только первое правило, все остальные по аналогии.

Если пакет приходит с интерфейса ether1 и адрес назначения лежит в сети 88.88.88.0/29, и такой пакет создал соединение, то маркируем соединение маркой Next-Hop/88.88.88.1.

Небольшие пояснения:

88.88.88.0/29 - почему сеть, а не IP? Если вы будете делать правила для каждого IP адреса, количество правил будет расти, а смысл будет тот же самый.

connection-state=new - нет смысла пытаться маркировать соединения которые уже установлены, как вы помните, new - это пакет который создал соединение, т.е он только один, а в случае со всеми пакетами routeros будет каждый раз пытаться маркировать соединение, которое уже и так может иметь маркировку.

Next-Hop/99.99.99.1 - почему именно так? Как вы помните, наша главная задача отправить трафик через тот же самый шлюз, через который трафик пришёл, а мы таким названием себе явно напоминаем, какой шлюз будет использоваться для выхода в сторону провайдера. Мы бы могли использовать что-нибудь вроде ISP1, но так как у нас первый провайдер даёт два префикса в одном и том же интерфейсе, мы должны трафик который приходит на разные префиксы каким нибудь образом разделить.

И так это наша заготовка, далее мы начнём работать непосредственно с логикой.

С этого момента, весть трафик который придёт со стороны провайдера будет промаринован, а далее бы будет оперировать данной маркировкой.

Доступ к маршрутизатору

Первая задача, которую нам необходимо решить, это организовать возможность управления маршрутизатором через разных провайдеров. Мы должны иметь возможность подключится по любому IP адресу по ssh, winbox, а также если вы будете использовать RouterOS в случае VPN сервера. В общем организовать правильный выход пакетов, которые будет отправлены с маршрутизатора в ответ на входящие соединения.

Для начала нам надо организовать правильные таблицы маршрутизации. В одной таблице маршрутизации не могут быть одновременно два одинаковых активных маршрута, если маршруты одинаковы, то приоритет выбирается из значения distance. Для того чтобы можно было использовать несколько одинаковых маршрутов в RouterOS есть возможность создавать альтернативные (именованные) таблицы маршрутизации.

Создадим данные таблицы.

/ip route> 
add dst-address=0.0.0.0/0 gateway=88.88.88.1 routing-mark=Next-Hop/88.88.88.1
add dst-address=0.0.0.0/0 gateway=99.99.99.1 routing-mark=Next-Hop/99.99.99.1                
add dst-address=0.0.0.0/0 gateway=44.44.44.1 routing-mark=Next-Hop/44.44.44.1

Разберём:

dst-address=0.0.0.0/0 - обычный маршрут по умолчанию, не более чем.

gateway=88.88.88.1 - шлюз, обратите внимание на то, что нам первый провайдер даёт два префикса с разными шлюзами, и поэтому мы создаём три маршрута, для нас по факту не два провайдера, а три.

routing-mark=Next-Hop/88.88.88.1 - это и есть именованная таблица маршрутизации. Она может иметь любое имя, какое вам удобнее, лично моё мнение, такое именование удобно, записывать в названии таблицы шлюз через который будет отправлен пакет в случае если он будет использовать данный маршрут. Имена маркировок соединений и маршрутов просто совпали и могут быть совершенно разные.

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

/ip firewall mangle> add routing-<tab><tab>
routing-mark  routing-table

Дело в том, что routing-mark это маркировка, когда вы своими руками с помощью mangle назначили на пакет маркировку, а routing-table это то через какую таблицы маршрутизации вышел пакет.

Если маршрутизатор не найдёт подходящего маршрута в именованной таблицы маршрутизации, маршрутизатор продолжит поиск подходящего маршрута в таблице по умолчанию main и такой пакет можно будет отфильтровать например так routing-mark=custommark routing-table=main. Нам же такое поведение не нужно, если по какой-то причине маршрут не будет найден, пакет должен умереть на маршрутизаторе, а отправлять через другого провайдера нет ни какого смысла.

Нам необходимо переопределить данное поведение.

/ip route rule> 
add routing-mark=Next-Hop/88.88.88.1 action=lookup-only-in-table table=Next-Hop/88.88.88.1
add routing-mark=Next-Hop/99.99.99.1 action=lookup-only-in-table table=Next-Hop/99.99.99.1 
add routing-mark=Next-Hop/44.44.44.1 action=lookup-only-in-table table=Next-Hop/44.44.44.1 

Т.е марка и таблица по факту это одно и тоже, пакет который имеет определённую routing-mark пытается найти маршрут в таблице с таким же именем.

Осталась самая малость, это отправить в нужную марку необходимый трафик.

/ip firewall mangle> 
add chain=output connection-mark=Next-Hop/88.88.88.1 action=mark-routing new-routing-mark=Next-Hop/88.88.88.1 passthrough=no
add chain=output connection-mark=Next-Hop/99.99.99.1 action=mark-routing new-routing-mark=Next-Hop/99.99.99.1 passthrough=no
add chain=output connection-mark=Next-Hop/44.44.44.1 action=mark-routing new-routing-mark=Next-Hop/44.44.44.1 passthrough=no

Цепочка output, так как мы работаем только с трафиком, который генерирует в ответ на запрос соединения. Выбрали пакеты принадлежащие только определённым соединениям и отправили в именованную таблицу.

Вроде бы всё хорошо и всё должно работать но это не так, в RouterOS есть один маленький нюанс, который необходимо помнить и учитывать. Дело в том, что маршрутизатор прежде чем отправить пакет в цепочку output, смотрит в таблицу маршрутизации и ищет для адреса назначения подходящий маршрут в таблице main, есть всего три типа сервисов, которые умеют работать вне данного поведения, это ping, traceroute и ospf - это необходимо для работы в VRF.

На данный момент у нас нет маршрута по умолчанию в таблице маршрутизации main, встаёт вопрос, какой шлюз указать в качестве маршрута по умолчанию, если мы укажем первого провайдера, то в случае падения интерфейса мы останемся у разбитого корыта, мы может сразу указать три шлюза и с помощью distance указать приоритеты, но тогда мы должны помнить про данную настройку и случае замены провайдера или какого-либо изменения править конфигурацию и в этом моменте, а там то всего нужно пройти выбор маршрута и далее уже переопределить направление, т.е по факту это логический кейс.

Все интерфейсы имеют способность падать, есть один интерфейс, который всегда находится в состоянии UP, но в RouterOS использовать его в конфигурации не представляется возможным - это Loopback.

В RouterOS данный интерфейс можно заменить пустым bridge.

/interface bridge> add name=Br-Loopback

Я часто раскалываю на курсах, почему именно такое название, а не просто Loopback, возможно в ближайшем будущем в RouterOS будет добавлено поддержка Loopback интерфейса и если разрабочики заложат такое-же название то при обновлении версии RouterOS могут возникнуть проблемы.

А теперь создадим маршрут в таблице main, который необходим для преодоления выбора маршрута и попадания пакета в цепочку output.

/ip route> add dst-address=0.0.0.0/0 gateway=Br-Loopback distance=254

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

Напоминаю, что дистанция 255 это административная дистанция, которая явно указывает, что данный маршрут мёртв и не участвует в маршрутизации.

Всё, на данном этапе вы должны иметь возможность подключаться к маршрутизатору по любому IP адресу через любого провайдера одновременно, можете пинговать и делать всякие другие непотребства с внешними IP адресами.

Выход с маршрутизатора

Хоть и по сути мы сделали уже много, но у нас ещё несколько кейсов впереди. Теперь мы должны сделать таким образом, чтобы пакеты которые генерирует сам маршрутизатор (не в ответ), уходили через нужного провайдера и шлюза.

Когда вы пингуете с маршрутизатора, строите PPP* или IP туннели с самого маршрутизатора или dns запросы отправляете с самого маршрутизатора. Разница с прошлым кейсом в том, что мы отправляли пакет по уже установленному соединению, а здесь пакет улетает с маршрутизатора и соединение не имеет маркировки.

Здесь будет значительно проще.

/ip firewall mangle> 
add chain=output src-address=88.88.88.0/29 action=mark-routing new-routing-mark=Next-Hop/88.88.88.1 passthrough=no
add chain=output src-address=99.99.99.0/24 action=mark-routing new-routing-mark=Next-Hop/99.99.99.1 passthrough=no
add chain=output src-address=44.44.44.0/24 action=mark-routing new-routing-mark=Next-Hop/44.44.44.1 passthrough=no

Весь трафик который уходит с маршрутизатора, и имеет IP адрес который попадает под префикс, будет отправлен в именованную таблицу маршрутизации.

Всё, теперь вы можете строить туннели и у вас всё будет работать, но только в том случае если явно указан IP адрес например в Ipsec или gre, ip туннели и прочее, там где явно можно указать Source адрес. А что делать с сервисами, где нельзя указать явно IP адрес источника? Ответ на этот вопрос кроется в таблице маршрутизации. Параметр pref-src отвечает за то, какой IP адрес будет выбран если он явно не задан.

Ещё раз для понимания, у нас есть два вариант развитая сюжета, если IP адрес источника явно указан и тогда нам нечего не грозит и всё замечательно работает. Второй вариант когда IP адрес явно не задан, например вы подминаете l2tp-client у нас нет возможности указать source адрес, но ведь адрес назначения есть в любом случае. Тогда маршрутизатор поступает следующим образом он находи маршрут из таблице маршрутизации main смотрит какой указан pref-src и использует данный ip адрес как адрес источника.

Вы помните что мы создавали фиктивный маршрут.

/ip route> add dst-address=0.0.0.0/0 gateway=Br-Loopback distance=254

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

/ip route> 
set pref-src=88.88.88.2 [ find gateway=Br-Loopback dst-address=0.0.0.0/0 ]

Выбор IP адреса зависит только от вас, выбирайте тот адрес которые считает менее загруженным.

На этом этапе всё, теперь вы можете строить различные туннели и устанавливать соединения не только указывая явно source адрес.

Доступ за НАТ

172.20.18.2 - это exchange сервер, мы должны обеспечить доступность 25,80,443 портов через каждого провайдера.

НАТ делаем как обычно без всяких излишеств.

/ip firewall nat> 
add chain=dstnat in-interface=ether1 dst-address=88.88.88.2 protocol=tcp dst-port=25,80,443 action=dst-nat to-addresses=172.20.18.2
add chain=dstnat in-interface=ether1 dst-address=99.99.99.2 protocol=tcp dst-port=25,80,443 action=dst-nat to-addresses=172.20.18.2
add chain=dstnat in-interface=ether2 dst-address=44.44.44.2 protocol=tcp dst-port=25,80,443 action=dst-nat to-addresses=172.20.18.2

А теперь давайте вспомним, то что мы делали самым первым правилом в mangle мы промаркировали все соединения которые приходят через всех провайдеров! Данная маркировка нам опять поможет.

Нам необходимо отфильтровать весь трафик который идёт из локальной сети и отправить в том направлении к маркировки которого соединение имеет отношение.

Попробуем логически по шагам описать то, как это будет работать. Опишем для одного провайдера, для остальным по тоже схеме.

  1. Когда пакет придёт на IP адрес 88.88.88.2 мы промаркировали соединение которому принадлежит пакет.
  2. Далее в NAT мы изменили адрес назначения и маршрутизатор отправит его до сервера.
  3. Естественно сервер в ответ отправит пакет как минимум syn,ack так как данный пакет принадлежит уже существующему соединению, мы по имени соединению отправим данный пакет в именованную таблицу маршрутизации.

НАТ уже сделали, дело осталось за малым, найти трафик который приходит от сервера.

/ip firewall mangle> 
add chain=prerouting connection-mark=Next-Hop/88.88.88.1 in-interface=!ether1 action=mark-routing new-routing-mark=Next-Hop/88.88.88.1 passthrough=no
add chain=prerouting connection-mark=Next-Hop/99.99.99.1 in-interface=!ether1 action=mark-routing new-routing-mark=Next-Hop/99.99.99.1 passthrough=no 
add chain=prerouting connection-mark=Next-Hop/44.44.44.1 in-interface=!ether2 action=mark-routing new-routing-mark=Next-Hop/44.44.44.1 passthrough=no 

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

Наверное многие спросят, а почему указывается не интерфейс ether1, а не взять и указать явно локальный интерфейс например ether4.

Мы с вами делаем универсальную конфигурацию, если явно указать какой-либо другой интерфейс, значит в случае если у нас будет ещё один NAT, который пойдёт в другой порт, нам необходимо будет добавлять ещё одно аналогичное правило, но уже с другим интерфейсом. А ведь мы можем даже завернуть трафик с помощью NAT вообще на внешние сервера например 1.1.1.1, и что тогда? Единственный интерфейс откуда в цепочке prerouting мы не должны ожидать данный трафик это трафик с самого провайдера и причём именно с того с которого он пришёл.

Всё работает, теперь вы можете подключаться в своему серверу по любому IP адресу. Создайте DNS A запись RR и укажите все три внешних IP адреса и всегда ссылайте на данную запись.

Например: mail.mycompany.ru

mail.mycompany.ru A 88.88.88.2
mail.mycompany.ru A 99.99.99.2
mail.mycompany.ru A 44.44.44.2

Ещё каких-то лет 7 назад, DNS RR работал не очень хорошо, в плане того, что приложения зачастую использовали только первый IP адрес, сейчас все изменилось и многие приложения в случае если не смогут подключиться по одному адресу будут пытаться подключаться по другому и так далее...

А также source NAT?

Промелькнула такая мысль в голове? Ведь когда пакет от сервера будет уходить через маршрутизатор, нам надо будет подменить его src адрес, на адрес на который он шёл в самом начале. Но мы нечего не сделали для этого.

Нам делать нечего не нужно, если вспомнить то в правило NAT попадает только самый первый пакет, тот на основании которого было создано соединение new, именно поэтому обычно вы видите небольшие значения в счётчиках правила NAT.

Обратное преобразования NAT произойдёт автоматически, давайте взглянем на запись в conntrack.

/ip firewall connection> print detail where dstnat     
Flags: E - expected, S - seen-reply, A - assured, C - confirmed, D - dying, F - fasttrack, s - srcnat, d - dstnat 
 0  SAC  d  protocol=tcp src-address=5.19.245.3:57839 dst-address=88.88.88.2:80 reply-src-address=172.20.18.2:80 reply-dst-address=5.19.245.3:57839 tcp-state=established timeout=23h56m33s orig-packets=191 orig-bytes=19 352 orig-fasttrack-packets=0 orig-fasttrack-bytes=0 repl-packets=200 repl-bytes=32 631 repl-fasttrack-packets=0 repl-fasttrack-bytes=0 orig-rate=0bps repl-rate=0bps 

Давайте уберём из вывода лишнее, чтобы оно нам не мешало.

 0  SAC  protocol=tcp src-address=5.19.245.3:57839 dst-address=88.88.88.2:80 reply-src-address=172.20.18.2:80 reply-dst-address=5.19.245.3:57839 

И так когда пакет попал на маршрутизатор и соединение было "только только" создано, соединение имело такой вид

 0  SAC src-address=5.19.245.3:57839 dst-address=88.88.88.2:80

После того как произошла процедура dst NAT. Маршрутизатор добавил флаги и самое главное на какой адрес изменяется IP адрес во всех пакетах в данном соединении.

 0  SAC d src-address=5.19.245.3:57839 dst-address=88.88.88.2:80 reply-src-address=172.20.18.2:80 

Когда пакет уходил с маршрутизатора в цепочки postrouting работает процедура src NAT, но у нас нет правил src NAT, оставили значение исходное.

 0  SAC d src-address=5.19.245.3:57839 dst-address=88.88.88.2:80 reply-src-address=172.20.18.2:80 reply-dst-address=5.19.245.3:57839 

Обратите внимание, что все данные этапы были сделаны на момент прохождения только первого пакета.

Теперь если пакет приходит на маршрутизатор и у него в заголовках src-address=5.19.245.3:57839 dst-address=88.88.88.2:80 dst-address изменится на 172.20.18.2:80.

Если пакет приходит на маршрутизатора с адресами в заголовках src-address=172.20.18.2:80 dst-address=5.19.245.3:57839 src адрес изменится на 88.88.88.2:80.

Тем самым src NAT на данном этапе работает автоматически на основании правил dst-NAT.

Выпустить с правильного адреса

Часто бывают ситуации, что вам необходимо жёстко определить, чтобы какой-то внутренний хост выходил, только с определённого IP адреса.

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

Сначала настроим адрес листы в которые будем добавлять внутренние адреса хостов, которые необходимо отправить через нужного провайдера и с определённого IP адреса.

/ip firewall address-list>
add list=via/88.88.88.2 address=0.0.0.1
add list=via/99.99.99.2 address=0.0.0.1
add list=via/44.44.44.2 address=0.0.0.1

Адрес 0.0.0.1 для того чтобы создать лист, но не привязывать к реальному адресу.

Название листа явно говорит, о том на какой IP адрес необходимо изменить адрес источника.

Для реализации данного кейса нам необходимо учитывать особенность работы RouterOS.

Дело в том, что для трафика который проходит через маршрутизатор мы можем изменить таблицу маршрутизации только в цепочке prerouting, и естественно интерфейс выходы ещё нам неизвестен, он будет известен только в цепочке forward.

И мы не можем просто взять и завернуть весь трафик от внутренного хоста в определённого провайдера, так как у нас есть ещё и локальная сеть.

Допустим если мы добавим хост 172.20.17.100 и скажем что весь трафик направить в первого провайдера, то что будет с трафиком который идёт на хост 172.20.18.2? Естественно он будет направлен в первый провайдер.

Для решении данной задачи нам помогут BOGON сети, это список сетей, которые некогда не должны использоваться для публикации между public AS в проколе BGP, другими словами это все те сети которые используются исключительно в локальных целях.

Создадим адрес лист с BOGON сетями.

/ip firewall address-list
add list="BOGONS" address=0.0.0.0/8
add list="BOGONS" address=10.0.0.0/8
add list="BOGONS" address=100.64.0.0/10
add list="BOGONS" address=127.0.0.0/8
add list="BOGONS" address=169.254.0.0/16
add list="BOGONS" address=172.16.0.0/12
add list="BOGONS" address=192.0.0.0/24
add list="BOGONS" address=192.0.2.0/24
add list="BOGONS" address=192.168.0.0/16
add list="BOGONS" address=198.18.0.0/15
add list="BOGONS" address=198.51.100.0/24
add list="BOGONS" address=203.0.113.0/24
add list="BOGONS" address=224.0.0.0/3

А далее создадим правила для того чтобы выпустить хосты с определённого IP адреса.

/ip firewall mangle> 
add chain=prerouting src-address-list=via/88.88.88.2 dst-address-list=!BOGONS action=mark-routing new-routing-mark=Next-Hop/88.88.88.1 passthrough=no
add chain=prerouting src-address-list=via/99.99.99.2 dst-address-list=!BOGONS action=mark-routing new-routing-mark=Next-Hop/99.99.99.1 passthrough=no
add chain=prerouting src-address-list=via/44.44.44.2 dst-address-list=!BOGONS action=mark-routing new-routing-mark=Next-Hop/44.44.44.1 passthrough=no

Если пакет в адресе источника находится адрес который перечислен в адрес листе и при этом адрес назначения не попадает под богон листы (т.е трафик в интернет), отправить в именованную таблицу.

И последний нюанс это настроить NAT.

/ip firewall nat> 
add chain=srcnat routing-mark=Next-Hop/88.88.88.1 src-address-list=via/88.88.88.2 action=src-nat to-addresses=88.88.88.2
add chain=srcnat routing-mark=Next-Hop/99.99.99.1 src-address-list=via/99.99.99.2 action=src-nat to-addresses=99.99.99.2
add chain=srcnat routing-mark=Next-Hop/44.44.44.1 src-address-list=via/44.44.44.2 action=src-nat to-addresses=44.44.44.2

Обратите внимания, что не весь трафик, а только тот который находится в определённом маркированном маршруте, это необходимо чтобы трафик между локальными сетями не попадал под NAT правило.

Выпускаем всех остальных и балансируем нагрузку.

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

Мы будем использовать ECMP для того, чтобы распределить нагрузку по провайдерам.

Наверное вы уже догадались что весь оставшийся трафик от ваших локальных хостов будет попадать в таблицу main.

Давайте сделаем маршрут ECMP с тем учётом, что шлюз 88.88.88.1 это 10Mbps, а 44.44.44.1 5Mbps.

/ip route> 
add dst-address=0.0.0.0/0 gateway=88.88.88.1,88.88.88.1,44.44.44.1 pref-src=88.88.88.2

Пакеты будут отправляться поочередно для каждого шлюза, на каждые 3 пакета, 2 пакету будут отправлены в 88.88.88.1 и отдавшийся один пакет на шлюз 44.44.44.1.

Хотя это немного и не правильно, дело в том, что у процесса ECMP есть отдельная таблица кеша, и чтобы каждый раз не выбирать маршрут. Маршрутизатор для связки src-address:port dst-address:port создаёт хеш и выберет для данного хеша уже шлюз по схеме Round Robin, тем самым для одного соединения будет выбираться один и тотже шлюз.

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

На ресурсах которые используют привязку с IP адресу сессию авторизации вы получите проблему в виде запроса логин и пароля, например mail.ru будет у вас запрашивать пароль при смене ip адреса.

Проблема в том, что ограничение в 10 минут, это ограничение жёсткое и нам его не убрать и не изменить.

Будем решать штатными средствами RouterOS.

Давайте подумаем вместе, что нам известно о пакете который попал под ECMP маршрут? Конечно данный пакет находится в таблице main.

Идея данного способа, заключается в следующем. Дать маршрутизатору выбрать маршрут с помощью ECMP, промаркировать такие соединения и все последующие пакеты в этом соединение пускать мимо ECMP, тем самым мы убираем проблему 10 минут.

Делаем.

/ip firewall mangle
add chain=postrouting routing-mark=main out-interface=ether1 connection-state=new  action=mark-connection new-connection-mark=ECMP/ether1 passthrough=no
add chain=postrouting routing-mark=main out-interface=ether2 connection-state=new  action=mark-connection new-connection-mark=ECMP/ether2 passthrough=no

Давайте разберём.

chain=postrouting - Работаем в цепочке по факту того что уже выбрал ECMP, можно использовать и цепочку forward, но тогда не попадёт трафик которым был сгенерирован самим маршрутизатором.

routing-mark=main - Маршрут ECMP находиться в main таблице.

out-interface=ether1 - ECMP выбрал шлюз которые лежит через первый интерфейс

connection-state=new - Мы маркируем соединение, нет смысла работать совсем пакетами.

action=mark-connection new-connection-mark=ECMP/ether1 - маркируем соединение.

Ещё раз, мы дали возможность ECMP выбрать направление и мы уже по факту промаркировали соединения основываясь на выборе интерфейса.

А теперь все последующие пакеты в соединениях с такой маркировкой должны быть отправлены в тот же интерфейс, но не в таблицу main, так как там работает ECMP, нам уже это не к чему.

/ip firewall mangle> 
add chain=prerouting connection-mark=ECMP/ether1 action=mark-routing new-routing-mark=Next-Hop/88.88.88.1 passthrough=no
add chain=prerouting connection-mark=ECMP/ether2 action=mark-routing new-routing-mark=Next-Hop/44.44.44.1 passthrough=no

Почти всё.

Осталось настроить NAT

/ip firewall nat> 
add chain=srcnat out-interface=ether1 routing-mark=main action=src-nat to addresses=88.88.88.2
add chain=srcnat out-interface=ether2 routing-mark=main action=src-nat to-addresses=44.44.44.2

За сим всё, спасибо за внимание.

Удалённая настройка маршрутизатора, к дальней дороге.