Что такое встроенная сеть (embedded network)? Мне довольно сложно было найти подходящее название для этого явления, но я очень часто с ним сталкивался, и поэтому придумал своё. Хорошим примером может служить портативная видеостойка. Допустим, вы таскаете стойку с видео- и сетевым оборудованием, и вам нужно подключать её к сети на месте проведения мероприятия для стриминга в Интернет. Устройства в стойке должны общаться друг с другом, но вы не хотите заново конфигурировать их адреса каждый раз, когда приезжаете на новое место, потому что в нём используется другая подсеть.

Решить эту проблему очень просто! Достаточно добавить в стойку небольшой маршрутизатор, чтобы у вас была постоянная подсеть, а NAT изолирует вас от изменения IP-адресов снаружи вашей маленькой сети. Ваша стойка имеет адреса 10.0.0.0/24, потому что их легко запомнить, а маршрутизатор получает IP-адрес на месте при помощи DHCP.

Всё это замечательно работает, пока не оказывается, что публичная сеть на месте проведения мероприятия тоже находится в сети 10.0.0.0/24. У маршрутизатора внезапно появляется одна и та же подсеть на обоих интерфейсах, а адреса в стойке начинают конфликтовать с другим оборудованием.

На этом этапе часто начинают выбирать для портативного оборудования странные подсети. «Каковы шансы, что на месте будет использоваться подсеть 172.16.42.0/24 или 10.11.12.0/24?» И да, это будет работать, но однажды у вас возникнет конфликт, потому что люди попросту не очень хорошо справляются с выбором случайных чисел. На самом деле, необязательно, чтобы сеть зависела от случайности, вам просто нужны другие возможности маршрутизаторов, нечасто применяемые в стандартных потребительских моделях.

Решение с IPv6

Наиболее официальное решение — это, разумеется, IPv6. Если внутри вашей приватной сети используется IPv6, то можно просто адресовать каждое устройство по его локальному адресу канала. Так как маршрутизатор разделяет сегмент сети между стойкой и публичной сетью, вы будете знать, что все локальные адреса каналов всегда будут вашими собственными устройствами.

Вам даже больше не понадобится DHCP-сервер в локальной сети. Каждое IPv6-устройство просто получает собственный адрес fe80::, а вы будете использовать протоколы сетевого обнаружения для нахождения адреса устройства. Например, для ресолвинга имён для этих адресов можно применять avahi.

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

Огромная проблема такого решения заключается в том, что поддержка IPv6 в устройствах, отличающихся от обычных компьютеров общего назначения, практически отсутствует. Прямо сейчас под рукой у меня есть портативная стойка с аудиомикшером Behringer X-Air, но он позволяет лишь использовать DHCP для получения адреса, никакой поддержки IPv6 в нём нет. Если взять произвольный видеомикшер, то, скорее всего, он не будет поддерживать IPv6, а в некоторых даже и DHCP ещё нет.

Строго говоря, такое же решение можно реализовать и в сети IPv4. Вероятно, вы с ним уже сталкивались: получали адрес 169.254.0.0/16 на компьютере при выборе DHCP, когда в сети нет работающего DHCP-сервера. Это адрес APIPA, в IPv4 эквивалентный адресу IPv6 fe80::. К сожалению, в данной ситуации такое решение не очень подходит, потому что при работе с сетью APIPA никак не создать шлюз, так что доступа к Интернету у вас не будет. Кроме того, если ваша машина получает валидный IP-адрес для подключения к Интернету, то адрес APIPA обычно сбрасывается на этом интерфейсе, потому что больше не требуется. Как и в случае с поддержкой IPv6 во встроенном оборудовании, чаще всего он не реализуется.

Здесь можно использовать следующий трюк, если вы имеете с сетью IPv6 и ищете адреса хостов в вашем сегменте:

$ ping -c 2 -I enp3s0 ff02::1
... здесь ответы от различных устройств ...
$ ip -6 neigh show dev enp3s0
fe80::cc55:13ff:fe9b:82a2 lladdr ce:55:13:9b:82:a2 REACHABLE 
fe80::df8c:9c93:6850:7132 lladdr b0:35:9f:5a:b2:49 REACHABLE 
fe80::ac2b:55ff:fe62:a34 lladdr ae:2b:55:63:0a:34 REACHABLE 
fe80::a0b8:78ff:fe5c:8229 lladdr a2:b8:78:5a:82:29 REACHABLE 
fe80::5660:9ff:fee1:cb4b lladdr 54:60:09:e1:cb:4b REACHABLE 
fe80::f61e:57ff:fe61:9a58 lladdr f4:1e:57:91:9a:58 router REACHABLE

Так можно отправить локальному сегменту широковещательный пинг, а потом считать список соседей, известных на этом интерфейсе, что также позволит вам узнать, какое из устройств рассылает уведомления о маршрутах. ff02::1 — это один из «примечательных групповых адресов ipv6», удобный список которых есть в Википедии.

Более общее решение

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

Это значит, что ваша внутренняя сеть может иметь вид 10.0.0.0/24 и внешняя сеть (на месте проведения мероприятия) тоже может быть 10.0.0.0/24, и всё без проблем будет работать. Видеомикшер в стойке может иметь адрес 10.0.0.4 и в внешней сети может быть адрес 10.0.0.4, но при этом ничто не будет конфликтовать. Разумеется, при таком решении придётся идти на компромисс; в данном случае он заключается в том, что вы больше не сможете дотягиваться до устройств в внешней сети, но это не должно стать проблемой, если вы подключаетесь к ней только для доступа к Интернету.

Волшебным решением здесь могут быть VRF. Обычно у маршрутизатора есть только одна таблица маршрутизации, определяющая, куда должен двигаться трафик на основании адреса получателя. Таблица маршрутизации — основная проблема в данной ситуации, потому что при наличии одинаковых подсетей внутри и снаружи в таблице просто будет два маршрута, сообщающих, что 10.0.0.0/24 должен относиться к интерфейсу LAN и к интерфейсу WAN.

$ ip route
default via 10.0.0.1 dev enp1s0 proto dhcp src 10.0.0.33 metric 100
10.0.0.0/24 dev enp1s0 proto kernel scope link src 10.0.0.33 metric 100
10.0.0.0/24 dev enp2s0 proto kernel scope link src 10.0.0.254 metric 100

По сути, мы сообщаем маршрутизатору, что одна и та же сеть 10.0.0.0/24 достижима по обоим интерфейсам. Единственный способ сообщить ядру, что на самом деле они отдельные — использование VRF.

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

В моей тестовой системе я использовал устройство Mikrotik, потому что оно позволило мне конфигурировать VRF, так как у меня не было Linux-устройства с достаточным количеством интерфейсов для создания простого теста. Но в то же время это показывает, что подобная система не настолько эзотерична, что для её маршрутизации понадобился бы полнофункциональный PC. Я выбрал Mikrotik hAP mini, это трёхпортовый маршрутизатор за $15 — вероятно, самое дешёвое из устройств с этой функцией. Для тестирования у меня есть порт WAN (ether1) подключённый к моей домашней сети, а два других порта подключены к ноутбукам, которые должны общаться друг между другом, но оставаться изолированными от домашней сети.

Базовая конфигурация, уже настроенная в этом устройстве, позволяет ему обеспечивать NAT между двумя портами LAN и портом WAN, поэтому единственное, что мне оставалось сделать — разбить их, сделав внутреннюю подсеть такой же, что и у моей домашней сети, а затем сконфигурировать всё, что связано с VRF, для правильной маршрутизации.

# У bridge-internal есть два порта для внутренних устройств
/interface bridge
add name=bridge-internal
/interface bridge port
add bridge=bridge-internal interface=ether2
add bridge=bridge-internal interface=ether3

# Даём маршрутизатору адрес во внутренней сети
/ip address
add address=10.0.0.1/24 interface=bridge-internal

# Получаем адрес для интерфейса WAN от DHCP
/ip dhcp-client
add interface=ether1

# Создаём vrf стойки для bridge
/ip vrf
add interfaces=bridge-internal name=rack

# VRF в стойке сообщает ей, что шлюз по умолчанию находится в основной VRF
# по адресу 10.0.0.254. IP шлюза _может_ быть тоже может быть адресом 10.0.0.1, 
# который я использовал для этого маршрутизатора, но в данном случае я сделал их разными,
# чтобы конфигурация была понятнее
/ip route
add gateway=10.0.0.254@main routing-table=rack

# Правило iptables для обычного использования NAT для всего трафика, исходящего через порт WAN
/ip firewall nat
add action=masquerade chain=srcnat out-interface=ether1

# Используем отслеживание соединения, чтобы помечать трафик от внутренней VRF с целью доставки
# обратного трафика на ту же VRF. Первое правило даёт соединению
# пометку "rack" в таблице отслеживания соединений. Второе правило
# сопоставляет трафик с порта WAN, соответствующего соединению, имеющему
# пометку "rack", а затем настраивает таблицу маршрутизации для использования "rack", то есть
# VRF. Это цепочка предварительной маршрутизации, поэтому эти правила исполняются
# до того, как производятся действия с таблицами маршрутизации.
/ip firewall mangle
add action=mark-connection chain=prerouting connection-state=new in-interface=bridge-internal new-connection-mark=rack
add action=mark-routing chain=prerouting connection-mark=rack in-interface=ether1 new-routing-mark=rack

Вот и всё, что нужно. Трафик, обрабатываемый VRF стойки, доставляется на интерфейсы, связанные с этой VRF. Трафик для основной таблицы маршрутизации выходит из порта WAN.

Чтобы предназначенный для Интернета трафик пересекал границу между таблицами маршрутизации, в VRF добавляется маршрут, отправляющий предназначенный для Интернета трафик на адрес шлюза по умолчанию в основной таблице маршрутизации. Она пропускает его через правила файрволла и применяет стандартное правило NAT, заменяющее адрес отправителя на адрес маршрутизатора. Также в трекер соединений добавляется пометка соединения, сообщающая iptables, что источником этого соединения была VRF стойки.

Когда пакет возвращается из Интернета, трекер соединений iptables сопоставляет его с соединением, у которого есть пометка соединения. При этом срабатывает ещё одно mangle-правило, гарантирующее, что этот пакет обрабатывается VRF стойки, чтобы он был отправлен обратно на устройств в стойке, создавшее это соединение.

Всё это позволяет устройствам в стойке иметь подключение к Интернету, как будто это обычное подключение с NAT. Однако через него невозможно получить доступ к другим устройствам в моей домашней сети, потому что таблица маршрутизации для стойки просто будет отправлять предназначенный для 10.0.0.0/24 обратно по тому же интерфейсу, а не через порт WAN. То же самое происходит, когда устройство в домашней сети пытается использовать маршрутизатор в качестве шлюза для доступа к устройству в стойке.

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

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

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


  1. net_racoon
    03.09.2025 08:41

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


    1. BDI
      03.09.2025 08:41

      можно использовать DHCP для внутренней подсети и менять адресацию одной командой

      Ожидал такого решения походу чтения этой статьи(самое простое - заготовить два диапазона, и если первый используется на внешней сети, то отключать его), пока не наткнулся на упоминание устройств умеющих только статический IP4. В этом случае смена выдаваемых DHCP адресов проблему полностью не решает.


      1. SerjV
        03.09.2025 08:41

        Или умеющих не только статический, но по неким причинам требующим именно статического для цели использования. Даже не "прибитого" к устройству на DHCP сервере, а именно статического.

        Так-то иначе можно и по DHCP постоянный адрес устройству выдавать.

        Другое дело, что автор, используя VRF, обошелся без упоминания MPLS :)

        Ибо самое интересное начинается в случае, если совпадающая адресация оказывается не в разных физических сетях. До некоторого количества совпадающих сетей это разруливается за счёт VLAN'ов и управляемых коммутаторов, конечно.


        1. sirmax123
          03.09.2025 08:41

          Другое дело, что автор, используя VRF, обошелся без упоминания MPLS :)

          Мне нравится эта шутка )


        1. mayorovp
          03.09.2025 08:41

          Совпадающая адресация в пределах одной embedded network - это нечто запредельно странное, как и MPLS.


          1. sirmax123
            03.09.2025 08:41

            Что бы абсолютно точно не было никогда никакого совпадения без VRF и MPLS достаточно было бы "позаимствовать" честную белую сеть, про которую вы точно знаете что она никогда вам не пригодится, зарегестрированную за условным Зимбабве и туда же смаршрутизированную

            Вероятность что вы захотите установить прямой коннект с каким-то пользователем "Зимбабве-телеком" исчезающе мала

            Это если совсем лень адресацию менять каждый раз.

            Второй варинат - more specific
            Я очень сомневаюсь что автору на самом деле нужно /24 в его стойке,
            /28 где то из bogon если не хочется брать реальник,
            из середины диапазона, что бы меньше вероятность сопадения со шлюзом была


          1. SerjV
            03.09.2025 08:41

            Зависит от кейса использования.

            У автора указано, что речь идёт о комплекте устройств, которые перевозятся с места на место для организации мероприятий. Подключение к Инету обеспечивает принимающая площадка

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

            Еще может случиться интеграция всяких legacy сетей, например технологических, которые строились независимо друг от друга, но в какой-то момент понадобилось получить к ним централизованный доступ. Мотаться по региону перенастраивать, например, приборы учёта, ради этой цели вряд ли целесообразно.

            Если сеть планируются с нуля изначально - то да, подобная проблема может возникнуть только у оператора связи или ЦОДа. Но вот там одной лишь технологии VRF маловато будет, какой-нибудь MPLS и/или VXLAN понадобятся.


    1. firegurafiku
      03.09.2025 08:41

      ИМХО проблема высосана из пальца

      Не совсем так. Представьте, что вы разрабатываете комплекс «под ключ» (например, маленькую производственную линию) и вашим устройствам от внешней сети нужен только интернет (условно, для проверки лицензии и передачи телеметрии). При этом вы не хотите даже знать, какие там адреса подсетей у клиента на объекте и какой там интернет-провайдер, и тем более, нечаянно с ними пересечься. При таких вводных приведённое в статье решение будет максимально беспроблемным.

      благо в 10ой сети их много

      Нельзя заранее быть уверенным, что админ условного завода не забрал себе всю 10.0.0.0/8 под локальную сеть.


  1. sirmax123
    03.09.2025 08:41

    Нельзя заранее быть уверенным, что админ условного завода не забрал себе всю 10.0.0.0/8 под локальную сеть.

    Конечно нет но вам вся и не нужна - главное что бы шлюз был доступен


    1. mgnhabrauser
      03.09.2025 08:41

      И в какой интерфейс уйдет запрос на 10.0.0.1?


      1. mayorovp
        03.09.2025 08:41

        Во внешнюю, если только для внутренней не взята сеть со всеми нулями.


  1. omaxx
    03.09.2025 08:41

    Можно использовать 169.254.0.0/16 для внутренней адресации


  1. Whols
    03.09.2025 08:41

    Чтобы в стойке были доступны устройства при конфликте IP снаружи достаточно прибить арпы на управляемом коммутаторе.


    1. omaxx
      03.09.2025 08:41

      На коммутаторе нет арпов :(


      1. Whols
        03.09.2025 08:41

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


        1. MKudryavcev
          03.09.2025 08:41

          И зачем коммутатору знать на каком порту сидит ip?


          1. Whols
            03.09.2025 08:41

            -


        1. omaxx
          03.09.2025 08:41

          Коммутатору незачем знать, где какой ip адрес, т.к. это L2 устройство. Вы путаете с mac address table


          1. Whols
            03.09.2025 08:41

            Да, подзабыл уже малость. Спасибо что поправили, CAM-таблица. В которой мы прибиваем маки к портам. Сути не меняет. Работает железно в любой сети с идентичным IP адресами.


            1. omaxx
              03.09.2025 08:41

              Нет... это вам никак не поможет в данной ситуации


              1. Whols
                03.09.2025 08:41

                У меня так год стойка работала. С преднастроенными IP, биндом маков на портах коммутатора и мне было похрен на внешнюю адресацию ЗА пределами свитча. Единственное условие - уникальный IP шлюза во внешней сети. Видеосервер на него-таки должен был выходить.


                1. mayorovp
                  03.09.2025 08:41

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


                  1. Whols
                    03.09.2025 08:41

                    Конфликты гарантированно были, иначе не пришлось бы ничего биндить. Оборудование отвечало не "первее", а гарантированно по нужным портам тк flood с входящего аплинка был прибит. а пересылка внутри сегмента - только на один порт. Как видите, никаких чудес.


                    1. mayorovp
                      03.09.2025 08:41

                      Бинд маков на портах коммутатора устраняет конфликт MAC-адресов, но абсолютно никак не влияет на конфликты IP-адресов.


        1. SerjV
          03.09.2025 08:41

          "Простой" управляемый коммутатор знает про ARP только на management интерфейсе (физическом или виртуальном, смотрящем в управляемую сеть).

          На всех остальных интерфейсах он интересуется только MAC-адресами. Ему вообще плавать, работает поверх Ethernet IP или какой-нибудь (кто еще помнит?) IPX, или еще что-то.

          L3 свитч уже да, что-то знает, но это гибрид свитча и роутера.


      1. Whols
        03.09.2025 08:41

        На коммутаторе нет арпов :(

        Держи, в качестве ликбеза. Cisco SF300
        Держи, в качестве ликбеза. Cisco SF300


        1. mayorovp
          03.09.2025 08:41

          Погуглил устройство - это не управляемый коммутатор, это L3 коммутатор. "Немножко" разные вещи.

          Ещё бы понять в каком режиме ARP у вас там настроен, по умолчанию даже L3 коммутаторы не имеют к нему никакого отношения, но вроде как раз у цисок есть странно-костыльные опции работы с этим протоколом.


  1. VMcS
    03.09.2025 08:41

    Использовать Link-Local адресов (LLA) для встроенной сети вполне возможно и даже приемлимо, если все устройства находятся в общем канальном сегменте. Даже если есть несколько соединенных маршрутизатором сегментов, то построить общую сеть на LLA все же можно (даже без динамической маршрутизации), но это порождает множество проблем или, как минимум, неудобств. Следует так же учитывать необязательное использование EUI-64 (а часть устройств может генерировать интерфейсную часть адреса случайным образом), возможное использование одиного и того же LLA на разных интерфейсах одного и того же маршрутизатора (LLA должен быть уникальным только в пределах одного сегмента), и прочие проблемы, осложняющие настройку и отладку.

    Для изолированных сетей (включая встраиваемые сети) дизайнерами IPv6 был разработан специальный тип адресов - ULA (Unique Local Address). Это если вы желаете чтобы устройства из внутренней сети не могли коммуницировать наружу. А если необходим доступ, то нет никаких проблем с назначением внутренним устройствам глобальных адресов (GUA). Что с ULA, что с GUA, DHCPv6 сервер не обязателен, адреса можно раздать через IA_PD в RS/RA (а так же адреса серверов DNS), но если неоходимо передать устройствам специфическую информацию (сервер NTP, etc.) то DHCP сервер необходим.

    Мыслите вы правильно и в верном направлении, но, как мне кажется, не вполне эффективно пытаетесь использовать стек IPv6.