Тогда я подробно описал модель OSI и начальной настройки. Однако, полноценной отказоустойчивости и распределения нагрузки я тогда не достиг.
Задачка оказалась совсем не простой. Надо сказать, что спустя восемь лет я склоняюсь к мысли, что она не имеет полного и окончательного решения - чуть позже я объясню почему.
Но полагаю, что мне удалось приблизиться к заветной цели настолько, насколько это вообще возможно на сегодняшнем уровне развития RouterOS.
Важным граничным условием задачи было использование существующих механизмов - без скриптинга и множества правил маркировки.
Итак, приступим!
Вернее, продолжим.
Я рассмотрю три случая настроек подключения:
- Static IP - вбиваем адреса, шлюз и DNS руками;
- PPPoE - всё получаем от провайдера используя имя и пароль;
- DHCP - просто получаем все настройки втыкая кабель в порт роутера.
Укажем адреса на интерфейсах:
Код: Выделить всё
/ip address
add address=80.72.223.114/30 interface=ether1-TTK
add address=31.23.202.41/30 interface=ether2-Rostelecom
Код: Выделить всё
/ip dns
set allow-remote-requests=yes servers=80.72.225.2,80.72.230.2, 80.254.108.202,80.254.108.194
Прописываем маршруты:
Код: Выделить всё
/ip route
add check-gateway=arp distance=1 gateway=80.72.224.115
add check-gateway=arp distance=2 gateway=31.23.202.42
add check-gateway=ping distance=1 gateway=31.23.202.42 routing-mark=RT_table
Во первой строке я назначил шлюз провайдера ТТК как маршрут по умолчанию в основной таблице маршрутизации (main).
Доступность шлюза я проверяю используя протокол уровня Ethernet.
Во-второй строкой я прописал шлюз Ростелекома, указав, что он менее предпочтителен, в сравнении с TTK (distance=2).
Третьей строкой я прописал шлюз Ростелекома маршрутом по умолчанию в таблице RT_table. Доступность шлюза проверяю через ping. Оба способа (arp и ping) будут работать одновременно. Все маршруты Ростелекома лягут независимо от того, на каком правиле первей сработает проверка.
Напомню, что в таблице маршрутизации может быть лишь один действующий маршрут по умолчанию.
При данной настройке весь трафик будет идти через ТТК. Если ТТК отвалится - трафик тут же потечёт через Ростелеком.
Отказоустойчивость есть, балансировки - нет.
Но мы же не зря написали третью строчку.
Надо завернуть в неё часть трафика правилами:
Код: Выделить всё
/ip route rule
add comment="DNS RT" dst-address=80.254.0.0/16 table=RT_table
add comment="Torrent NAS" src-address=192.168.25.240/32 table=RT_table
Для внешнего подключения к минорному интерфейсу (где distance=2) придётся использовать метку соединений:
Код: Выделить всё
/ip firewall mangle
add action=mark-connection chain=input connection-state=new dst-address=31.23.202.41 new-connection-mark=RT_conn
add action=mark-routing chain=output connection-mark=RT_conn new-routing-mark=RT_table
Код: Выделить всё
/ip route
add check-gateway=arp distance=1 gateway=80.72.224.115 routing-mark=TTK_table
add check-gateway=ping distance=1 gateway=31.23.202.42 routing-mark=RT_table
add check-gateway=ping distance=1 gateway=80.72.224.115%ether1-TTK,31.23.202.42%ether2-Rostelecom
В основной таблице пишем оба маршрута через запятую включая ECMP (равномерное распределение соединений).
Это не значит, что трафик будет распределён равномерно. Никто и никогда заранее не угадает через какое соединение вдруг пойдёт закачка большого файла или просмотр видео.
Равномерно распределятся именно соединения.
Разрулим обращения к DNS-серверам:
Код: Выделить всё
/ip route rule
add comment="DNS RT" dst-address=80.254.0.0/16 table=RT_table
add comment="DNS TTK" dst-address=80.72.0.0/16 table=TTK_table
Или исходящие подключения туннелей (VPN работает лучше внутри сети одного провайдера).
И ещё два слова про NAT.
Вы можете создать список WAN-интерфейсов и сказать:
Код: Выделить всё
/ip firewall nat
add action=masquerade chain=srcnat out-interface-list=WAN src-address=192.168.25.0/24
Код: Выделить всё
/ip firewall nat
add action=src-nat chain=srcnat out-interface=ether1-TTK src-address=192.168.25.0/24 to-addresses=80.72.223.114
[... и таки да - отдельное правило для каждого интерфейса]
Код: Выделить всё
/interface pppoe-client
add name=TTK add-default-route=yes default-route-distance=1 interface=ether1-TTK use-peer-dns=yes user=yyyyyyyy password=xxxxxxx
add name=RT add-default-route=yes default-route-distance=2 interface=ether2-Rostelecom use-peer-dns=yes user=yyyyyyyy password=xxxxxxx
К тому же все означенные настройки могут время от времени меняться.
Но как в таком случае задать routing-mark и check-gateway?
Есть два способа. Первый - виртуальная таблица маршрутизации:
Код: Выделить всё
/ip route vrf
add interfaces=RT routing-mark=RT_table
В /ip route наше PPPoE подключение к Ростелекому будет с меткой routing-mark=RT_table
Мы можем направить туда часть трафика с помощью правил /ip route rule, но если канал Ростелекома упадёт - то опаньки.
Переключения на ТТК не случится. Поэтому для целей отказоустойчивости используем второй способ:
Код: Выделить всё
/routing filter
add chain=dynamic-in distance=2 set-check-gateway=ping set-routing-mark=RT_table
В /ip route всё будет выглядеть и работать ровно так же, как при VRF. Но если маршрут помрёт - назначенный ему трафик пойдёт через таблицу main, где основным маршрутом будет ТТК.
В данном случае ECMP будет работать по имени интерфейса:
Код: Выделить всё
/ip route
add check-gateway=ping distance=1 gateway=TTK,TTK,RT
Понятно, в основной таблице не должно быть других маршрутов с distance=1.
Значит ТТК надо убрать в отдельную таблицу маршрутизации
Код: Выделить всё
/routing filter
add chain=dynamic-in distance=1 set-check-gateway=ping set-routing-mark=TTK_table
Фигура третья, динамическая
Мы получаем от провайдера произвольный адрес и прочие настройки по DHCP.
Не только выдаваемый вам адрес, но и gateway и DNS могут менять время от времени.
Да, мы умеем назначать разные таблицы маршрутизации при помощи /routing filter и направлять в них трафик при помощи правил /ip route rule.
Но как включить ECMP?
Имена интерфейсов в данном случае не работают. Только прямое указание ip шлюза (и желательно с указанием интерфейса, через который он достижим - будет работать быстрее):
Код: Выделить всё
/ip route
add check-gateway=ping comment="Main Gateway" distance=1 gateway=80.72.224.115%ether1-TTK,31.23.202.42%ether2-Rostelecom
Создадим скрипт SetGW4ECMP следующего содержания:
Код: Выделить всё
:local TTK_GW [/ip dhcp-client get [find interface=ether1-TTK] gateway]
:local RT_GW [/ip dhcp-client get [find interface=ether2-Rostelecom] gateway]
/ip route set [find comment ="Main Gateway"] gateway="$TTK_GW%ether1-TTK,$RT_GW%ether2-Rostelecom"
Код: Выделить всё
/ip dhcp-client
set 0,1 script=SetGW4ECMP
Post scriptum
Так же не могу не упомянуть про новый механизм detect-internet.
Код: Выделить всё
/interface list
add name=WAN
add name=LAN
add name=Inet
/interface list member
add interface=ether1-TTK list=WAN
add interface=ether2-Rostelecom list=WAN
/interface detect-internet
set detect-interface-list=WAN internet-interface-list=Inet wan-interface-list=WAN
Код: Выделить всё
:put [/interface detect-internet state get [find name=ether1-TTK] state]
ineternet
За сим разрешите откланяться.
Удачи на маршрутах ;)