Перейти до вмісту

B1. Міст і VLAN руками

базовийспирається на модуль 4, модуль 5

Модуль 4 каже, що комутатор вчиться: бачить адресу відправника кадру й запам’ятовує, з якого порту той прийшов. Модуль 5 додає, що одну фізичну коробку можна розрізати на кілька окремих широкомовних доменів. У цій роботі ви побудуєте такий комутатор зі звичайних шматків Linux: міст (bridge), пар veth і простору імен на кожен хост. Потім спостерігатимете все те, про що говорить теорія: запит ARP, який долітає лише до «своїх», і таблицю MAC, що наповнюється на очах.

Після цієї роботи ви зможете:

  • зібрати міст із кількома портами в окремому просторі імен і під’єднати до нього хости парами veth;
  • увімкнути VLAN-фільтрацію на мосту й налаштувати порти доступу (bridge vlan add ... pvid untagged);
  • показати в tcpdump, що широкомовний ARP-запит доходить лише до хостів своєї VLAN;
  • прочитати таблицю MAC (bridge fdb show) і пояснити, чому в ній один MAC з’являється з номером VLAN;
  • довести, що хост однієї VLAN не дістає хоста іншої навіть тоді, коли підмережа в нього «правильна».

Так перевіряють мережу, коли «принтер в іншому відділі не бачить сервера»: спершу з’ясовують, в одній вони широкомовній області чи в різних, і вже потім шукають проблему вище.

Результат роботи — п’ять просторів імен і міст у одному з них, за схемою:

Простір імен Роль Адреса VLAN
sw комутатор (міст, без IP-адреси) немає
h1 хост 10.0.10.1/24 10
h2 хост 10.0.10.2/24 10
h3 хост 10.0.20.1/24 20
h4 хост 10.0.20.2/24 20

Назви просторів імен і адреси зафіксовані, їх перевіряє check.sh. Назви мосту, портів і інтерфейсів у хостах оберіть самі.

Що зробити:

  1. Створити простори імен і з’єднати кожен хост із sw парою veth: один кінець у хості, другий у sw і підключений до мосту.
  2. Увімкнути на мосту VLAN-фільтрацію й розкласти порти: h1, h2 у VLAN 10, h3, h4 у VLAN 20, як порти доступу (кадри хоста без тега потрапляють у свою VLAN і виходять до хоста без тега).
  3. Переконатися, що хости всередині VLAN бачать одне одного.
  4. Показати в tcpdump широкомовний ARP-запит і те, куди він дійшов, а куди ні.
  5. Прочитати таблицю MAC моста й зіставити записи з MAC-адресами хостів.
  6. Довести, що VLAN не сполучаються: зробити так, щоб для h1 хост h3 був «на тому самому дроті», і переконатися, що міст його не пропускає.

Чого робити не треба. Маршрутизація між VLAN (міжVLANний маршрутизатор) у цю роботу не входить, вона з’явиться в B2. Тегований транк між комутаторами, STP і агрегація каналів теж не потрібні. Адреси на самому мості не призначайте: нехай sw буде чистим комутатором.

Обмеження. Тільки ip і bridge з пакета iproute2: без brctl, без Open vSwitch і без підінтерфейсів ip link add ... type vlan. Суть роботи в тому, щоб VLAN робив сам міст.

Готово, коли sudo ./check.sh не показує жодного «НІ», а в нотатках у вас є відповіді на питання з етапів 4, 5 і 6.

  • Прочитайте в модулі 4 розділ про таблицю комутації й у модулі 5 розділи про VLAN і ARP.
  • Встановіть інструменти: sudo bash setup/provision.sh (потрібні iproute2, tcpdump, python3).
  • Потрібні права root. Підходить віртуальна машина з setup/Vagrantfile. У контейнері VLAN-фільтрація на мосту часто вимкнена в ядрі господаря: перевірте sudo bash setup/probe-net-env.sh, рядок про міст і VLAN. Якщо вона недоступна, для цієї роботи потрібна віртуальна машина.
  • Працюйте в каталозі labs/b1-bridge-vlan. Заготовок немає: топологію ви будуєте самі, check.sh лише перевіряє.
  1. Простори імен і міст.

    Terminal window
    sudo ip netns add sw
    for h in h1 h2 h3 h4; do sudo ip netns add $h; done
    sudo ip netns exec sw ip link add br0 type bridge
    sudo ip netns exec sw ip link set br0 up

    Міст поки що звичайний: без VLAN-фільтрації він пересилає кадри між усіма портами за таблицею MAC, тобто працює як один великий комутатор.

    Перевірте: sudo ip netns exec sw ip -d link show br0 показує vlan_filtering 0.

  2. Хости й дроти.

    Для кожного хоста потрібна пара veth. Її можна створити разом з розкладанням кінців по просторах імен:

    Terminal window
    sudo ip link add sw-h1 netns sw type veth peer name eth0 netns h1
    sudo ip netns exec sw ip link set sw-h1 master br0
    sudo ip netns exec sw ip link set sw-h1 up
    sudo ip netns exec h1 ip link set lo up
    sudo ip netns exec h1 ip addr add 10.0.10.1/24 dev eth0
    sudo ip netns exec h1 ip link set eth0 up

    Повторіть для h2, h3 і h4 зі своїми адресами з таблиці.

    Перевірте: поки VLAN-фільтрації немає, усі чотири хости бачать одне одного. sudo ip netns exec h1 ping -c1 10.0.10.2 проходить, а от до h3 потрібна ще спільна підмережа: додайте на h1 тимчасово адресу 10.0.20.99/24 і пропінгуйте 10.0.20.1. Це буде вашою контрольною точкою «до»: міст без VLAN не розрізняє нікого. Тимчасову адресу потім приберіть: ip addr del 10.0.20.99/24 dev eth0.

  3. VLAN-фільтрація.

    Terminal window
    sudo ip netns exec sw ip link set br0 type bridge vlan_filtering 1
    sudo ip netns exec sw bridge vlan show

    Тепер кожен порт за замовчуванням належить до VLAN 1 (вона ж pvid і untagged). Замініть її на потрібну для кожного порту:

    Terminal window
    sudo ip netns exec sw bridge vlan del dev sw-h1 vid 1
    sudo ip netns exec sw bridge vlan add dev sw-h1 vid 10 pvid untagged

    pvid означає, що кадр без тега, який вхопив порт, отримає цей номер VLAN. untagged означає, що на виході з порту тег знімається, тож хосту не доводиться нічого знати про VLAN. Так поводиться порт доступу на справжньому комутаторі.

    Перевірте: bridge vlan show у sw показує порти h1 і h2 у VLAN 10, а h3 і h4 у VLAN 20, і жоден порт не сидить у двох.

  4. ARP і широкомовлення в tcpdump.

    Очистіть ARP-таблицю h1 і запустіть захоплення на h2, h3 та h4 (у трьох вікнах термінала або у фоні):

    Terminal window
    sudo ip netns exec h2 tcpdump -ni any -e arp
    sudo ip netns exec h3 tcpdump -ni any -e arp
    sudo ip netns exec h4 tcpdump -ni any -e arp

    Потім з h1:

    Terminal window
    sudo ip netns exec h1 ip neigh flush all
    sudo ip netns exec h1 ping -c1 10.0.10.2

    На h2 ви побачите запит who-has 10.0.10.2 tell 10.0.10.1 на адресу ff:ff:ff:ff:ff:ff і відповідь на нього. На h3 і h4 нічого. Це і є межа широкомовного домену.

    Запишіть: чому запит ішов широкомовно, а відповідь одноадресно? Звідки h2 знає MAC-адресу h1, щоб відповісти саме їй?

  5. Таблиця MAC.

    Terminal window
    sudo ip netns exec sw bridge fdb show

    Серед рядків знайдіть записи з MAC-адресами хостів. ip -o link у кожному хості покаже його адресу. Запис виглядає приблизно так:

    9e:3a:b5:e0:d1:1c dev sw-h1 vlan 10 master br0

    Звіртеся: у кожного з чотирьох хостів є запис із його VLAN. Виміряйте, як швидко запис зникає: cat /sys/class/net/br0/bridge/ageing_time у sw показує час життя в сотих частках секунди.

    Запишіть: чому до першого пакета таблиця порожня і що міст робить з кадром, адреси одержувача якого він ще не знає?

  6. Ізоляція.

    У різних підмережах h1 і h3 не пінгуються й без VLAN, бо в них немає маршруту. Тож щоб перевірити саме канальний рівень, зробіть так, щоб вони були в одній підмережі. Тимчасово додайте h1 адресу з підмережі VLAN 20:

    Terminal window
    sudo ip netns exec h1 ip addr add 10.0.20.99/24 dev eth0
    sudo ip netns exec h1 ping -c2 -W1 10.0.20.1

    Пінг не проходить, а tcpdump на h3 не бачить навіть запиту ARP: кадр застряг у VLAN 10. Порівняйте з етапом 2, коли той самий експеримент проходив. Приберіть адресу.

    Запишіть: чому роздати різні підмережі недостатньо для ізоляції і чим VLAN відрізняється від просто двох підмереж на одному мосту?

Terminal window
sudo ./check.sh

Скрипт нічого не будує. Він знаходить хост за адресою, а міст за типом, тож назви інтерфейсів і мосту можуть бути будь-якими. Перевіряється:

  • адреси на чотирьох хостах;
  • що в sw є міст із щонайменше чотирма портами, на ньому ввімкнено VLAN-фільтрацію, а в bridge vlan show є по два порти у VLAN 10 і 20;
  • що хости в межах VLAN пінгують одне одного;
  • що ізоляція працює на канальному рівні: скрипт на кілька секунд додає h1 адресу з підмережі VLAN 20 (і навпаки h3), перевіряє, що ARP не проходить, і забирає адреси назад;
  • що широкомовний ARP-запит h1 доходить до h2, але не до h3 і h4 (через tcpdump);
  • що в таблиці MAC є всі чотири хости, кожен зі своїм номером VLAN.

Приклад розбору: якщо ви забули прибрати VLAN 1 з портів, але pvid виставили правильно, перевірка пройде. Кадри без тега однаково потраплять у VLAN 10 або 20, а VLAN 1 лишиться порожньою. Якщо ж VLAN-фільтрацію не ввімкнули, впадуть саме перевірки ізоляції й широкомовлення: міст перешле ARP усім.

vlan_filtering не ввімкнено. bridge vlan add у такому разі може виконатися без помилок, але міст ігнорує номери VLAN і працює як звичайний. Перевірте ip -d link show <міст>.

Порт залишився у VLAN 1. Порт, який ви додали у VLAN 10 без pvid, не прийматиме кадрів від хоста без тега: вони потраплять у pvid, а це досі VLAN 1. Симптом: хост пінгує «в нікуди». pvid untagged потрібні обидва.

Інтерфейс хоста не піднято. Створений veth у стані DOWN, і в хості, і в мосту. Піднімайте обидва кінці, включно з lo.

Перевірка ізоляції нібито проходить. Якщо ви пінгуєте h3 з h1 без спільної підмережі, пінг не проходить з іншої причини: немає маршруту. Перевіряти треба саме канальний рівень, як в етапі 6.

Старий ARP-кеш. Хост пам’ятає відповідь хвилину-дві. Якщо після переналаштування поведінка не змінилась, зробіть ip neigh flush all у хості.

Додайте тегований порт (bridge vlan add dev <порт> vid 10 без pvid untagged) і підключіть до нього п’ятий хост з інтерфейсом ip link add link eth0 name eth0.10 type vlan id 10: так виглядає транк між комутаторами. Спробуйте також вимкнути навчання MAC на порту (bridge link set dev <порт> learning off) і подивіться, як комутатор перетворюється на концентратор для одержувачів, яких не знає.