MikroTik. Правильный dst nat при использовании 2-х и более провайдеров

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

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


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

    Часть 1.


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

    Версия RouterOS:
    # oct/11/2016 22:02:32 by RouterOS 6.37.1
    # software id = X62B-STGZ
    

    Интерфейсы:
    /interface list
    add name=WAN
    /interface list member
    add interface=ISP1 list=WAN
    add interface=ISP2 list=WAN
    add interface=ISP3 list=WAN
    

    Не помню начиная с какой версии RouterOS появилась эта фишка. Она позволяет группировать интерфейсы, что весьма удобно (например, в правилах /ip firewall). У меня создана группа из 3-х WAN-интерфейсов.
    AcidVenom подсказал, что в 6.36

    IP-адреса (адреса, по понятным причинам, «левые»):
    /ip address
    add address=192.168.0.1/24 comment=defconf interface=bridge network=192.168.0.0
    add address=95.11.29.240/24 interface=ISP1 network=95.11.29.0
    add address=5.35.59.162/27 interface=ISP2 network=5.35.59.160
    add address=5.98.112.30/30 interface=ISP3 network=5.98.112.28
    

    Роутинг:
    /ip route
    add distance=1 gateway=95.11.29.254 routing-mark=ISP1-route
    add distance=1 gateway=5.35.59.161 routing-mark=ISP2-route
    add distance=1 gateway=5.98.112.29 routing-mark=ISP3-route
    add check-gateway=ping distance=1 gateway=8.8.8.8
    add check-gateway=ping distance=2 gateway=8.8.4.4
    add check-gateway=ping distance=3 gateway=1.1.36.3
    add distance=1 dst-address=8.8.4.4/32 gateway=5.35.59.161 scope=10
    add distance=1 dst-address=8.8.8.8/32 gateway=95.11.29.254 scope=10
    add distance=1 dst-address=1.1.36.3/32 gateway=5.98.112.29 scope=10
    

    Для организации Failover'а я настроил рекурсивную маршрутизацию, подробнее расскажу в 2-ой части.

    Firewall (для данной публикации я сознательно привожу правила, разрешающие все.
    Не делайте так!):

    /ip firewall filter
    add action=accept chain=forward
    add action=accept chain=input
    add action=accept chain=output
    

    dst и src nat:
    /ip firewall nat
    add action=masquerade chain=srcnat out-interface-list=WAN
    add action=dst-nat chain=dstnat comment="HTTP" dst-port=80 \
        in-interface-list=WAN protocol=tcp to-addresses=192.168.0.83 to-ports=80
    add action=dst-nat chain=dstnat comment="HTTPs" dst-port=443 \
        in-interface-list=WAN protocol=tcp to-addresses=192.168.0.83 to-ports=443
    

    mangle
    /ip firewall mangle
    add action=mark-connection chain=input in-interface=ISP1 \
        new-connection-mark=ISP1-conn passthrough=yes
    add action=mark-routing chain=output connection-mark=ISP1-conn \
        new-routing-mark=ISP1-route passthrough=no
    add action=mark-connection chain=input in-interface=ISP2 new-connection-mark=\
        ISP2-conn passthrough=yes
    add action=mark-routing chain=output connection-mark=ISP2-conn \
        new-routing-mark=ISP2-route passthrough=no
    add action=mark-connection chain=input in-interface=ISP3 \
        new-connection-mark=ISP3-conn passthrough=yes
    add action=mark-routing chain=output connection-mark=ISP3-conn \
        new-routing-mark=ISP3-route passthrough=no
    add action=mark-connection chain=forward in-interface=ISP1 \
        new-connection-mark=ISP1-conn-f passthrough=no
    add action=mark-routing chain=prerouting connection-mark=ISP1-conn-f \
        in-interface=bridge new-routing-mark=ISP1-route 
    add action=mark-connection chain=forward in-interface=ISP2 \
        new-connection-mark=ISP2-conn-f passthrough=no
    add action=mark-routing chain=prerouting connection-mark=ISP2-conn-f \
        in-interface=bridge new-routing-mark=ISP2-route 
    add action=mark-connection chain=forward in-interface=ISP3 \
        new-connection-mark=ISP3-conn-f passthrough=no
    add action=mark-routing chain=prerouting connection-mark=ISP3-conn-f \
        in-interface=bridge new-routing-mark=ISP3-route 
    

    Часть 2.


    Рассмотрим все подробнее.

    Роутинг:
    глянь под спойлер, чтобы не листать
    /ip route
    add distance=1 gateway=95.11.29.254 routing-mark=ISP1-route
    add distance=1 gateway=5.35.59.161 routing-mark=ISP2-route
    add distance=1 gateway=5.98.112.29 routing-mark=ISP3-route
    
    add check-gateway=ping distance=1 gateway=8.8.8.8
    add check-gateway=ping distance=2 gateway=8.8.4.4
    add check-gateway=ping distance=3 gateway=1.1.36.3
    
    add distance=1 dst-address=8.8.4.4/32 gateway=5.35.59.161 scope=10
    add distance=1 dst-address=8.8.8.8/32 gateway=95.11.29.254 scope=10
    add distance=1 dst-address=1.1.36.3/32 gateway=5.98.112.29 scope=10
    


    /ip route
    В первых трех строчках мы указываем default gateway каждого из 3-х наших провайдеров.
    Маршруты имеют одинаковый вес (distance), но работают в разных таблицах маршрутизации.

    Другими словами, эти маршруты работают для пакетов промаркированных соответствующим тегом (routing-mark). Теги пакетам мы будем навешивать в /ip firewall mangle (о чем я подобно расскажу ниже).

    Следующие 3 строки — указание маршрутов по умолчанию в основной таблице маршрутизации.

    Здесь стоит обратить внимание на:

    1. Параметр distance. Для каждого маршрута разный и, соответственно, «вес» маршрутов тоже разный.

      ISP1 — основной, за ним ISP2 и ISP3 замыкает, т.е. при отказе провайдера ISP1 работать будем через ISP2, если и ISP2 почил в бозе, то за дело возьмется ISP3.

    2. Несколько непонятным может быть значение параметра gateway. Как это гугловые DNS и какой-то левый IP-адрес вдруг стали маршрутами по-умолчанию? Магия заключается в параметре scope из последних трех строк, а так же в самом механизме Nexthop lookup.

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

    3. О параметре check-gateway=ping. Суть в том, что в самой простой схеме построения Failover, указывая check-gateway=ping в маршрутах по умолчанию, мы проверяем связь только до маршрутизатора провайдера. Если же за маршрутизатором провайдера будет недоступен Интернет, то мы этого не поймем. А с помощью финта с параметром scope мы проверяем связь уже не с провайдером, а смотрим за него, в Интернет.

    Под спойлером мой подробный перевод/адаптация вики MikroTik на эту тему.

    MikroTik. Nexthop_lookup
    Английский статьи http://wiki.mikrotik.com/wiki/Manual:IP/Route, на мой взгляд, слегка упорот. Это не Cisco CCNA Exploration, который читается на одном дыхании, но я постараюсь перевести ее отрывок максимально понятно. Если где-то увидите такую же упоротость, поправьте меня, пожалуйста.

    Во-первых, определимся с некоторыми терминами.
    Nexthop — следующий прыжок, если дословно. Следующий шлюз/роутер/маршрутизатор на пути следования пакета из точки А(от моего роутера, например) в точку Б (допустим до гуглового DNS 8.8.8.8), т.е. следующий транзитный участок, на котором будет обрабатываться пакет. В переводе будет использоваться словосочетание “следующий хоп” (простите за англицизм).

    Immediate nexthop — следующий шлюз/роутер/маршрутизатор на пути следования пакета из точки А в точку Б, доступный непосредственно. Для моего домашнего MikroTik, с маршрутом по-умолчанию:

    dst-address=0.0.0.0/0 gateway=89.189.163.1 gateway-status=89.189.163.1 reachable via ether1-gateway

    89.189.163.1 — это и есть immediate nexthop, т.к. доступен он через ether1-gateway. В переводе будет использоваться словосочетание “непосредственно доступный следующий хоп”.

    Connected route — связанный маршрут. Маршрут, шлюз которого доступен непосредственно.

    Gateway — сетевой шлюз/роутер/маршрутизатор.
    Я буду пользоваться всеми тремя вариантами перевода.

    scope — Используется в механизме поиска следующего хопа, т.е. решения какой же хоп станет следующим. Нужный маршрут может быть выбран только среди маршрутов, значения scope которых меньше либо равно значению target-scope. Значения по-умолчанию зависят от протокола:

    • связанные маршруты: 10 (если интерфейс запущен(running))
    • OSPF, RIP, MME маршруты: 20
    • статические маршруты: 30
    • BGP маршруты: 40
    • связанные маршруты: 200 (если интерфейс не запущен)

    target-scope — Используется в механизме поиска следующего хопа, т.е. решения какой же хоп станет следующим. Это максимальное значение параметра scope для маршрута, посредством которого может быть найден следующий хоп. Для iBGP значение установленно в 30 по-умолчанию.

    Табличка значений обоих параметров.



    Поиск следующего хопа.
    Поиск следующего хопа является частью процесса выбора маршрута.

    Маршрутам, находящимся в FIB, нужен интерфейс, соответствующий каждому из адресов шлюзов. Адрес следующего хопа-шлюза должен быть непосредственно доступен через этот интерфейс. Интерфейс, который следует использовать для посылки исходящего пакета каждому из шлюзов, находится с помощью поиска следующего хопа.

    Некоторые маршруты (например, iBGP), в качестве адреса шлюза, могут иметь адрес принадлежащий маршрутизатору, находящемуся через несколько прыжков-шлюзов от нашего MikroTik. Для установки таких маршрутов в FIB необходимо найти адрес шлюза, доступного непосредственно (an immediate nexthop), т.е. напрямую от нас, который и будет использоваться для достижения адреса шлюза в этом маршруте. Непосредственный адрес следующего хопа также может быть найден при помощи механизма поиска следующего хопа.

    Поиск следующего хопа выполняется только в основной таблице маршрутизации main, даже для маршрутов, имеющих отличное значение параметра routing-mark. Это необходимо для ограничения установки маршрутов, которые могут быть использованы для поиска непосредственно доступных хопов (immediate nexthops). В маршрутах для протоколов RIP или OSPF предполагается, что следующий маршрутизатор доступен непосредственно и должен быть найдены используя только связанные маршруты(connected routes).

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

    Маршруты, имеющие значение параметра scope больше максимально допустимого не используются в поиске следующего хопа. В каждом маршруте указывается максимально допустимое значение параметра scope, для его следующего хопа, в параметре target-scope. Значение по-умолчанию для этого параметра позволяет выполнить поиск следующего хопа только через связанные маршруты (connected routes), за исключением iBGP-маршрутов, которые имеют большее значение по-умолчанию и могут выполнить поиск следующего хопа также через IGP и статические маршруты.



    Интерфейс и адрес следующего непосредственно доступного маршрутизатора выбираются основываясь на результатах поиска следующего хопа:

    • Если наиболее точный активный маршрут, который был обнаружен в ходе поиска адреса следующего хопа, является связанным маршрутом, то интерфейс этого связанного маршрута используется как интерфейс следующего хопа и шлюз помечается как reachable. После того как маршрутизатор становится непосредственно доступным через этот интерфейс (именно это и следует понимать как “связанный маршрут” или “connected route”) его адрес используется как адрес непосредственно доступного маршрутизатора (immediate nexthop address).

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

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

    • Если механизм поиска адреса следующего хопа не нашел ни одного маршрута, то шлюз помечается как unreachable.

    А теперь, как говорят в КВН, зачем же я показал этот номер. Обратите внимание, мы устанавливаем scope=10 для статических маршрутов в последних трех строках, тем самым «заставляем» MikroTik принимать во внимание эти маршруты при поиске следующего хопа.

    Он и принимает, и таким образом маршруты по-умолчанию через:

    • 8.8.8.8
    • 8.8.4.4
    • 1.1.36.3

    становятся recursive, т.е. непосредственно доступными хопами будут шлюзы провайдеров и трафик мы пошлем через них, но check-gateway=ping будет проверять доступность адресов ЗА провайдерскими сетями.

    Надеюсь мой перевод и объяснение будут вам полезны.

    Пока самые охочие до знаний читают под спойлером, расскажу немого короче и проще.
    Когда мы указываем scope=10 в последних трех строках, мы даем понять MikroTik'у, что:

    • 8.8.8.8
    • 8.8.4.4
    • 1.1.36.3

    ему доступны не напрямую, а рекурсивно через данные статические маршруты. По одному IP на брата-провайдера.

    /ip firewall mangle
    правила здесь
    /ip firewall mangle
    add action=mark-connection chain=input in-interface=ISP1 \
        new-connection-mark=ISP1-conn passthrough=yes
    add action=mark-routing chain=output connection-mark=ISP1-conn \
        new-routing-mark=ISP1-route passthrough=no
    
    add action=mark-connection chain=input in-interface=ISP2 new-connection-mark=\
        ISP2-conn passthrough=yes
    add action=mark-routing chain=output connection-mark=ISP2-conn \
        new-routing-mark=ISP2-route passthrough=no
    
    add action=mark-connection chain=input in-interface=ISP3 \
        new-connection-mark=ISP3-conn passthrough=yes
    add action=mark-routing chain=output connection-mark=ISP3-conn \
        new-routing-mark=ISP3-route passthrough=no
    
    add action=mark-connection chain=forward in-interface=ISP1 \
        new-connection-mark=ISP1-conn-f passthrough=no
    add action=mark-routing chain=prerouting connection-mark=ISP1-conn-f \
        in-interface=bridge new-routing-mark=ISP1-route  
    
    add action=mark-connection chain=forward in-interface=ISP2 \
        new-connection-mark=ISP2-conn-f passthrough=no
    add action=mark-routing chain=prerouting connection-mark=ISP2-conn-f \
        in-interface=bridge new-routing-mark=ISP2-route  
    
    add action=mark-connection chain=forward in-interface=ISP3 \
        new-connection-mark=ISP3-conn-f passthrough=no
    add action=mark-routing chain=prerouting connection-mark=ISP3-conn-f \
        in-interface=bridge new-routing-mark=ISP3-route  
    


    Для пояснения правил этого раздела пригласим несколько помощников.

    1. MANGLE — данная таблица предназначена для операций по классификации и маркировке пакетов и соединений, а также модификации заголовков пакетов (поля TTL и TOS) (викиучебник).

      Таблица mangle содержит следующие цепочки:
      1. PREROUTING — позволяет модифицировать пакет до принятия решения о маршрутизации.
      2. INPUT — позволяет модифицировать пакет, предназначенный самому хосту.
      3. FORWARD — цепочка, позволяющая модифицировать транзитные пакеты.
      4. OUTPUT — позволяет модифицировать пакеты, исходящие от самого хоста.
      5. POSTROUTING — дает возможность модифицировать все исходящие пакеты, как сгенерированные самим хостом, так и транзитные.
    2. CONNECTION TRACKING — специальная подсистема, отслеживающая состояния соединений и позволяющая использовать эту информацию при принятии решений о судьбе отдельных пакетов.
    3. Packet flow MikroTik'а

    Я разбил правила на группы, для облегчения их понимания. В первой группе 6 правил, которые отвечают за трафик в/из самого роутера, и во второй группе 6, для транзитного трафика.

    Начем с первых двух.
    В первом мы сообщаем роутеру, что все входящие chain=input соединения на интерфейс ISP1 нужно маркировать action=mark-connection new-connection-mark=ISP1-conn, а так же указаваем passthrough=yes, чтобы пакет, после прохождения этого правила, не покинул таблицу и продолжил следование по правилам.

    Во втором говорим MikroTik'у, чтобы он отловил исходящие соединения chain=output помеченные как ISP1-conn и присвоил им метку роутинга(для помещения в соответствующую таблицу маршрутизации, вы ведь помните первые три маршрута?), а также сообщаем passthrough=no , как бы говоря — нечего делать здесь пакету после этого правила, т.е. пакет покинет таблицу.

    Все описанное выше справедливо и для ISP2 и для ISP3. Таким образом мы добились того, что роутер ответит именно с того интерфейса, на который к нему прийдет запрос.

    Переходим к завершающим шести правилам.
    Уже понятно, они также разбиты на подгруппы по 2, для каждого из наших ISP.
    Первое из них поручает роутеру следить за цепочкой FORWARD и если происходит соединение через интерфейс ISP1, то оно маркируется action=mark-connection новым тегом new-connection-mark=ISP1-conn-f (обратите внимание! отличным от тега трафика самого маршрутизатора, в данном случае мы маркируем транзитный трафик). passthrough=no, т.к. мы не хотим, чтобы пакет, после попадания в это правило, обрабатывался в таблице как-то еще.

    Второе навешивает нужную метку роутинга new-routing-mark=ISP1-route в цепочке PREROUTING, т.е. ДО принятия решения о маршрутизации, и отслеживает трафик пришедший к нам из локальной сети in-interface=bridge.
    Здесь нас выручает механизм CONNECTION TRACKING, позволяющий поймать промаркированные правилом выше соединения из локальной сети(от WEB-сервера) и навесить им необходимый тег роутинга.

    Это позволяет транзитному трафику(здесь к/от web-сервера) идти именно тем путем, которым он и пришел, т.е. пришел через ISP1 — уходи через него же.

    Заключение


    Очень рад, если мои объяснения понятны, а данный труд станет полезен.
    Ушел медитировать, всем удачи!

    Благодарю за внимание!
    Поделиться публикацией

    Комментарии 58

      0
      Не помню начиная с какой версии RouterOS появилась эта фишка.

      v6.36
        0
        Спасибо, добавил в статью.
        +1
        Указывать гейт провайдера плохая идея. Бывают провайдеры с несколькими гейтами. Использую рекурсивную маршрутизацию для резервирования через 3г модем. Поставил клиенту, а у провайдера оказалось множество гейтов. Поймал 3 разных, после этого в маршруте пришлось указывать интерфейс, а не гейт.
          +1
          MikroTik чрезвычайно гибкий инструмент, на мой взгляд, так что все зависит от задачи.
          Failover можно и скриптом сделать (я делал вот так https://habrahabr.ru/post/271747/)
          В моем случае (и я уверен, что для многих других этот вариант тоже подойдет) это вполне решение (я про указание гейта провайдера).
            0
            Тут в другом проблема. Пример из вашего конфига. Указываем у первого провайдер гейт 95.11.29.254, а у него (о чем мы не знаем) есть второй гейт 95.11.29.253. Следовательно первый провайдер будет считаться недоступным, т.к. гейт не виден. Тут два варианта — либо указывать интерфейс, либо узнавать все возможные гейты. Второй вариант конечно предпочтительней, но в техподдержке иногда работают не очень умные люди, которые не знают что это и к чему.
              +2
              Это не проблема конфига. Это проблема упоротых провайдеров не умеющих нормально обеспечить отказоустойчивость для основных типов клиентских устройств.
              Если провайдер настолько упорот, он может завести хоть 65533 gateway, только сообщать о них клиентам он как будет? Выдавать по DHCP каждые 10 секунд? Или упорно слать icmp-redirect?
              Интерфейс в качестве gateway на broadcast-интерфейсе? Это тоже надо очень сильно упороться.

                +2
                Это проблема клиента этого провайдера, а следовательно и моя. И её надо решать. Гейт меняется при реконнекте pppoe. Как и почему — дело десятое. Задача — переход на резерв и возврат обратно. Если указан гейт, то обратно маршрут не переключится.
                И что криминального указывать маршрут через интерфейс, а не гейт? Речь идет конкретно о МТ.
                  +1
                  Я уже писал — здесь Failover скриптом бы обеспечил.
                    0
                    Вы не знает разницы между соединениями точка-точка и подключением через обычный ethernet при наличии broadcast-домена. Это разные случаи и методики маршрутизации и адресации будут разные.
                      0
                      Подумайте как следует над строчками
                      /ip address
                      add address=95.11.29.240/24 interface=ISP1 network=95.11.29.0
                      add address=5.35.59.162/27 interface=ISP2 network=5.35.59.160

                      Посмотрите как строится адресация на вашем PPPoE. Сравните.
                        +1
                        Если позволите, то коллеги имеют ввиду следующее, для сред с множественным доступом, а Ethernet одна из таких, это приведёт к тому, что маршрутизатор будет считать, что адрес напрямую подключен к интерфейсу. Что приведёт к отправке ARP запросов для определения соответствия сетевого адреса, канальному. Если у вашего ISP не будет активирована функция Proxy ARP, то на ARP запрос не кому будет ответить.

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

                        Не претендую на истину в последней инстанции, если где-то ошибся, буду рад услышать где. :)
                –2
                Автор, я так понимаю, не совсем в теме.
                Вместо того что-бы маркировать (routing-mark=) в данном случае запросто можно обойтись:
                /ip route rules
                раскидав по таблицам маршрутизации.

                Так как описано в статье делалось на микротиках очень давно.

                как пример, чтоб пакеты уходи с того интерфейса, на который пришли:
                /ip route rule
                add interface=vlan2 src-address=192.168.1.1 table=RES
                add interface=vlan3 src-address=172.16.1.1 table=OFC

                /ip route
                add check-gateway=arp distance=8 gateway= 192.168.1.2 routing-mark=RES
                add check-gateway=arp distance=9 gateway=172.16.1.2 routing-mark=OFC

                  0
                  я имею ввиду, что вместо того чтоб городить кучу правил в mangle, достаточно направить в отдельную таблицу маршрутизации.
                    0
                    Вообще, может понадобиться сделать пробросы портов с двух каналов на один сервер во внутренней сети (например, почтовый). В таком случае, насколько мне известно, правилами в стиле iproute2:
                    ip route add from 192.168.1.2 lookup ISP1

                    не обойтись. В этом случае CONNECTION TRACKING и пригодится.
                      –1
                      В данном случае не имеет значения куда и что пробрасывать, совершенно.
                      Мы просто меняем механизм маршрутизации с управления на файрволе в таблице mangle, на управление в помощью ip rule.
                      Так же как в линукс-е.

                      Конечно, в некоторых исключительных случаях не обойтись без mangle, но в данном случае он абсолютно не нужен.
                        0
                        fix: * ip rule add from 192.168.1.2 lookup ISP1_table

                        Ну и да, правила выбора таблицы маршрутизации позволяют выбирать таблицу на основе маркера пакета. В linux так:
                        ip rule add from all fwmark 0x1 lookup ISP1_table

                        Значит и в mikrotik можно
                          0
                          ну так а я о чём «с утра» написал?
                          а вот когда речь пойдет о полноценном PBR, вот тогда без mangle не обойтись.
                      +2
                      Вместо того что-бы маркировать (routing-mark=) в данном случае запросто можно обойтись:
                      /ip route rules
                      раскидав по таблицам маршрутизации.

                      Давайте представим нормальную ситуацию, когда все внешние шлюзы считаются доступными.
                      Обратите внимание — сеть маскарадится в три направления, т.е. web-сервер не имеет своего белого IP. Это важно, т.к. в ответе web-сервера src-ip меняется в зависимости от направления.
                      Поскольку маршрутизация тогда будет идти попакетно, на основе src-ip, все ответы web-сервера пойдут через один и тот же шлюз, первым указанный в таблице, куда его приведет /ip route rule (при src=192.168.0.83 адрес web-сервера). Пусть это будет как у автора «95.11.29.254»
                      Тогда клиент обратившийся ко второму внешнему IP, через второго провайдера (5.35.59.162/27 interface=ISP2 ) всё равно будет получать ответы WEB-сервера через ISP1 с IP 95.11.29.254 и соединение не установится.

                      Установка соединения при предложенном /ip route rule
                      Tcp-Запрос клиента:
                      (src-ip: 1.1.1.1:52000, dst-ip:5.35.59.162:80) -> dst-nat -> routing -> (src-ip: 1.1.1.1:52000, dst-ip:192.168.0.83:80)

                      Ответ web-сервера:
                      (src-ip: 192.168.0.83:80, dst-ip:1.1.1.1:52000) -> routing-> src-nat -> (src-ip: 95.11.29.254:80, dst-ip:1.1.1.1:52000)

                      Клиент запросивший соединение с 5.35.59.162:80, получит ответ с 95.11.29.254:80 и обломится.
                        0
                        Если взять сеть автора и есть, к примеру, правило
                        /ip firewall nat
                        add action=dst-nat chain=dstnat dst-address-list=self-ext dst-port=80,443 protocol=tcp to-addresses=192.168.0.11

                        соединение установлено через ISP2
                        Каким образом вы предлагаете, используя ip route rules, отправлять пакеты через тот же интерфейс?
                          0
                          Я этого и не предлагаю. Это предложил shadowalone. Вы не тому отвечаете.
                            0
                            Возможно вы были не внимательны, это как раз ответ на сообщение shadowalone, а не ваше.
                          0
                          Все немного не так, в вашем примере вы используете vlan-ы, чтобы понимать по какому каналу пришел запрос на web-сервер, чтобы отправить ответ по нему-же.
                          У автора же, сервер принимает на и отвечает с одного и того-же адреса, если я все верно понял.

                          Однако, это не отменяет того, что автор сильно перемудрил, используя vlan-ы или на худой конец просто alias-ы можно было бы обойтись 3-мя route rule и 3-мя роутами.
                            +1
                            Автор поста как раз vlan-ы НЕ использует, у него всё здраво. Это shadowalone что-то про интерфейсы с именами «vlan» написал.
                              0
                              Не можно было бы обойтись.
                              Дайте конфиг, где вы достигаете ровно той же цели, что и я только за счет роутрулов.
                                0
                                Смотрите, объясню, как это всегда работало у меня.
                                На web-server добавляете ip alias -ы (как я выше написал, можно vlan-ами, но для упрощения объясню с алиасами).
                                В результате ваш сервер доступен на N внутренних адресах.
                                На роутере настраиваете DNAT, где каждый внешний ip меняете на свой внутренний ip:
                                1.2.3.4 -> 192.168.0.2
                                4.3.2.1 -> 192.168.0.3
                                5.4.3.2 -> 192.168.0.4
                                Теперь с помощью ip rule на роутере добавляете:
                                from 192.168.0.2 lookup ISP1_TABLE
                                from 192.168.0.3 lookup ISP2_TABLE
                                from 192.168.0.4 lookup ISP3_TABLE
                                В таблицах роуты для специфического провайдера.
                                Вот и все, теперь ваш web-сервер доступен на всех внешних адресах.
                                  0
                                  коллега, прошу прощения, но вы показали, как не надо делать
                                  у меня правило ната выглядит одной строкой, в которой можно указать либо лист с интерфейсами, либо лист с внешними пипишками.
                                  лукапом можно убрать мангловый марк, т.к. остальное сделает контрак, быть может оно и сработает, даже если есть балансировка (не использую, т.к. возникают специфические проблемы).
                                  хотя велосипед прикольный %)
                                    0
                                    Чем конкретно этот подход хуже 12 правил мангла для тех-же 3-х провайдеров?
                                      0
                                      дык это надо ещё lookup на линупсах лепить, ещё по 2 строки в networks на каждый ип :)
                                        0
                                        Все верно, давайте я попробую описать плюсы своего подхода (субъективно, конечно).
                                        Опять же, не настаиваю, что это серебряная пуля, просто минусов данного решения я за много лет не нашел.
                                        • виден траффик конкретного провайдера и можно определить перекос балансировки (это если у вас на интерфейсе не только сервер)
                                        • сервер видит через какой провайдер идут запросы, что тоже, иногда, бывает необходимо
                                        • используя vlan-ы можно убрать траффик сервера из локальной сети (это можно сделать и с подходом автора, но тут это вписывается в модель :) )
                                        • теоретически, меньшая нагрузка на роутер при большом траффике (с удовольствием бы проверил, но свободной железки нет :( )
                                          0
                                          1-2. Даже не думал об этом, но да :)
                                          Хотя в микроте это не сложно посмотреть, если история не нужна.
                                          4. меньшая нагрузка точно, микроты до/включая 1100ah2 на гигабитных скоростях очень маркировку любят превращать в пожирание cpu, в ccr это получше выглядит
                                          Но сирано конфига — жесть :)
                                          Как решали без подмены днс доступность сайта а-ля hairpin nat? Тут вроде только conn mark катит, имхо
                                            0
                                            Я лично использовал DNS подход, вы знаете какие-то случаи, когда это плохо работает?
                                              +1
                                              если машин для форварда много и порты для них разные — кучка dns A/AAAA записей?
                                            0
                                            А что делать с UPnP для узлов из LAN в вашем сценарии?
                                              0
                                              Как сами понимаете — никак, я UPnP не использую (старовер).
                                              Если вам нужен UPnP — то остается вариант автора.
                                      0
                                      Вариант, но с манглом не проще разве?
                                      Еще и на web-сервере алиасы настраивать, зачем?

                                      А если нам нужно еще почту прокинуть, SIP, еще 50 портов, мы что, тоже будем везде алиасы вешать?
                                        0
                                        Я выше описал плюсы своего подхода, но да, у него есть и минусы.
                                        Если у вас сервисы на разных серверах, то алиасы/vlan-ы должны быть на каждом.
                                        Если же все на одном сервере, имхо, мой подход проще.
                                          0
                                          Как написали в одном паблике в ВК, после данной публикации, — «Каждый готовит MikroTik по своему»
                                          По этому, считаю, нам не стоит продолжать полемику в поиске единственно верного решения

                                          Если у вас сервисы на разных серверах, то алиасы/vlan-ы должны быть на каждом.

                                          зачем? Не совсем понял вашу мысль.
                                          Есть внутри web-сервер, почтовый, телефония, каждый должен иметь по несколько IP?
                                      +1
                                      Возможно, я немного поспешил с выводами.
                                      Как показали комментарии, есть много сценариев, где ваш подход выручает (UPnP, пару сотен серверов).
                                      Возьму на заметку, спасибо.
                                        0
                                        Рад, если статья окажется полезной.
                                    0
                                    Да не, автор в теме ;)
                                    рулсами мы не раскрасим транзитный трафик, если я ошибаюсь, то дайте конфиг.
                                    +1
                                    rules lookup не рассмотрели, количество правил бы уменьшилось
                                      0
                                      решил не городить огороды и сделать все в мангл
                                        0
                                        когда конфига будет страниц в 12-50, в мангл страшно будет заглядывать
                                        казалось бы дел на секунду, надо добавить какое-нить одно правило, а сидишь с умным лицом полчаса. В особенности ежели наличествует дикий qos ;)
                                          0
                                          забыли нарисовать аналог hairpin nat для нескольких wan, я делал через mangle, тож развесисто получается
                                        0
                                        Более элегантно это выглядело с помощью PBR(Policy Based Routing).

                                        Если не знаете этот метод — посмотрите статью Чудина за прошлый год(в гугле «Чудин Mikrotik»)
                                          0
                                          vrf lite в комментах присутствует :)
                                          0
                                          ему доступны не напрямую, а рекурсивно через данные статические маршруты. По одному IP на брата-провайдера.

                                          А где мы указываем статические маршруты, если они у нас имеют routing-mark, согласно вашим правилам?
                                          Т.е. нам надо создать ещё и такие правила?


                                          add distance=1 gateway=95.11.29.254
                                          add distance=1 gateway=5.35.59.161
                                            0

                                            Просто если всё сделать как указано в статье, то из локальной сети ничего работать не будет, т.к. роутер будет отвечать что


                                            [192.168.88.1] сообщает: Заданная сеть недоступна.
                                              0
                                              Пробовали hairpin nat делать?
                                                +1

                                                Да, для меня это обязательное условие.
                                                А с этой проблемой разобрался.


                                                Очень краткая выжимка
                                                in-interface=ISP1 - первый провайдер (основной)
                                                in-interface=ISP2 - второй провайдер (резервный)
                                                in-interface=ISP3 - третий провайдер (резервный резервного)
                                                in-interface=bridge - интерфейс локальной сети
                                                
                                                /interface list add name=WAN
                                                
                                                /interface list member add interface=ISP1 list=WAN
                                                /interface list member add interface=ISP2 list=WAN
                                                /interface list member add interface=ISP3 list=WAN
                                                
                                                /ip route add distance=1 gateway=11.11.11.11 routing-mark=ISP1-route comment="https://habrahabr.ru/post/313342/"
                                                /ip route add distance=1 gateway=22.22.22.22 routing-mark=ISP2-route comment="https://habrahabr.ru/post/313342/"
                                                /ip route add distance=1 gateway=33.33.33.33 routing-mark=ISP3-route comment="https://habrahabr.ru/post/313342/"
                                                
                                                /ip route add check-gateway=ping distance=1 gateway=8.8.8.8 comment="https://habrahabr.ru/post/313342/"
                                                /ip route add check-gateway=ping distance=2 gateway=8.8.4.4 comment="https://habrahabr.ru/post/313342/"
                                                /ip route add check-gateway=ping distance=3 gateway=1.1.1.1 comment="https://habrahabr.ru/post/313342/"
                                                
                                                /ip route add distance=1 dst-address=8.8.8.8/32 gateway=11.11.11.11 scope=10 comment="https://habrahabr.ru/post/313342/"
                                                /ip route add distance=1 dst-address=8.8.4.4/32 gateway=22.22.22.22 scope=10 comment="https://habrahabr.ru/post/313342/"
                                                /ip route add distance=1 dst-address=1.1.1.1/32 gateway=33.33.33.33 scope=10 comment="https://habrahabr.ru/post/313342/"
                                                
                                                /ip firewall mangle add action=mark-connection chain=input in-interface=ISP1 new-connection-mark=ISP1-conn passthrough=yes comment="https://habrahabr.ru/post/313342/"
                                                /ip firewall mangle add action=mark-routing chain=output connection-mark=ISP1-conn new-routing-mark=ISP1-route passthrough=no comment="https://habrahabr.ru/post/313342/"
                                                
                                                /ip firewall mangle add action=mark-connection chain=input in-interface=ISP2 new-connection-mark=ISP2-conn passthrough=yes comment="https://habrahabr.ru/post/313342/"
                                                /ip firewall mangle add action=mark-routing chain=output connection-mark=ISP2-conn new-routing-mark=ISP2-route passthrough=no comment="https://habrahabr.ru/post/313342/"
                                                
                                                /ip firewall mangle add action=mark-connection chain=input in-interface=ISP3 new-connection-mark=ISP3-conn passthrough=yes comment="https://habrahabr.ru/post/313342/"
                                                /ip firewall mangle add action=mark-routing chain=output connection-mark=ISP3-conn new-routing-mark=ISP3-route passthrough=no comment="https://habrahabr.ru/post/313342/"
                                                
                                                /ip firewall mangle add action=mark-connection chain=forward in-interface=ISP1 new-connection-mark=ISP1-conn-f passthrough=no comment="https://habrahabr.ru/post/313342/"
                                                /ip firewall mangle add action=mark-routing chain=prerouting connection-mark=ISP1-conn-f in-interface=bridge new-routing-mark=ISP1-route comment="https://habrahabr.ru/post/313342/"
                                                
                                                /ip firewall mangle add action=mark-connection chain=forward in-interface=ISP2 new-connection-mark=ISP2-conn-f passthrough=no comment="https://habrahabr.ru/post/313342/"
                                                /ip firewall mangle add action=mark-routing chain=prerouting connection-mark=ISP2-conn-f in-interface=bridge new-routing-mark=ISP2-route comment="https://habrahabr.ru/post/313342/"
                                                
                                                /ip firewall mangle add action=mark-connection chain=forward in-interface=ISP3 new-connection-mark=ISP3-conn-f passthrough=no comment="https://habrahabr.ru/post/313342/"
                                                /ip firewall mangle add action=mark-routing chain=prerouting connection-mark=ISP3-conn-f in-interface=bridge new-routing-mark=ISP3-route comment="https://habrahabr.ru/post/313342/"
                                                  0
                                                  Спасибо за выжимку! А с исходящим с LAN интернетом нет проблем, при падении провайдера? Вообще, исходящий интернет как работает? Тоже в режиме резерва второго, третьего… провайдера? Или делит поровну?
                                                    +1

                                                    Исходящий и входящий будут идти через первого по порядку рабочего провайдера и будет работать через него до тех пор, пока established соединение не будет разорвано и new connection не пойдёт через рабочего.
                                                    Удобно для торрента, если анонсирование прошло через резервного и потом основной восстановился, то соединения будут идти через основной и резерный, суммируя скорости.

                                            0
                                            Спасибо Вам, помогли с решением похожей задачи!
                                              0
                                              Спасибо за статью! У меня в mungle вместо input работает с prerouting.
                                                0
                                                Вопрос, если есть два провайдера, и по качеству они более-менее одинаковые, и хочется их чередовать, например, каждую полночь меняя местами основной и вторичный? Можно ли это реализовать как-то через вызов какого-то скрипта в планировщике?
                                                  +1
                                                  Можно.
                                                  Просто меняйте default gw.
                                                    0
                                                    а можно по-другому, например пусть маршруты:
                                                    /ip route
                                                    add check-gateway=ping distance=1 gateway=8.8.8.8
                                                    add check-gateway=ping distance=2 gateway=8.8.4.4

                                                    имеют соответственно номера 4 и 5, и тогда в скрипте планировщика делать такую команду:
                                                    /ip route
                                                    set distance=1 number=5
                                                    set distance=2 number=4

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

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

                                                  Самое читаемое