image

Нечасто, но с завидной периодичностью на профильных форумах возникал один и тот же вопрос: «как на одном интерфейсе роутера MikroTik получить два IP-адреса с разными MAC?». Обычно этот вопрос остается без ответа, либо вопрошающему отвечают «никак». И действительно, задача нетривиальная. В стандартной конфигурации соблюдается правило «1 интерфейс = 1 MAC». В этой статье я расскажу как обойти это ограничение используя расширенный функционал MikroTik.

Сначала вспомним матчасть RouterBoard. Помимо маршрутизации, устройства MikroTik могут выполнять и коммутацию. Для этого некоторые из них имеют отдельный свитч-чип, а также возможность объединять интерфейсы с помощью программного коммутатора — bridge. Bridge (в русской терминологии «мост») производит коммутацию пакетов за счёт ресурсов процессора устройства. С помощью моста также объединяют между собой разнородные ethernet-образные инетрфейсы — ethernet, wlan, vlan, eoip, vpls.

image

Мост в иерархии интерфейсов микротик является более высокой, объединяющей сущностью. При объединении интерфейсов с помощью моста, на него устанавливается MAC-адрес, который будет транслироваться во все подчиненные (slave) интерфейсы. MAC-адреса подчиненных интерфейсов перестают использоваться и заменяются в исходящих фреймах MAC-адресом моста.

Соответственно, IP-адрес и все службы связанные с протоколом IP должны быть привязаны НЕ к зависимым интерфейсам, а к вышестоящему мосту.

За счёт того, что мост реализован ресурсами CPU, он имеет очень широкий функционал по управлению трафиком. Фильтрация входящих и транзитных пакетов, а также возможность трансляции MAC-адресов сразу привлекли моё внимание. Итак, инструментом решения задачи будет bridge, точнее bridge NAT.

image

Приступим. У нашего подопытного маршрутизатора есть внутренний мост «bridge-local», которому присвоен адрес 192.0.2.1/24 и который является шлюзом для компьютеров локальной сети. Для «bridge-local» администратором назначен MAC D4:CA:6D:C7:11:11 Физический интерфейс Ether2 является одним из подчиненных (slave) портов моста «bridge-local» и непосредственно соединяется с локальной сетью.

Задача: добавить на маршрутизатор адрес из той же IP-подсети, но с другим MAC-адресом. Для примера выбрано сочетание IP 192.0.2.111/24 и MAC: D4:CA:6D:C7:22:22

Поскольку в лоб правило «1 интерфейс = 1 MAC» преодолеть нельзя, мы пойдем в обход. Для начала создадим вспомогательный интерфейс «bridge111» куда навесим дополнительный IP-адрес и MAC:

RouterOS command
/interface bridge add admin-mac=D4:CA:6D:C7:22:22 auto-mac=no name=bridge111 protocol-mode=none


Теперь разбираемся, что, откуда и куда нужно будет подменять используя мост. Для этого заглянем в описание протокола ARP: ru.wikipedia.org/wiki/ARP#.D0.9F.D1.80.D0.B8.D0.BD.D1.86.D0.B8.D0.BF_.D1.80.D0.B0.D0.B1.D0.BE.D1.82.D1.8B
Очевидно, что нам нужно перехватывать ARP-запросы узлов запрашивающих MAC устройства имеющего IP 192.0.2.111. Для этого в NAT существует отдельный action «arp-reply»:

RouterOS command
/interface bridge nat add action=arp-reply arp-dst-address=192.0.2.111/32 chain=dstnat dst-mac-address=FF:FF:FF:FF:FF:FF/FF:FF:FF:FF:FF:FF in-bridge=bridge-local mac-protocol=arp to-arp-reply-mac-address=D4:CA:6D:C7:22:22


Попытка выполнить с компьютера команду «ping 192.0.2.111» явного результата не дала, однако при просмотре на компьютере локальной arp-таблицы стало видно сопоставление нового IP-адреса с новым MAC. Получается протокол ARP мы победили.
image

Переходим к следующему шагу — нам нужно добиться связности по IP. Для этого захватываем пакеты идущие на дополнительную пару MAC+IP:

RouterOS command
/interface bridge add action=redirect chain=dstnat dst-address=192.0.2.111/32 in-bridge=bridge-local mac-protocol=ip


После этой команды появляется некое подобие связности. Локальная ARP-таблица компьютера содержит две записи — по одной для каждой пары MAC+IP. MAC-адреса в ней различаются, так как мы и хотели. Пинг до адреса 192.0.2.111 и ответы исправно прилетают.

Но давайте посмотрим на принятые пакеты через wireshark:

image

Мы видим, что echo-ответы идут с MAC-адреса D4:CA:6D:C7:11:11, связанного с первым IP-адресом 192.0.2.1. И хотя связность есть, решение является незаконченным. Нам необходимо также подменять MAC-адреса в исходящих от роутера пакетах, имеющих src-ip 192.0.2.111. Сделаем это:

RouterOS command
/interface bridge nat add action=src-nat chain=srcnat mac-protocol=ip src-address=192.0.2.111/32 src-mac-address=D4:CA:6D:C7:11:11/FF:FF:FF:FF:FF:FF to-src-mac-address=D4:CA:6D:C7:22:22


Вот, теперь пакеты в сети выглядят правильно — имеют правильное сочетание src-IP и src-MAC:

image

В окошке winbox настроенные правила преобразования выглядят так:

image

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

image

Update: добавил результаты теста с включенным и с выключенным Bridge L2-NAT.
Для теста использовался RB951Ui-2HnD с процессором AR9344. Загрузка процессора изменяется незначительно, в пределах погрешности измерительных инструментов. В среднем рост составил 2% на 100M интерфейсе.

L2-NAT выключен:
image

L2-NAT включён:

image

Комментарии (18)


  1. onegreyonewhite
    23.09.2017 03:47

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


    1. nkusnetsov Автор
      23.09.2017 07:20
      +1

      Конечно, процессор всегда нагружается при дополнительной обработке пакетов. Но иногда приходится с этим смириться, если нет другого варианта.
      Кстати, вот пример вопроса на соседнем ресурсе: toster.ru/q/276217
      Альтернатива — в разрыв линка установить отдельный свитч и два патч-корда в два разных порта МТ, или в один порт на два VLAN опять же, через внешний «умный» свитч.


      1. onegreyonewhite
        23.09.2017 07:51

        Лучшее решение автор вопроса сам предложил: зарегистрировать оба адреса на один mac.
        Дело не в дополнительной обработке пакетов, а в том, что микротик будет ядром пакеты перерабатывать даже когда это не нужно. Если даже просто два интерфейса между собой мостом соединить, то при 100мб/с процессор только и будет заниматься пакетами этого моста.


        1. nkusnetsov Автор
          23.09.2017 08:11
          +1

          Мне кажется Вы недооцениваете мощность процессора. На неоптимизированной системе «из коробки», при наличии простого фаервола прирост нагрузки CPU составил в среднем +2%, в редких пиках подскакивал до +10%. См. результат теста в конце статьи.


  1. Dobrumir
    23.09.2017 07:15
    +1

    >RouterOS command
    >/interface bridge nat add action=src-nat chain=srcnat mac-protocol=ip src->address=192.168.10.111/32 src-mac-address=D4:CA:6D:C7:11:11/FF:FF:FF:FF:FF:FF to-src-mac->address=D4:CA:6D:C7:22:22
    Точно 192.168.10.111/32?


    1. nkusnetsov Автор
      23.09.2017 07:15

      Спасибо, вкралась опечатка. Исправил.


  1. native
    23.09.2017 10:50

    а что делать, если ip-адреса нужно получить по dhcp?


    1. nkusnetsov Автор
      23.09.2017 13:42

      В данном случае с dhcp не всё получится, т.к. в arp-reply идет работа с заранее известным IP-адресом. Нормально dhcp-client отработает только на основном интерфейсе «bridge-local»


  1. ElvenSailor
    23.09.2017 13:42

    А можно хоть один пример из практики, когда поодобное реально может понадобиться?


    1. nkusnetsov Автор
      23.09.2017 13:46

      1) Когда провайдер даёт два IP с привязкой к разным макам на одном физическом порту.
      2) Имитировать физическое присутствие некоего оборудования на площадке, фактически висящего в другой отдаленной сети — не зависит от удаленного маршрутизатора, т.к. не требует L2 туннелирования через EoIP или VPLS.


      1. sigmatik
        23.09.2017 19:15

        А такое бывает? Я про провайдера… и главное зачем?


        1. pr0l
          23.09.2017 22:15

          когда необходимо поднять 2 и более ПППоЕ до провайдера например


        1. nkusnetsov Автор
          23.09.2017 22:36

          Наблюдал одного провайдера, у которого долгое время было жесткое правило «Один IP = один MAC». Потом узнал, что ограничение было связано как-то с их биллингом. То ли самописный он был, то ли просто специалистов по настройке этого биллинга небыло в штате.


  1. HeroFromEarth
    23.09.2017 13:46

    Коллеги, а есть ли объективные причины, по которым MikroTik не реализует функционал сабинтерфейсов?


  1. pr0l
    23.09.2017 22:13
    +1

    а так не легче?
    Может кому то будет интересно или пригодится, на официальном форуме микротика нашел вполне рабочий вариант использовать 3-х связок IP-MAC на одном интерфейсе (мне просто больше не нужно), способ подразумевает использование интерфейсов VRRP, вот собственно и часть конфига:

    Сейчас тестирую у себя, пока всё ок.

    /interface vrrp
    add interface=ether1 name=vrrp1 vrid=1
    add interface=ether1 name=vrrp2 vrid=2
    add interface=ether1 name=vrrp3 vrid=3
    # VRRP interface needs some static address to come up:
    /ip address
    add address=127.0.0.2/32 interface=vrrp1 network=127.0.0.2
    add address=127.0.0.3/32 interface=vrrp2 network=127.0.0.3
    add address=127.0.0.4/32 interface=vrrp3 network=127.0.0.4
    /ip dhcp-client
    add default-route-distance=0 dhcp-options=hostname,clientid disabled=no \
    interface=ether1
    add add-default-route=no dhcp-options=hostname,clientid disabled=no interface=\
    vrrp1 use-peer-dns=no use-peer-ntp=no
    add add-default-route=no dhcp-options=hostname,clientid disabled=no interface=\
    vrrp2 use-peer-dns=no use-peer-ntp=no
    add add-default-route=no dhcp-options=hostname,clientid disabled=no interface=\
    vrrp3 use-peer-dns=no use-peer-ntp=no

    It's definitely not a proper solution and I'm not sure about all possible side effects. But at the first sight, it works:
    ros code

    Flags: X - disabled, I - invalid, D - dynamic
    # ADDRESS NETWORK INTERFACE
    0 127.0.0.2/32 127.0.0.2 vrrp1
    1 127.0.0.3/32 127.0.0.3 vrrp2
    2 127.0.0.4/32 127.0.0.4 vrrp3
    3 D 192.168.80.50/24 192.168.80.0 ether1
    4 D 192.168.80.48/24 192.168.80.0 vrrp2
    5 D 192.168.80.47/24 192.168.80.0 vrrp3
    6 D 192.168.80.49/24 192.168.80.0 vrrp1


    1. nkusnetsov Автор
      23.09.2017 22:32

      Интересный способ. Главное, относительно простой.
      Но к сожалению, для vrrp-интерфейса невозможно задать произвольный MAC-адрес, т.к. он определен стандартом «0000:5E00:01xx, где xx — номер группы VRRP».
      Из других моментов: vrrp пытается искать соседа по мультикасту и трафик может быть перехвачен с последующим захватом роли master. Версия VRRP v3 включаемая по-умолчанию не поддерживает аутентификацию, что настораживает.
      Если делать это на том же роутере, где на основном интерфейсе поднят DHCP-сервер то, dhcp-client не получает IP.


      1. Chupaka
        24.09.2017 19:02

        Если делать это на том же роутере, где на основном интерфейсе поднят DHCP-сервер то, dhcp-client не получает IP.

        У меня связка "dhcp-клиент на ethernet + dhcp-клиент на vrrp поверх этого ethernet" работает нормально. Касательно MAC-адресов — можно попробовать поиграться справилами Bridge NAT, как в этой статье.


  1. AEP
    24.09.2017 22:14

    А теперь, пожалуйста, то же самое, но для IPv6.