Q-in-Q в NetBox: как учесть CVLAN и SVLAN правильно
АйТи Фреш
Сети и VPN

Как учесть Q-in-Q в NetBox: где хранить CVLAN, SVLAN и внешний тег порта

Автор: , директор ООО «АйТи-Фреш» · · ~14 мин чтения
Клиентский VLAN инкапсулируется внутри сервисного VLAN оператора — визуальная метафора Q-in-Q
Q-in-Q — это тег внутри тега, а не два независимых VLAN на одном порту.

Q-in-Q — это не «ещё один VLAN», а отдельная модель данных: клиентский тег живёт внутри сервисного, и если завести оба тега как обычный trunk, связь между ними потеряется при первой же миграции. В NetBox с версии 4.2 для этого есть отдельные поля у VLAN и у интерфейса. Ниже — как я их использую, где обычно путают customer и service VLAN и что происходит, если оператор поменял внешний тег, а в базе об этом никто не узнал.

Почему обычный VLAN не описывает Q-in-Q

Q-in-Q, он же IEEE 802.1ad, — это инкапсуляция одного тега VLAN внутрь другого. Провайдер заворачивает трафик клиента в свой сервисный тег (SVLAN), а клиентский тег (CVLAN) едет внутри него нетронутым через всю сеть оператора. На интерфейсе клиента это выглядит как обычный access или trunk-порт, но на границе с оператором это уже два заголовка 802.1Q подряд. Когда я веду внедрение NetBox для компании, которая арендует L2-канал у оператора, я сразу спрашиваю: как размечен канал — простой VLAN, транк или именно Q-in-Q. Ответ определяет, какие поля заполнять в карточке VLAN и интерфейса, и я видел, как в двух разных проектах путали это до потери связи с филиалом.

До версии 4.2 в NetBox не было выделенной модели для этой связки. Администраторы либо заводили SVLAN как обычный VLAN и писали «сервисный, оператор X» в комментарии, либо вообще не документировали внешний тег — он жил только в конфиге коммутатора и в переписке с оператором. Оба варианта работают, пока об инфраструктуре помнит один человек. В момент, когда его сменяет коллега, инвентаризация или ITSM-система пытаются построить отчёт по VLAN, а два тега на одном порту неотличимы от обычного trunk с двумя вланами.

Как устроена модель Q-in-Q в NetBox

С релиза 4.2.0 (вышел 6 января 2025 года) в NetBox добавлена прямая поддержка обозначения клиентских (CVLAN) и сервисных (SVLAN) VLAN для инкапсуляции IEEE 802.1ad. Фича прошла путь от issue #13428 в репозитории netbox-community/netbox, где изначально предлагалась отдельная модель «svlan» и режим интерфейса «Double tagged»; в итоговой реализации от отдельной модели отказались в пользу двух новых полей у существующей модели VLAN — так проще фильтровать, строить отчёты и не плодить сущности.

У модели VLAN появилось необязательное поле qinq_role — оно указывает, чем является этот VLAN в топологии Q-in-Q: Customer (клиентский, CVLAN) или Service (сервисный, SVLAN). В интерфейсе вы видите эти подписи, а в базе и REST API хранятся короткие значения cvlan и svlan — это важно, если заполняете поля скриптом. Второе новое поле — qinq_svlan, рекурсивная связь VLAN на VLAN: в ней клиентский VLAN ссылается на свой сервисный VLAN. Документация прямо оговаривает: это поле можно задать только для клиентского VLAN, связь всегда идёт от CVLAN к SVLAN, а обратная сторона видна как список привязанных клиентских VLAN. Валидация в коде работает в обе стороны: qinq_svlan у VLAN с другой ролью NetBox не сохранит, а клиентский VLAN без указанного сервисного — тоже, с ошибкой «A Q-in-Q customer VLAN must be assigned to a service VLAN».

Практический вывод из этого ограничения: сначала заводите сервисный VLAN с ролью Service, и только потом клиентский с ролью Customer — связь указывается только на стороне клиентского VLAN и обязательна при его сохранении. Роль VLAN не заменяет обычные поля vid и name: у клиентского и сервисного VLAN по-прежнему свои идентификаторы, они просто дополнительно помечены ролью и связаны друг с другом.

Схема связи полей qinq_role и qinq_svlan между клиентским и сервисным VLAN в NetBox
Связь всегда однонаправленная: от клиентского VLAN к сервисному, а не наоборот.

Настройка интерфейса: режим Q-in-Q и qinq_svlan

Второе изменение 4.2 — новый режим 802.1Q на интерфейсе. У Interface (и у VMInterface — виртуальные интерфейсы получили ту же логику) в списке mode теперь четыре варианта: Access — весь трафик порта относится к одному VLAN без тега; Tagged — один нетегированный «родной» VLAN плюс любое число тегированных; Tagged (all) — интерфейс несёт все VLAN сразу; и новый Q-in-Q — на интерфейсе выполняется инкапсуляция IEEE 802.1ad с использованием назначенного сервисного VLAN. Это отдельный, самостоятельный режим, а не комбинация Tagged плюс комментарий.

Когда вы выставляете интерфейсу режим Q-in-Q, у него появляется поле qinq_svlan — «назначенный сервисный VLAN (для интерфейсов Q-in-Q/802.1ad)», как формулирует документация. Обратите внимание: у VLAN поле называется qinq_svlan и указывает на сервисный VLAN текущего клиентского VLAN, а у интерфейса поле с тем же именем qinq_svlan указывает, какой сервисный VLAN инкапсулируется на этом порту. Это не одно и то же поле в базе, у них разные модели и разные внешние ключи, но одинаковое смысловое назначение — обе привязки в итоге должны указывать на один и тот же объект VLAN с ролью Service. Форма редактирования интерфейса, кстати, сама предлагает в этом поле только VLAN с ролью Service, а API вернёт ошибку, если передать qinq_svlan интерфейсу в любом режиме, кроме q-in-q.

Клиентские теги на Q-in-Q-порту я задаю так же, как на обычном trunk: через tagged_vlans со ссылкой на VLAN с ролью Customer. Оговорюсь честно: страница документации про интерфейс описывает tagged_vlans как поле режима Tagged, но валидация API запрещает его только для Access и Tagged (all), а в 4.2 отдельно чинили отображение tagged VLAN у Q-in-Q-интерфейсов — то есть такой способ записи разработчики предусматривают. Иначе говоря, полная картина порта в сторону оператора — это режим Q-in-Q, один qinq_svlan (сервисный VLAN оператора) и один или несколько tagged_vlans (клиентские VLAN, которые реально едут внутри туннеля).

Пошагово: заводим канал с двойным тегированием

На практике я завожу связку в четыре шага. Сначала создаю сервисный VLAN — VID, который назначил оператор для вашего канала, с ролью Service (qinq_role = svlan) и понятным именем вроде SVLAN-Operator-Branch2. Затем создаю клиентский VLAN — тот VID, что реально используется в вашей сети (например, VLAN 10 с трафиком филиала), с ролью Customer (qinq_role = cvlan), и в его поле qinq_svlan сразу указываю только что созданный сервисный VLAN — без этого NetBox клиентский VLAN не сохранит. Дальше нахожу пограничный интерфейс — тот порт коммутатора, который физически смотрит в сторону оператора, — и меняю его mode на Q-in-Q, а в qinq_svlan интерфейса подставляю тот же сервисный VLAN. Последний шаг — добавляю клиентский VLAN в tagged_vlans этого интерфейса.

Через REST API это делается двумя PATCH-запросами: сначала клиентскому VLAN проставляется роль и ссылка на сервисный VLAN, затем интерфейсу — режим и сервисный VLAN.

curl -s -X PATCH https://netbox.example.local/api/ipam/vlans/142/ \
  -H "Authorization: Token $NETBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"qinq_role": "cvlan", "qinq_svlan": 98}'

curl -s -X PATCH https://netbox.example.local/api/dcim/interfaces/551/ \
  -H "Authorization: Token $NETBOX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode": "q-in-q", "qinq_svlan": 98, "tagged_vlans": [142]}'

Обратите внимание: в API роль передаётся значением cvlan/svlan, а не словом customer — на него NetBox ответит ошибкой выбора. ID здесь условные — их нужно подставить свои, взятые из /api/ipam/vlans/ и /api/dcim/interfaces/. Токен создаётся в разделе учётных данных NetBox и должен иметь право записи в IPAM и DCIM для этой операции.

Отдельно проверяю обратную сторону: если у клиента несколько филиалов через одного оператора, сервисный VLAN обычно один на канал (или на точку присоединения), а клиентских VLAN может быть несколько — по одному на VRF или сегмент внутри туннеля. В этом случае у одного service-VLAN будет несколько клиентских VLAN со ссылкой qinq_svlan на него — модель это позволяет, ограничение стоит на направлении связи (от клиентского к сервисному), а не на количестве. Есть одно полезное ограничение уникальности: внутри одного сервисного VLAN не может быть двух клиентских с одинаковым VID или одинаковым именем. При этом один и тот же клиентский VID под разными SVLAN допустим — ровно так, как это и работает у оператора.

Пошаговый чек-лист из четырёх шагов для настройки Q-in-Q в NetBox
Порядок важен: сначала оба VLAN с ролями, потом связь, и только потом интерфейс.

Кейс: подключение филиала через Q-in-Q у «Подбор без ошибок»

Условный клиент — рекрутинговая компания «Подбор без ошибок», 9 рабочих мест в головном офисе и небольшой филиал на три человека в другом бизнес-центре того же города. Вместо второго интернет-канала и VPN-туннеля компания арендовала у местного оператора L2-канал: порт в головном офисе и порт в филиале объединены в один Ethernet-сегмент через сеть провайдера. Оператор выдал сервисный VLAN 3401 на своей стороне и сказал, что клиентский трафик компании — VLAN 10 — «поедет прозрачно». До внедрения NetBox эта информация жила в одном письме от оператора и в конфиге пограничного коммутатора, без какой-либо записи в системе учёта.

Когда я заводил инфраструктуру компании в NetBox, я создал VLAN 3401 с ролью Service и именем SVLAN-Operator-L2-Branch, и VLAN 10 с ролью Customer и ссылкой qinq_svlan на VLAN 3401. Пограничный интерфейс на коммутаторе головного офиса получил режим Q-in-Q, qinq_svlan = VLAN 3401 и tagged_vlans = [VLAN 10]. Отдельно я оставил карточку устройства с комментарием, какой именно физический порт оператора это подключение занимает — эта информация в модель Q-in-Q не входит, но нужна для эскалации, если канал упадёт ночью.

Пользы от этого оказалось больше, чем я ожидал изначально. Через полгода оператор менял оборудование на своей стороне и попросил подтвердить, какой сервисный VLAN использует канал компании — ответ был получен за минуту прямым запросом к VLAN 3401 в NetBox, без поиска старой переписки. Ещё раз это пригодилось, когда в компании расширяли филиал и нужно было понять, можно ли добавить второй клиентский VLAN в тот же туннель без переговоров с оператором о новом сервисном VLAN — фильтр списка VLAN по qinq_svlan_vid=3401 сразу показал, что к этому сервисному VLAN привязан только VLAN 10, и новый VID 20 не конфликтует с уже заведёнными. Пропускную способность NetBox, конечно, не считает — её мы сверили с договором отдельно.

Частые ошибки при заведении Q-in-Q

Самая частая ошибка — перепутать направление связи. Администратор пытается указать qinq_svlan сервисному VLAN, ссылаясь на клиентский, — NetBox отклоняет такую попытку, потому что поле допустимо только для роли Customer. Если вам кажется, что нужно связать в обратную сторону, скорее всего, вы перепутали, какой VLAN клиентский, а какой сервисный: сервисный — тот, что назначил оператор для инкапсуляции, клиентский — тот, что реально используется вашей локальной сетью.

Вторая ошибка — заводить сервисный VLAN как обычный VLAN без заполненного qinq_role, потому что «он всё равно не используется напрямую в вашей сети». Формально трафик действительно продолжит ходить: коммутатор не проверяет заполненность полей в NetBox. Но тогда при следующем аудите или генерации отчёта по VLAN сервисный тег окажется неотличим от обычного неиспользуемого VLAN, и кто-то удалит его как «мёртвый», разорвав канал в самый неподходящий момент.

Третья, более редкая ситуация — интерфейс оставлен в режиме Tagged вместо Q-in-Q, а оба VLAN просто добавлены в tagged_vlans. Синтаксически это допустимо и ничего не сломает в самом NetBox, но модель перестаёт отражать реальность: Tagged означает «несколько независимых VLAN на одном порту», а не «один VLAN внутри другого». Отчёты по использованию VLAN и любая автоматизация, которая опирается на mode интерфейса, в этом случае будут работать с неверными допущениями о топологии. Такая же дисциплина точных полей вместо приблизительных нужна и в других сетевых механизмах — например, в синхронизации времени по PTPv2, где микросекундная точность тоже не описывается на словах.

Дерево решений: когда в NetBox нужна модель Q-in-Q, а когда достаточно обычных VLAN
Q-in-Q нужен не всем — только там, где реально есть инкапсуляция тега в тег на границе с оператором.

Когда заводить Q-in-Q, а когда достаточно общей документации сети

Если в компании нет L2-каналов через операторов и никакой инкапсуляции VLAN в VLAN, отдельно разбираться с полями qinq_role и qinq_svlan не нужно — это узкая модель именно под 802.1ad, и обычные VLAN с tagged_vlans полностью покрывают внутреннюю сеть офиса. Я подробно писал про то, с чего вообще начинать документацию инфраструктуры в NetBox: DCIM, IPAM, стойки и кабели — там про Q-in-Q почти ничего нет специально, потому что для большинства компаний до 50 рабочих мест этот сценарий не встречается.

Q-in-Q стоит заводить, как только у вас появляется хотя бы один канал, где провайдер оперирует сервисным VLAN, а вы — клиентским: аренда L2-канала между офисами, подключение к сети оператора ЦОД через его агрегирующий коммутатор. Даже если у вас один такой канал на всю компанию, разница между «просто trunk» и корректно описанным Q-in-Q проявится в первый же раз, когда придётся объясняться с оператором или передавать инфраструктуру новому администратору. Десять минут на заполнение двух полей у VLAN и двух у интерфейса стоят дешевле часа переписки с техподдержкой провайдера.

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

С какой версии NetBox доступна поддержка Q-in-Q?

С версии 4.2.0, вышедшей 6 января 2025 года. Тогда у модели VLAN появились поля qinq_role и qinq_svlan, а у Interface и VMInterface — режим mode «Q-in-Q» и поле qinq_svlan.

Можно ли задать qinq_svlan у сервисного VLAN?

Нет. Поле qinq_svlan допустимо только у VLAN с ролью Customer (в API — cvlan): оно указывает, какому сервисному VLAN подчинён клиентский. Более того, клиентский VLAN без qinq_svlan NetBox не сохранит.

Чем отличается режим интерфейса Q-in-Q от Tagged?

Tagged означает несколько независимых VLAN на одном порту с одним нетегированным «родным» VLAN. Q-in-Q — отдельный режим (в API значение q-in-q), где выполняется инкапсуляция IEEE 802.1ad с использованием сервисного VLAN из поля qinq_svlan интерфейса.

Может ли у одного сервисного VLAN быть несколько клиентских?

Да: несколько VLAN с ролью Customer могут ссылаться через qinq_svlan на один сервисный VLAN. Ограничение одно — внутри одного SVLAN клиентские VID и имена должны быть уникальны.

Нужно ли поддерживать Q-in-Q, если в офисе один интернет-канал без операторских VLAN?

Нет. Поля qinq_role и qinq_svlan нужны только когда провайдер или другая сторона реально инкапсулирует ваш VLAN в свой сервисный. Для обычной внутренней сети офиса хватает стандартных VLAN и режима Tagged/Access.

Работает ли Q-in-Q для виртуальных интерфейсов, а не только физических портов коммутаторов?

Да, у VMInterface та же логика: режим 802.1Q с вариантом Q-in-Q и поле qinq_svlan появились в 4.2 одновременно и для Interface, и для VMInterface.

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

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

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

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

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

Источники

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