2WAN или MultiWAN с резервом

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

Легенда

  • Провайдер 1 дает по IPoE статику
  • Провайдер 2 дает по PPPoE статику (динамический шлюз)
  • Провайдер 3 дает по 4G (динамика)

Нужно сделать автоматическое переключение с провайдера 1 на провайдера 2 и в крайнем случае на провайдера 3, назовем это все TrippleWAN

Настройка шлюза

Провайдер 1

IP адрес 1.1.1.2/30 c шлюзом 1.1.1.2

Провайдер 2

IP адрес 2.2.2.2/32 но с рандомным шлюзом, который можно «прибить» на постоянный обратившись к статье:

Тем самым у провайдера 2 получаем шлюз 127.0.1.1

Провайдер 3

IP адрес динамический, но если используется USB модем с прошивкой HiLink, то он выполняет роль NAT и IP адрес с шлюзом используется от модема и известен заранее.
Но это не профессиональный подход 🙂

USB модем с безлимитной SIM картой и белым IP можно купить у моего товарища https://4g-inter.net

Для подключения к LTE оператору будет использована антенна MikroTik в режиме проброса IP адреса.

Получаем шлюз 10.177.0.3

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

Интерфейс-листы WAN

Чтобы было проще настраивать NAT, Firewall и Mangle и был один стиль названий WAN интерфейсов:

  1. ether1-WAN1 будет WAN1
  2. PPPoE_WAN2 будет WAN2
  3. vlan101-LTE-Internet будет WAN3
/interface list
add name=WAN1
add name=WAN2
add name=WAN3
add include=WAN1,WAN2,WAN3 name=WAN-ALL
/interface list member
add interface=ether1-WAN1 list=WAN1
add interface=PPPoE_WAN2 list=WAN2
add interface=vlan101-LTE-Internet list=WAN3

Маркировка входящего трафика

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

/ip firewall mangle
add action=mark-connection chain=prerouting comment="Mark Connection WAN1" connection-mark=no-mark in-interface-list=WAN1 new-connection-mark=con-WAN1 passthrough=yes
add action=mark-connection chain=prerouting comment="Mark Connection WAN2" connection-mark=no-mark in-interface-list=WAN2 new-connection-mark=con-WAN2 passthrough=yes
add action=mark-connection chain=prerouting comment="Mark Connection WAN3" connection-mark=no-mark in-interface-list=WAN3 new-connection-mark=con-WAN3 passthrough=yes
add action=mark-routing chain=prerouting comment="Mark Routing !WAN" connection-mark=con-WAN1 in-interface-list=!WAN-ALL new-routing-mark=WAN1 passthrough=yes
add action=mark-routing chain=prerouting comment="Mark Routing !WAN" connection-mark=con-WAN2 in-interface-list=!WAN-ALL new-routing-mark=WAN2 passthrough=yes
add action=mark-routing chain=prerouting comment="Mark Routing !WAN" connection-mark=con-WAN3 in-interface-list=!WAN-ALL new-routing-mark=WAN3 passthrough=yes
add action=mark-routing chain=output comment="Mark Roution Out WAN1" connection-mark=con-WAN1 new-routing-mark=WAN1 passthrough=yes
add action=mark-routing chain=output comment="Mark Roution Out WAN2" connection-mark=con-WAN2 new-routing-mark=WAN2 passthrough=yes
add action=mark-routing chain=output comment="Mark Roution Out WAN3" connection-mark=con-WAN3 new-routing-mark=WAN3 passthrough=yes

Настройка рекурсивных маршрутов

Рекурсивная маршрутизация позволяет проверить наличие интернета за шлюзом через Check Gateway, но включаться он будет через Netwatch
Проверять будет за счет серверов Яндекс.DNS:

  • 77.88.8.1 для WAN1
  • 77.88.8.2 для WAN2
  • 77.88.8.3 для WAN3
/ip route
add comment=WAN1_!_Recursive distance=1 gateway=77.88.8.1 routing-mark=WAN1
add comment=WAN2_!_Recursive distance=1 gateway=77.88.8.2 routing-mark=WAN2
add comment=WAN3_!_Recursive distance=1 gateway=77.88.8.3 routing-mark=WAN3
add comment=WAN1_Recursive distance=10 gateway=77.88.8.1
add comment=WAN2_Recursive distance=20 gateway=77.88.8.2
add comment=WAN3_Recursive distance=30 gateway=77.88.8.3
add comment=WAN1 distance=1 dst-address=77.88.8.1/32 gateway=1.1.1.1 scope=10
add comment=WAN2 distance=1 dst-address=77.88.8.2/32 gateway=127.0.1.1 scope=10
add comment=WAN3 distance=1 dst-address=77.88.8.3/32 gateway=10.177.0.3 scope=10

Добавим правила маршрутизации:

  • 8.8.8.8 для WAN1
  • 8.8.4.4 для WAN2
  • 4.2.2.1 для WAN3
/ip route rule
add comment=Route_Only_WAN1 src-address=1.1.1.2/32 table=WAN1
add dst-address=8.8.8.8/32 table=WAN1
add routing-mark=WAN1 table=WAN1
add comment=Route_Only_WAN2 src-address=2.2.2.2/32 table=WAN2
add dst-address=8.8.4.4/32 table=WAN2
add routing-mark=WAN2 table=WAN2
add comment=Route_Only_WAN3 dst-address=4.2.2.1/32 table=WAN3
add routing-mark=WAN3 table=WAN3

Чтобы трафик до «проверочных» узлов не убегал через другого провайдера, в Firewall добавим адрес листы:

/ip firewall address-list
add address=8.8.8.8 list=Only_WAN1
add address=8.8.4.4 list=Only_WAN2
add address=4.2.2.1 list=Only_WAN3

И настроим запрет пересылки, кроме разрешенного интерфейса:

/ip firewall filter
add action=drop chain=output comment="Only WAN1" dst-address-list=Only_WAN1 out-interface-list=!WAN1
add action=drop chain=output comment="Only WAN2" dst-address-list=Only_WAN2 out-interface-list=!WAN2
add action=drop chain=output comment="Only WAN3" dst-address-list=Only_WAN3 out-interface-list=!WAN3

Я использую данный способ как счетчик и защита от зависших соединений. В отличии от жесткой привязки к маршруту через lookup only table, этот способ никогда не «залипал».

Проверка наличия Интернета

Способ 1 — Netwatch

/tool netwatch
add comment=Check_WAN1 down-script="/ip route set [find comment=\"WAN1_Recursive\"] check-gateway=ping" host=8.8.8.8 up-script="/ip route unset [find comment=\"WAN1_Recursive\"] check-gateway"
add comment=Check_WAN2 down-script="/ip route set [find comment=\"WAN2_Recursive\"] check-gateway=ping" host=8.8.4.4 up-script="/ip route unset [find comment=\"WAN2_Recursive\"] check-gateway"
add comment=Check_WAN3 down-script="/ip route set [find comment=\"WAN3_Recursive\"] check-gateway=ping" host=4.2.2.1 up-script="/ip route unset [find comment=\"WAN3_Recursive\"] check-gateway"

Каждые 60 секунд отрабатывает Netwatch, который проверяет отклик серверов проверки. Если нет отклика, скрипт находит маршрут по комментарию и включает опцию Check Gateway, которая через 2 проверки с интервалом 10 секунд считает канал «упавшим» и отключает маршрут.

Этот способ хорошо отрабатывает для стабильных каналов, которые стабильно полностью падают и через них не пробивается ICMP, пока канал полностью не подымится.

Используется в большинстве корпоративных установок.

Способ 2 — Умный анализ

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

1 и 2 способ в связке потому, что скрипт умного анализа читает IP адрес с интерфейса, а если он еще не поднялся или еще не имеет IP, то скрипт не отрабатывает. На этот случай страхует 1 способ проверки.

Нужно добавить дополнительные скрипты «ручного» переключения WAN:

:local PingCount 3;
:local losses 1;
:local PingTargets {77.88.8.7; 4.2.2.2; 8.26.56.26}
:local CountTargets [:len $PingTargets];

:local WAN1Interface ether1-WAN1;
:local WAN1Interval 100ms;
:local WAN1Pings 0;

:local WAN2Interface PPPoE_WAN2;
:local WAN2Interval 100ms;
:local WAN2Pings 0;

:local WAN3Interface vlan101-LTE-Internet;
:local WAN3Interval 1000ms;
:local WAN3Pings 0;

local result [/ip address get value-name=address [find interface=$WAN1Interface]];
local WAN1IP [:pick $result 0 [:find $result "/"]];

local result [/ip address get value-name=address [find interface=$WAN2Interface]];
local WAN2IP [:pick $result 0 [:find $result "/"]];

local result [/ip address get value-name=address [find interface=$WAN3Interface]];
local WAN3IP [:pick $result 0 [:find $result "/"]];

foreach host in=$PingTargets do={
   :local res [/ping $host count=$PingCount interface=$WAN1Interface src-address=$WAN1IP interval=$WAN1Interval]
   :set WAN1Pings ($WAN1Pings + $res)

   :local res [/ping $host count=$PingCount interface=$WAN2Interface src-address=$WAN2IP interval=$WAN2Interval]
   :set WAN2Pings ($WAN2Pings + $res)

   :local res [/ping $host count=$PingCount interface=$WAN3Interface src-address=$WAN3IP interval=$WAN3Interval]
   :set WAN3Pings ($WAN3Pings + $res)
}

:local balance (($CountTargets*$PingCount)-$losses);

if ($WAN1Pings >= $balance) do={
   /system script run WAN1>WAN2>WAN3;
} else {
   if ($WAN2Pings >= $balance) do={
      /system script run WAN2>WAN1>WAN3;
   } else {
      /system script run WAN3>WAN1>WAN2;
   }
}

В скрипте задаются названия интерфейсов, с которых берется IP адрес и с которых производится проверка. Параметр Interval в ms используется для оценки качества канала. Если за 100ms канал WAN1 не получил более 1 отклика, то он считается «битым» и сравнивается количество откликов у канала WAN2.
WAN3 всегда читается рабочим, если его не забракует 1 способ проверки.

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

Для его использования необходимо оценить работу всех каналов, скорости отклика и частоты падения. Только после этого «умный» скрипт подгоняется под конкретную установку.

Частота запуска «умного» скрипта задаётся индивидуально через System > Sheduler