Рекурсивная маршрутизация в MikroTik через шлюзы назначемые DHCP

Наиболее часто задаваемый мне вопрос по использованию рекурсивной маршрутизации звучит так: «Что делать, если основной провайдер назначает нам ip-адрес через dhcp, при этом часто изменяется шлюз по-умолчанию?».
image

Для чего нужна рекурсивная маршрутизация? Для мониторинга наличия интернета за шлюзом провайдера. Ведь нередко случается, что маршрутизатор провайдера прекрасно отвечает на эхо-запросы, но [ап]линк в глобальную сеть у провайдера о какой-то причине пропал.
Рекурсивная маршрутизация позволяет оценить наличие доступа в Интернет через выбранного провайдера и принять решение о маршрутизации трафика.
Однако, дело в том, что использование рекурсивной маршрутизации предполагает наличие прибитого гвоздями прямое явное указание IP-адреса шлюза среди параметров создаваемого маршрута. Указание в качестве шлюза имени broadcast-интерфейса является неправильным и во многих случаях просто не работает, т.к. требует наличия proxy-arp со стороны провайдера. А еще, вместо провайдера proxy-arp может включить ваш сосед про провайдерскому свитчу и попытаться перехватить таким образом ваш трафик, устроив классический MITM!

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

Рассмотрим простейшую схему Active/Backup. Наш маршрутизатор выполнятет NAT и подключен к двум провайдерам посредством интерфейсов Ether1-isp1 и Ether2-isp2. Основной провайдер (ISP-1) раздаёт своим клиентам IP-адреса посредством протокола DHCP и никак иначе. Второй провайдер предоставляет нам статический IP-адрес, но значительно меньшую скорость.
Переключение на запасного (ISP-2) должно происходить тогда, когда доступ в Интернет через основного провайдера становится невозможным.
image
Изюминкой от провайдера для подобной схемы является периодическая произвольная смена не только IP-адреса клиента, но и default-gateway.

До версии 6.39 мне приходилось видеть весьма изощренные костыли в различных комбинациях sheduler, netwatch и тому подобных механизмов.
Начиная с версии 6.39 разработчики RouterOS пошли навстречу таким пользователям и создали возможность вызывать специальный скрипт при срабатывании dhcp-клиента на устройстве.
Собственно решение состоит из двух частей:
1) нужно получить по протоколу dhcp от провайдера IP-адрес и адрес шлюза для использования в рекурсивных маршрутах
2) полученный от провайдера адрес шлюза из автоматического использования по возможности исключить.
Итак, начнём с конца.
Создадим резервный маршрут через «ISP-2» со значением «distance» больше, чем у будущего основного. В данном примере я использовал «distance=2»:

Backup via ISP-2

/ip route add dst-address=0.0.0.0/0 gateway=192.0.2.1 distance=2

Далее, для того, чтобы получать от провайдера «ISP-1» маршрут по-умолчанию, но прямо его не использовать, существует специальное значение «distance=255». Маршрут с таким значением distance попадет в системную таблицу маршрутизации, но никогда не станет активным.

Код

/ip dhcp-client add comment="ISP-1 dhcp" default-route-distance=255 dhcp-options=hostname,clientid interface=Ether1-isp1

Такой маршрут нужен нам только для чтения присланных провайдером параметров и внедрением их в настройки рекурсивных маршрутов посредством скрипта.
Из полученных параметров, нас более других интересует переменная $gateway-address. Как можно догадаться из названия, она содержит в себе адрес шлюза по-умолчанию в сети провайдера. Её мы и будем использовать, чтобы привести рекурсивные маршруты в актуальное состояние.
Сами же рекурсивные маршруты должны быть корректно опознаны из скрипта. Для этого, на этапе их создания мы укажем уникальный «comment», который и будет использоваться для их поиска внутри таблицы. Код создания рекурсивной пары маршрутов:

Создание пары маршрутов

/ip route add dst-address=8.8.4.4 gateway=127.0.0.1 scope=30 target-scope=30 comment="isp1route" disabled=yes
/ip route add dst-address=0.0.0.0/0 gateway=8.8.4.4 check-gateway=ping

Первая строка должна (и будет!) указывать на настоящий шлюз в сети провайдера лишь после того, как провайдер выдаст параметры по dhcp и они будут обработаны посредством dhcp-client script:

Упрощенный скрипт

/ip route set [find comment="isp1route"] gateway=($"gateway-address") disabled=no
Более продвинутый вариант

:if ($bound=1) do={ /ip route set [find comment="isp1route"] gateway=($"gateway-address")disabled=no; :log warning ("New ISP1 gateway: ".($"gateway-address")) }

Теперь, при получении от провайдера «ISP-1» IP-адреса для использования в качестве шлюза по-умолчанию, он будет внесен в маршрутную пару вместо «127.0.0.1».
Вторая строка, где указан маршрут до 0.0.0.0/0, собственно и осуществляет всю магию. Указанный там в качестве шлюза узел 8.8.4.4 будет проверяться на отклик опцией «check-gateway=ping» именно через сеть ISP-1. В случае если узел 8.8.4.4 не ответит дважды на эхо-запросы в течение 20 секунд, маршрутизатор будет считать связь с Интернетом через этот маршрут (ISP-1) недоступной. Новые соединения в этом случае будут направлены через запасного провайдера ISP-2.

Если всё сделано правильно, то в окне winbox /ip->routes около маршрута до 8.8.4.4 будет видно слова «resursive via…». Это значит маршрут построился именно как рекурсивный.

В завершении, исключительно для примера — скрин окна винбокса:
image


ссылка на оригинал статьи https://habr.com/post/428097/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *