Skip to content

VLAN и изоляция: почему «разделили сеть» — а она всё равно соединена ​

Контекст: лаба №6. Мы создали VLAN 10 и VLAN 20, рассадили клиентов по разным VLAN — и тест изоляции провалился: alpine1 спокойно пинговал alpine2. Пришлось добавлять правила firewall. Эта глава — почему так устроено и как это работает под капотом.


1. Что на самом деле делает VLAN (L2) ​

VLAN (802.1Q) добавляет в кадр Ethernet 4 байта — тег с номером VLAN:

text
Обычный кадр:   [MAC dst][MAC src][Ethertype][IP-пакет][CRC]
С тегом 802.1Q: [MAC dst][MAC src][0x8100][VLAN=10][Ethertype][IP-пакет][CRC]
                                    └────── 4 новых байта ──────┘

Правило коммутации меняется одной строкой: коммутатор пересылает кадр только в порты того же VLAN, что и тег кадра. Кадр с тегом 10 никогда не вылезет из порта VLAN 20 — так же, как почта с маркой «подъезд 10» не попадёт в почтовые ящики подъезда 20. Вот и вся L2-изоляция: она работает внутри одного устройства (коммутатора) и одного сегмента.

Одна физическая сеть — два изолированных L2-«мостика»коммутатор / мост lab-lan (видит ОБА VLAN, но кадры не смешивает)alpine1 (VLAN 10)alpine2 (VLAN 20)кадры с разными тегами — как вода и масло, мост их не смешивает

Проверка из лабы: tcpdump -e -i eth0 -n vlan на Alpine показывает теги; прямой ping alpine1→alpine2 по L2 невозможен — кадр просто не доходит. На этом этапе изоляция есть.

2. Почему роутер разрушает изоляцию: он стоит в обоих мирах ​

А теперь добавим CHR. У него по одному интерфейсу (ноге) в каждом VLAN:

CHR — роутерvlan10: 192.168.10.1 · vlan20: 192.168.20.1нога в VLAN 10нога в VLAN 20alpine1 .10.11alpine2 .20.12оба VLAN — «подключённые» сети роутера: в его таблице две строки C (connected)и его РАБОТА — перекладывать пакеты между сетями

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

text
DAc 192.168.10.0/24  vlan10     ← «сеть 10 достижима через меня»
DAc 192.168.20.0/24  vlan20     ← «сеть 20 достижима через меня»
 AS 0.0.0.0.0/0       → WAN      ← «остальное — наружу»

Теперь следим за пакетом ping alpine1 → 192.168.20.12 по шагам:

text
1. alpine1: 192.168.20.12 НЕ моя сеть (маска /24) → отправляю шлюзу: [ IP: 10.11 → 20.12 | Ethernet: я → MAC vlan10 ]

2. Кадр (тег 10) доходит до CHR. CHR снимает тег, читает IP:
   «20.12 — это мой connected-маршрут через vlan20» → РЕШАЕТ ПЕРЕСЛАТЬ.
   Никакого «а можно ли?» в маршрутизации нет — маршрут есть = пересылаю.

3. CHR собирает НОВЫЙ кадр: [ IP: 10.11 → 20.12 | Ethernet: MAC vlan20 → alpine2 ]
   с тегом 20 и отправляет в VLAN 20.

4. alpine2 получает ping, отвечает тем же путём (через свой шлюз .20.1).

Обрати внимание: L2-изоляция на каждом участке соблюдена идеально — кадры ходили только внутри своих VLAN. Изоляцию обошли не «сквозь стену», а через дверь, которая ведёт в обе комнаты. И это не баг: alpine1 ходит в интернет ТЕМ ЖЕ механизмом (пакет уходит на шлюз, CHR пересылает дальше на WAN). Разрешить «в интернет» и запретить «в соседний VLAN» — роутер сам по себе не умеет, для него оба действия — одинаковая операция «переслать между интерфейсами» (forward).

3. Изоляция = L2-теги + L3-политика. Обе части обязательны ​

Вывод, который надо выносить в спину:

VLAN изолирует радиосигнал (L2), firewall изолирует маршруты (L3). Одно без другого — не изоляция.

Поэтому финал лабы — два правила на CHR:

routeros
/ip firewall filter add chain=forward src-address=192.168.10.0/24 dst-address=192.168.20.0/24 action=drop
/ip firewall filter add chain=forward src-address=192.168.20.0/24 dst-address=192.168.10.0/24 action=drop

Что они делают в цепочке обработки пакета на CHR: маршрут выбран (forward), а firewall говорит «стоп» — если пакет летит между этими сетями, дроп. Интернет при этом жив: правилам подпадает только трафик 10↔20, пакеты «10 → наружу» под них не попадают.

Теперь весь пакетный путь в лабе выглядит так:

text
alpine1 (VLAN 10)
   │ кадр с тегом 10 — L2-изоляция здесь
   ▼
CHR: снять тег → маршрутизация (куда?) → firewall filter forward (можно ли?)
   │                                                        ├─ 10→20 или 20→10 → DROP
   ▼                                                        └─ куда угодно ещё → forward
кадр с тегом 20 (или наружу в WAN) — L2 снова
   ▼
alpine2 (VLAN 20)

4. Почему два правила, а не одно ​

Правило «src 10 → dst 20 drop» рубит только пакеты от 10 к 20. Ответный трафик (20 → 10) ему не подпадает — RouterOS не добавляет автоматического «и обратно» (нет stateful-магии на уровне «запомни направление и режь зеркально» для чистого drop; connection tracking следит за сессиями, но drop-правило без established-контекста действует построго по src/dst). Если оставить одно правило — пинги в одну сторону мертвы, а в обратную ходят. Два правила = изоляция в обе стороны.

Эталонная промышленная запись — через списки адресов и одно правило:

routeros
/ip firewall address-list add list=vlan-isolated address=192.168.10.0/24
/ip firewall address-list add list=vlan-isolated address=192.168.20.0/24
/ip firewall filter add chain=forward src-address-list=vlan-isolated dst-address-list=vlan-isolated action=drop

(«источник ИЗ списка И назначение В список» = любая пара изолированных сетей, одна строка вместо четырёх.)

5. Как это выглядит в реальной жизни (и почему сетевики ворчат) ​

Именно этот двухслойный механизм стоит за привычными вещами:

  • Гостевой Wi-Fi в кафе/отелях: гость в гостевом VLAN не достаёт ни одного офисного принтера — не потому что «Wi-Fi такой», а потому что L2-метка + firewall-политика на контроллере/роутере.
  • Провайдер разделяет абонентов: клиенты одного дома в одном VLAN — соседи друг друга не видят (изоляция + запрет intra-VLAN forwarding на агрегирующем свитче, DHCP snooping против жуликов — см. кейс №5).
  • IoT-карантин дома: камеры/лампочки в VLAN 30 без доступа в VLAN 10 — работает, пока не понадобится управление лампочкой из телефона… тогда сетевик пишет точечные разрешения (межсетевой экран: разрешить телефону → лампочкам по конкретным портам) и поднимает mDNS-рефлектор для обнаружения. Вот за этим его «половина не будет работать» из нашего чата — без этой работы изоляция ломает обнаружение устройств.

6. Проверь себя ​

  1. alpine1 (VLAN 10) пингует 192.168.20.1 — шлюз чужого VLAN. Изоляция с firewall-правилами включена. Что вернёт ping и почему? (Ничего: пакет доходит до CHR — он же адресат — но ICMP-ответ строится 20.1→10.11 и рубится правилом 20→10. Мелкая тонкость: до самого шлюза чужого VLAN «достучаться» можно было бы, если бы CHR отвечал до применения filter… на практике в RouterOS input-ответ тоже проходит, но ответная стадия режется forward'ом.)
  2. Почему DHCP из каждого VLAN работает корректно и не «перетекает» в соседний, хотя сервер один (CHR)? (Broadcast Discover живёт в рамках своего VLAN — тег не пускает его дальше; CHR слушает оба VLAN и отвечает в нужный.)
  3. Что сломается, если убрать L2-тегирование, оставив только firewall-правила? (Ничего с точки зрения L3-изоляции — но вся сеть слипнется в один broadcast-домен: DHCP-конфликты, шторм discovery-трафика, слушать сеть станет проще; VLAN нужен не только для безопасности, но и для гигиены эфира.)

Связанные главы: Модель OSI (L2/L3), IP-адресация (connected-маршруты, префиксы), кейсы №5–№6 в разделе «Кейсы».