Свитчи vs хабы — как кадр находит правильный порт
В 1990-х в офисах стояли коробки-хабы (концентраторы), и любой кадр, влетевший в один порт, выплёвывался во все остальные. Сейчас вместо хабов везде свитчи — они умные, и кадр идёт только в нужный порт. Эта разница кажется мелкой, но она поменяла сети в десятки раз: дала full duplex, ускорила всё на порядки, сделала VLAN-ы возможными.
В этом уроке разберём, как свитч на самом деле узнаёт, в какой порт класть кадр, что такое MAC-table и какой это L2 device, чем отличаются broadcast domain и collision domain. Это понимание важно для DE, потому что когда вы видите tcpdump-овые загадки («почему я не вижу трафик соседа?»), правильный mental model свитча сразу даёт ответ.
Хаб — тупой повторитель
Хаб (он же повторитель, repeater) — электрический усилитель. Он не имеет интеллекта, не понимает структуру Ethernet-кадра, не смотрит на MAC. Принцип:
- На любой порт хаба что-то приходит.
- Хаб повторяет этот сигнал на ВСЕ остальные порты.
- Все устройства смотрят на dst MAC в кадре и решают сами: моё — беру, не моё — молча игнорирую.
Что плохого в хабе:
- Пропускная полоса делится. Если хаб 100 Мбит/с и 4 устройства активно общаются — каждое получает в среднем 25 Мбит/с (а на пике трафика и того меньше).
- Коллизии. Если A и B шлют одновременно — сигналы накладываются, оба теряются. CSMA/CD: устройства слушают перед передачей, если коллизия — ждут случайное время и повторяют. Это half-duplex по определению.
- Подслушивание. Любой кадр виден всем. Это раздолье для snifferов: пускаешь Wireshark на хаб — видишь весь трафик всех устройств.
- Безопасность. MAC-фильтры не помогают — кадр всё равно физически приходит.
Хабы вымерли как класс примерно к 2005 году. Сейчас «хаб» — ругательное слово в IT.
Свитч — умный коммутатор
Свитч (он же bridge) — устройство второго уровня OSI. Он понимает Ethernet-кадры, читает MAC-адреса и знает, какой MAC за каким портом. Когда приходит кадр:
- Свитч смотрит на
dst MACв кадре. - Ищет этот MAC в своей MAC-table (forwarding table).
- Если нашёл — отправляет кадр только в тот порт.
- Если не нашёл — посылает во все порты (кроме того, откуда пришёл) — это называется flooding.
- Когда устройство отвечает — свитч учит, в каком порту этот MAC.
Преимущества:
- Full duplex. A может слать B, C может слать D одновременно — разные порты, никаких коллизий. Свитч 24x1Gbit фактически даёт 24 Gbit/s одновременно.
- Изоляция. B не видит трафик между A и C. Лучше с приватностью и безопасностью.
- Меньше нагрузки на хостов. Хост получает только нужные ему кадры.
- Поддержка большого числа устройств. Свитчи с MAC-table на десятки тысяч записей.
MAC learning — как свитч заполняет таблицу
Свитч не получает MAC-table от админа. Он учится сам в процессе работы. Алгоритм:
- Свитч включается — MAC-table пуста.
- Приходит первый кадр на port 1 c
src MAC = A. Свитч учит: «MAC A за port 1». Запоминает с TTL ~5 минут. - Что делать с этим кадром? Смотрит на
dst MAC. Если в таблице нет — flood во все порты. - Если кто-то ответил — его
src MAC=B, пришло с port 3. Учит: «MAC B за port 3». - Следующий кадр от A к B — уже знаем, идёт точно в port 3.
Записи в MAC-table имеют TTL (обычно 300 секунд). Если за это время с MAC не было трафика — запись стирается. Это нужно, чтобы:
- Если устройство переключили в другой порт — свитч переучится.
- MAC-table не разрастается бесконечно.
Посмотреть MAC-table на свитчах с CLI:
# Cisco IOS:
show mac address-table
# MikroTik RouterOS:
/interface bridge host print
# Linux bridge (если у вас Linux работает как свитч):
bridge fdb show
# или:
brctl showmacs br0
Это выведет таблицу формата MAC | VLAN | port | age | type.
Broadcast vs collision domain — разница, которую важно понимать
Эти два понятия путают чаще всего. Они не одно и то же.
Collision domain — область, где два устройства могут «столкнуться» при одновременной передаче (физическая коллизия сигналов).
- На хабе: collision domain = весь хаб. Все 8 портов хаба — один collision domain. Двое говорят одновременно — коллизия.
- На свитче: каждый порт = отдельный collision domain. Точка. Свитч физически разделяет порты.
- Full duplex Ethernet (современный): collision domain как понятие почти бессмысленно — одновременная передача в обе стороны — норма.
Broadcast domain — область, до которой долетит broadcast-кадр (dst MAC = ff:ff:ff:ff:ff:ff).
- На свитче: все порты — один broadcast domain. ARP-broadcast долетит до всех устройств за свитчём.
- Свитчи можно соединять цепочкой — broadcast domain расширяется (если без VLAN-ов — сильно расширяется, иногда болезненно).
- Граница broadcast domain — роутер. Роутер по умолчанию не пересылает broadcast’ы.
Почему это важно. Когда у вас в офисе 200 машин в одном broadcast domain:
- Каждый ARP-запрос видят все 200.
- DHCP DISCOVER (тоже broadcast) видят все 200.
- mDNS, LLMNR, NetBIOS broadcast’ы — всё в эту же кучу.
- Если кто-то сделает broadcast storm (петля в свитчах + broadcast в петле) — сеть умрёт.
Решение: делить broadcast domain на VLAN-ы (про них в следующем уроке) или использовать роутер.
Свитч — L2 устройство, но границы размываются
Классический свитч работает только на layer 2 — смотрит исключительно на MAC. Но в современности:
- L3 свитчи (managed) — умеют делать роутинг между VLAN-ами на железе, очень быстро. На уровне backplane они работают как роутер+свитч в одном корпусе.
- L4-L7 свитчи / load balancers — умеют делать решения на основе TCP-портов и даже HTTP-заголовков (это уже не свитчи, конечно, а application-level девайсы, но маркетинг такой).
В мире DC сейчас почти все свитчи — L3, потому что в современных топологиях (spine-leaf) роутинг на свитчах — норма.
Что с этим делать на практике
Видеть таблицу. Если у вас Linux-машина работает как свитч (через brctl или nmcli bridge), вы можете посмотреть bridge fdb show. Это полная аналогия MAC-table.
Понимать tcpdump. Если вы делаете tcpdump -i eth0 на машине — видите только трафик, который идёт через eth0 этой машины. Свитч не присылает вам чужой трафик. Это базовый ответ на «почему я не вижу пакеты между двумя соседями».
Чтобы увидеть чужой трафик:
- Сделать port mirror / SPAN на свитче (если есть admin-доступ).
- Использовать tap-устройство физически на проводе.
- Атаковать ARP-таблицы (ARP poisoning, но это незаконно за пределами своей лаборатории).
Понимать broadcast. Если ваш сервис делает много DNS lookup’ов на каждый запрос, эти DNS-запросы идут через свитч — normal traffic. Но если у вас в Kubernetes сотни pod’ов делают mDNS discovery — broadcast storm может положить весь сегмент.
Понимать MAC flapping. Если один MAC видим то с одного порта, то с другого — свитч начинает плеваться warnings. Это может быть:
- Петля в кабелях (два провода между свитчами без STP).
- Bond без правильной конфигурации (active-active без LACP).
- Виртуалка с миграцией между гипервизорами без правильной настройки.
# Логи свитча (Cisco):
# %MAC_MOVE-SP-4-NOTIF: Host AAAA.BBBB.CCCC in vlan 10 is flapping between port Gi1/0/3 and port Gi1/0/5
# Linux bridge:
dmesg | grep -i 'received packet on'
# или
bridge link show
Попробуй сам
# Если у вас Linux и есть рутовый доступ -- создайте свой свитч:
# 1. Создать bridge (программный свитч):
sudo ip link add name br-test type bridge
sudo ip link set br-test up
# 2. Добавить два виртуальных интерфейса (veth pair):
sudo ip link add veth-a type veth peer name veth-a-br
sudo ip link add veth-b type veth peer name veth-b-br
sudo ip link set veth-a-br master br-test
sudo ip link set veth-b-br master br-test
sudo ip link set veth-a-br up
sudo ip link set veth-b-br up
sudo ip link set veth-a up
sudo ip link set veth-b up
# 3. Задать IP в одном broadcast domain:
sudo ip addr add 10.99.99.1/24 dev veth-a
sudo ip addr add 10.99.99.2/24 dev veth-b
# 4. Пингануть и посмотреть, как заполняется MAC-table:
ping -c 3 -I veth-a 10.99.99.2
bridge fdb show br br-test # увидите MAC-и обоих veth
# +обнаружите, что свитч узнал MAC через MAC-learning
# 5. Сэмулировать сниффер -- запустить tcpdump на bridge:
sudo tcpdump -i br-test
# и параллельно генерировать трафик:
ping -I veth-a 10.99.99.2
# 6. Очистить:
sudo ip link del br-test
sudo ip link del veth-a
sudo ip link del veth-b
Это самый простой способ потрогать свитч руками — Linux bridge ведёт себя как реальный managed switch.
# Если у вас macOS -- запустите docker-контейнеры на одной bridge-сети:
docker network create test-bridge
docker run -d --name a --network test-bridge alpine sleep 1000
docker run -d --name b --network test-bridge alpine sleep 1000
docker exec a ping -c 3 b
# Под капотом Docker делает то же самое -- Linux bridge + veth.
Linux bridge в Docker: MAC-learning и forwarding в действии