NetBox VLAN трансляция идентификаторов 4.2
АйТи Фреш
Сети и VPN

На границе сети VLAN 100 превращается в VLAN 200: как описать трансляцию идентификаторов в NetBox 4.2

Автор: , директор ООО «АйТи-Фреш» · · ~15 мин чтения
Кабель пересекает границу сети: локальный VLAN превращается во внешний VLAN — трансляция идентификаторов в NetBox
На границе сети один и тот же линк может называться разными VLAN ID — важно, чтобы это было записано, а не в чьей-то голове.

Если на вашей стороне это VLAN 100, а у оператора тот же линк живёт как VLAN 200 — это нормально, если кто-то это записал. С версии 4.2 в NetBox для этого есть модель VLANTranslationPolicy с правилами VLANTranslationRule — их вешают на порт через UI или REST API. Разбираю синтаксис и ограничения модели на примере офиса на 22 рабочих места.

Почему обычный список VLAN не хранит соответствие ID на границе сети

В NetBox VLAN — это объект с vid, именем, группой и статусом на конкретной площадке или в конкретном VLAN group. Он прекрасно отвечает на вопрос «что такое VLAN 100 в этом офисе». Но он ничего не знает про то, как этот же сегмент называется по другую сторону границы — на аплинке к провайдеру, на транке между филиалами или на стыке с сетью подрядчика. А эта граница есть почти в каждой сети, где я внедряю NetBox для документирования: у провайдера Ethernet-канала нумерация VLAN своя, внутренняя, и с вашей она никогда не обязана совпадать.

До версии 4.2 эту привязку в NetBox можно было только имитировать: заводить второй VLAN-объект с тем же именем в отдельной VLAN group «внешние», писать в comments порта что-то вроде «на стороне оператора это VLAN 200» и надеяться, что через полгода это поле кто-то откроет перед заменой коммутатора. Запрос на нормальную модель для 1:1 трансляции VLAN ID между группами лежал в трекере NetBox под номером 7336 не один год, его приняли в разработку и включили в веху v4.2 — то есть сообщество явно упиралось в эту дыру достаточно часто, чтобы это стало отдельной фичей, а не костылём.

В релизе 4.2.0 (вышел 6 января 2025 года) это наконец появилось как первоклассная сущность: VLANTranslationPolicy — именованная политика, VLANTranslationRule — конкретное правило внутри неё вида «локальный VID → удалённый VID». Политику можно один раз описать и переиспользовать на любом числе портов, а не копировать комментарий из порта в порт. Добавили и пару REST-эндпоинтов — /api/ipam/vlan-translation-policies/ и /api/ipam/vlan-translation-rules/ — так что это не только функция формы в вебе, но и то, что можно завести скриптом при массовом описании сети.

Модель данных: что на самом деле хранят VLANTranslationPolicy и VLANTranslationRule

VLANTranslationPolicy устроена скромно: по факту у неё один содержательный собственный атрибут — name, строка до 100 символов, обязательно уникальная в рамках инсталляции. Остальное — description, comments, tags, custom fields — она получает от базового класса PrimaryModel, как и большинство объектов NetBox. Сама по себе политика ничего не транслирует, это просто именованный контейнер, к которому потом привязываются правила и порты. Логика в том, чтобы описать схему трансляции один раз («аплинк к оператору X», «транк на филиал Y») и вешать её на десятки интерфейсов без копирования.

Собственно трансляцию описывает VLANTranslationRule: обязательная ссылка policy на политику (при удалении политики правила удаляются вместе с ней, on_delete=CASCADE), два числовых поля local_vid и remote_vid с проверкой диапазона 1–4094, и необязательное description до 200 символов. Модель жёстко следит за целостностью: в рамках одной политики действует ограничение уникальности отдельно на пару (policy, local_vid) и отдельно на пару (policy, remote_vid). Это значит, что связка местный↔удалённый VID внутри политики строго один-к-одному: один local_vid не может смотреть в два разных remote_vid, и наоборот, два local_vid не могут указывать на один remote_vid.

Ниже — как это выглядит в сравнении со старым способом хранить эту информацию (свободный текст/таблица вне NetBox) и новой моделью: | Что нужно | Было (таблица/комментарий) | Стало (VLANTranslationPolicy) | |---|---|---| | Хранение пары ID | текст, не валидируется | поля local_vid/remote_vid, диапазон 1–4094 | | Уникальность пары | вручную, никто не проверяет | UniqueConstraint (policy, local_vid) и (policy, remote_vid) | | Переиспользование на портах | копипаста комментария | одна политика на много интерфейсов | | Доступ по API | нет | /api/ipam/vlan-translation-policies/, /api/ipam/vlan-translation-rules/ | | Аудит изменений | не ведётся | правило пишет объект изменений и на себя, и на родительскую политику | Последнее — не мелочь: у VLANTranslationRule переопределён to_objectchange, и изменение конкретного правила попадает в журнал изменений связанной политики тоже. Когда через полгода кто-то спросит «кто поменял маппинг VID на этом порту», ответ находится за один клик, а не за архивом переписки.

Схема связей VLANTranslationPolicy, VLANTranslationRule и интерфейса в NetBox 4.2
Один объект политики с правилами local_vid → remote_vid переиспользуется на любом числе портов.

Как политика попадает на порт: Interface, VMInterface и связь с режимом Q-in-Q

Поле vlan_translation_policy добавлено в общий базовый класс интерфейсов, поэтому оно одинаково доступно и на физическом DCIM-интерфейсе, и на VMInterface виртуальной машины — если у вас гипервизор или контейнерный хост с транком, который тоже подчиняется чужой нумерации VLAN на внешней стороне, трансляцию можно описать точно так же. Это внешний ключ на VLANTranslationPolicy с on_delete=PROTECT: NetBox физически не даст удалить политику, пока хотя бы один интерфейс на неё ссылается — сначала придётся руками отвязать все порты. Мелочь, но именно она спасает от ситуации «случайно снёс политику, и полсети потеряла описание границы».

Ключевое свойство здесь — переиспользование: одна и та же политика вешается на любое число интерфейсов. Если у вас, например, сеть разбита на VLAN по отделам и у каждого коммутатора есть однотипный аплинк с одинаковой схемой трансляции VID, политику заводят один раз и назначают на все такие порты — а не плодят N одинаковых правил под разными именами. При массовой смене схемы (провайдер перенумеровал VLAN на своей стороне) достаточно поправить local_vid/remote_vid в одном правиле, и это применится ко всем портам, которые на эту политику ссылаются.

Отдельно стоит не путать трансляцию с режимом Q-in-Q, который в NetBox 4.2 добавили тем же релизом: у поля «802.1Q Mode» интерфейса появилось четвёртое значение — Q-in-Q (IEEE 802.1ad), с отдельным полем под SVLAN. Q-in-Q — это двойная инкапсуляция, внешний тег поверх внутреннего, сохраняющий оба ID одновременно. VLANTranslationPolicy — это подмена одного ID на другой в рамках того же уровня инкапсуляции. Механизмы разные и в реальной сети решают разные задачи, но раз оба появились в одном релизе, я на практике вижу, как их путают уже на этапе выбора, какое поле заполнять на интерфейсе.

REST API: как завести политику и правила без единого клика в UI

Форма в вебе удобна для одной политики, но если вы документируете сеть с десятками однотипных аплинков, быстрее пройти через API — тем более что в 4.2 под это выделены отдельные эндпоинты. Сначала создаём саму политику:

curl -s -X POST https://netbox.example.com/api/ipam/vlan-translation-policies/ \
  -H "Authorization: Token $NETBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "klishe-profi-isp-uplink",
    "description": "Трансляция VID на аплинке к оператору"
  }'

Ответ вернёт id созданной политики — он понадобится для правил.

Дальше заводим само правило (или сразу несколько — эндпоинт принимает как один объект, так и список объектов для пакетного создания):

curl -s -X POST https://netbox.example.com/api/ipam/vlan-translation-rules/ \
  -H "Authorization: Token $NETBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "policy": 3,
    "local_vid": 100,
    "remote_vid": 200,
    "description": "Офис -> хэндофф провайдера"
  }'

policy здесь — числовой ID политики, а не имя: политика должна существовать до создания правила, нативно вложенного создания «политика + правила одним запросом» эндпоинт не поддерживает.

Осталось привязать политику к порту — это делается не через сам объект политики, а PATCH-запросом к интерфейсу:

curl -s -X PATCH https://netbox.example.com/api/dcim/interfaces/482/ \
  -H "Authorization: Token $NETBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"vlan_translation_policy": 3}'

Тот же PATCH с "vlan_translation_policy": null политику с порта снимает. Я обычно заворачиваю эти три вызова в один Python/Ansible-плейбук при массовом описании границы сети — так за один прогон закрывается вся пачка однотипных аплинков, а не по одному в вебе.

Сравнение способов хранить трансляцию VLAN: таблица вручную и VLANTranslationPolicy в NetBox
Правило в NetBox не расходится с портом само по себе — таблица в Excel расходится почти всегда.

Кейс: «Клише Профи» — VLAN 100 у нас, VLAN 200 у провайдера

Производство печатей и штампов «Клише Профи» — 22 рабочих места, один офис, один аплинк-канал у оператора связи. Офисная сеть живёт в VLAN 100, а через аплинк идут арендованная облачная 1С, IP-телефония и заказы от интернет-магазина на гравировку. У провайдера на их стороне хэндоффа этот же канал числится как VLAN 200 — так у них устроена внутренняя нумерация клиентских портов, и на это мы повлиять не можем. До того как я занялся их сетью, это соответствие 100↔200 нигде не было записано, кроме заметки в блокноте инженера, который когда-то поднимал канал.

Инцидент, который сделал это видимой проблемой: провайдер по своей заявке переключил клиента на другой порт агрегирующего коммутатора и попросил нас продиктовать VLAN ID со своей стороны. Диктовали 100 — то есть свой внутренний, а не тот, что был согласован на границе. Порт подняли с неверным маппингом, офис на 22 рабочих места простоял без доступа к 1С и телефонии порядка 40 минут, пока не подняли ту самую переписку годичной давности и не сверили правильную пару.

После этого завёл в NetBox политику klishe-profi-isp-uplink с description «граница с провайдером, хэндофф аплинка» и одним правилом: local_vid 100, remote_vid 200, description «офисный VLAN — внешний VID хэндоффа провайдера». Политику привязал к интерфейсу пограничного коммутатора, через который идёт аплинк. Порядок действий, который я теперь применяю к каждому пограничному порту, — в списке ниже; всё вместе заняло меньше времени, чем сам инцидент.

Правило в NetBox не меняет конфигурацию коммутатора само по себе — это документация, а не SDN-контроллер. Реальную трансляцию (или просто корректную нумерацию VLAN на порту) я всё равно настраиваю руками на оборудовании. Но теперь при любом обращении к провайдеру, при замене порта или при передаче сети другому инженеру нужный VID со своей и с чужой стороны — это одна карточка в NetBox, а не блокнот, который может потеряться вместе с человеком, который его вёл.

Объект в NetBox — это факт документации, а не команда на оборудование. Создание VLANTranslationPolicy не перенастраивает коммутатор и не гарантирует, что реальный порт действительно транслирует ID так, как записано — это нужно свести руками хотя бы один раз.
Цифры кейса «Клише Профи»: трансляция VLAN 100 в VLAN 200 на границе с провайдером в NetBox
Один правильно описанный объект в NetBox снял ошибку, из-за которой офис на 22 рабочих места терял связь.

Чего трансляция VID в NetBox не делает — и где на этом спотыкаются

Первое и самое важное ограничение я уже назвал в кейсе: NetBox — это Source of Truth для документации сети, а не система управления конфигурацией. VLANTranslationPolicy и её правила нигде не отправляют команды на свитч. Если у вас настроена сетевая документация как отдельный процесс, добавление этой модели логично встраивается туда же: сначала фиксируете факт в NetBox, потом (или параллельно) настраиваете реальную трансляцию на оборудовании — vendor-специфичной командой вроде маппинга VLAN на порту у Cisco или Q-in-Q/VLAN mapping у других производителей.

Второе — жёсткая схема 1:1 внутри одной политики. Ограничения уникальности на (policy, local_vid) и на (policy, remote_vid) исключают модель «много локальных VID схлопываются в один внешний» в рамках одной и той же политики: если реальная топология именно такая (агрегация нескольких внутренних VLAN в один внешний на границе), для каждой такой пары придётся заводить отдельную политику или пересматривать сетевой дизайн — сама модель вас на многие-к-одному не пустит, и это осознанное ограничение разработчиков, а не баг.

Третье — PROTECT на связи интерфейса с политикой ловит не всех. Он защищает от удаления самой политики, пока она используется хотя бы одним портом, но ничего не мешает создать правило с правильными на вид числами и забыть привязать политику к нужному интерфейсу — тогда данные в NetBox корректны, а граница сети по-прежнему не описана там, где реально нужна. Я в таких случаях после массового заведения политик прогоняю сверку: выбираю все интерфейсы с типом «аплинк»/«транк» по тегу и фильтром API проверяю, у скольких из них поле vlan_translation_policy пустое.

Как сделать трансляцию VID частью документации сети, а не разовой правкой

Смысла заводить VLANTranslationPolicy разово, для одного инцидента, немного — это работает как система, только если стало правилом при описании любого пограничного порта. Я завожу его в тот же момент, что и сам интерфейс в NetBox: если порт — это аплинк к внешней стороне (провайдер, филиал, подрядчик) и есть хоть малейший шанс, что нумерация VLAN у них своя, сразу спрашиваю заказчика или смотрю в акт подключения, какой ID там на самом деле, и завожу правило, а не оставляю «уточнить потом».

Если у вас в компании уже есть практика документировать инфраструктуру в NetBox целиком, трансляция VID — это не отдельный проект, а ещё одно поле в чек-листе на вводе нового интерфейса в границе сети. Отдельно рекомендую единый нейминг политик (у меня — «клиент-направление-uplink» или «площадка1-площадка2-trunk»): когда политик становится больше десятка, найти нужную по осмысленному имени в разы быстрее, чем перебирать список правил по ID.

Раз в квартал я прогоняю по API простую сверку: выгружаю все интерфейсы с непустым vlan_translation_policy, для каждого — реальный VID на порту (по факту с оборудования, не из NetBox) и сравниваю с local_vid в привязанном правиле. Разошлось — значит, кто-то поменял конфигурацию на коммутаторе и не обновил документацию, и это повод разобраться раньше, чем разойдётся окончательно и обернётся простоем вроде того, что был у «Клише Профи».

Частые вопросы

С какой версии NetBox доступна трансляция VLAN ID?

С 4.2.0, вышедшей 6 января 2025 года. Модели VLANTranslationPolicy и VLANTranslationRule и эндпоинты /api/ipam/vlan-translation-policies/ и /api/ipam/vlan-translation-rules/ доступны во всех последующих релизах ветки 4.2 и новее; в 4.2.5 добавили массовое назначение политики при bulk-редактировании интерфейсов, в 4.2.8 — фильтрацию интерфейсов по политике.

Можно ли назначить одну политику на несколько интерфейсов сразу?

Да, это и есть основной сценарий использования: политика — переиспользуемый объект, а не разовая настройка одного порта. Один и тот же VLANTranslationPolicy можно привязать к любому числу интерфейсов Interface и VMInterface.

Что будет, если попытаться удалить политику, которая привязана к порту?

NetBox не даст это сделать: поле vlan_translation_policy на интерфейсе ссылается на политику с on_delete=PROTECT. Сначала нужно отвязать политику от всех интерфейсов (или удалить сами интерфейсы), и только потом политика удалится.

Работает ли трансляция VID для виртуальных машин, не только для физических портов?

Да. Поле vlan_translation_policy определено на общем базовом классе интерфейсов, поэтому доступно и на физическом Interface в DCIM, и на VMInterface в модуле виртуализации.

Меняет ли создание правила в NetBox реальную конфигурацию коммутатора?

Нет. NetBox документирует факт трансляции, но не отправляет команды на оборудование. Реальный маппинг VLAN ID на порту нужно настроить отдельно, средствами конкретного вендора, и потом сверять с записью в NetBox.

Как быстро загрузить в NetBox много правил трансляции сразу?

Через bulk-создание: POST на /api/ipam/vlan-translation-rules/ с телом-массивом объектов вместо одного объекта создаст сразу несколько правил одним запросом — стандартный для REST API NetBox паттерн пакетных операций.

Столкнулись с похожей задачей? Обращайтесь — решим

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

Возьмёмся и за разовую задачу, и за постоянное обслуживание. Первичная консультация — бесплатно и без обязательств.

📞 +7 903 729-62-41 ✈ Telegram @ITfresh_Boss

С уважением, Семёнов Евгений Сергеевич, директор «АйТи Фреш» — IT-аутсорсинг для компаний до 50 рабочих мест, 15+ лет практики

Источники

© ООО «АйТи-Фреш» · Москва · Все статьи