Динамічна маршрутизація
Навіщо це
Section titled “Навіщо це”У модулі 7 таблицю маршрутів заповнювали руками: ip route add 10.0.23.0/24 via 10.0.12.2. На трьох маршрутизаторах це п’ять хвилин роботи. На тридцяти вже потрібна табличка, щоб нічого не забути. А тепер уявіть, що між двома з них обірвався кабель. Статичний маршрут про це не знає: він і далі вказує на мертву ланку, пакети зникають, а запасний шлях через третій маршрутизатор існує, але ніхто не сказав, що ним можна скористатися.
Динамічні протоколи маршрутизації самі розносять інформацію про префікси («за мною є 10.0.23.0/24»), самі помічають, що ланка зникла, і перераховують шляхи без участі людини. Є й причина не технічна: інтернет належить десяткам тисяч незалежних організацій, жодна з яких не може дати іншим команду. Вони домовляються між собою протоколом, і цей протокол, BGP, зовсім не схожий на те, що працює всередині однієї мережі.
Модуль спершу розбирає маршрутизацію всередині однієї організації (IGP, interior gateway protocol): тут усі довіряють одне одному, і мета проста, знайти найкоротший шлях. Далі йдеться про маршрутизацію між організаціями (EGP, exterior gateway protocol), де довіри немає, а мета зовсім інша: виконати політику власника мережі.
Передумови. Таблиця маршрутів і найдовший префікс (модуль 7), CIDR (модуль 6).
Як маршрутизатор дізнається топологію
Section titled “Як маршрутизатор дізнається топологію”Маршрутизатор бачить безпосередньо лише власні інтерфейси й сусідів на них. Про все інше йому мають розповісти, і розповідати можна двома принципово різними способами.
Distance vector: переказ чуток
Section titled “Distance vector: переказ чуток”За distance vector (вектор відстаней) маршрутизатор повідомляє сусідам таблицю «префікс і відстань до нього». Сусід додає до кожної відстані вартість ланки до відправника й запам’ятовує найкраще. Нічого, крім відстаней, ніхто не знає: про те, як саме влаштована мережа за сусідом, B мусить вірити сусідові на слово.
Найвідоміший представник, RIP, вимірює відстань у кількості переходів (hops) і вважає 16 «нескінченністю», тобто недосяжним префіксом. Він працює поверх UDP і вже давно вважається застарілим, але його вада повчальна.
Нехай C має єдиний шлях до мережі N через B. Ланка B до N обривається. B ще не встиг повідомити про це, а C вже оголосив йому «я знаю шлях до N, довжиною 2». B вирішує, що дорога до N проходить через C, записує довжину 3 і повідомляє це C. C оновлює своє значення до 4, B до 5, і так далі. Відстань росте по одиниці за раунд, поки не досягне «нескінченності». Це називається рахунком до нескінченності (count to infinity). Частково його гасять прийомами split horizon (не повідомляти маршрут тому, від кого він отриманий) і poison reverse (повідомляти такий маршрут із нескінченною відстанню), але повністю проблема не зникає.
Корінь проблеми в тому, що вектор відстаней не містить шляху. Маршрутизатор не бачить, що «найкращий шлях» сусіда проходить через нього самого.
Link state: спільна карта
Section titled “Link state: спільна карта”За link state (стан ланок) кожен маршрутизатор описує лише власні ланки: «я з’єднаний із B за вартістю 10 і з C за вартістю 10». Цей опис розсилається всім маршрутизаторам області, а не лише сусідам, і кожен його пересилає далі, не змінюючи. Після кількох раундів у всіх однакова база даних, тобто повна карта мережі. Далі кожен маршрутизатор запускає на цій карті алгоритм Дейкстри (у підручниках SPF, shortest path first), будує дерево найкоротших шляхів із себе самого й бере з нього наступні переходи.
Циклів такого типу, як рахунок до нескінченності, тут немає: всі обчислюють на одних і тих самих даних. Ціна інша. Кожен маршрутизатор тримає всю карту в пам’яті й має виконувати SPF щоразу, коли карта змінюється. Для мереж на сотні маршрутизаторів це нормально, для інтернету ні.
| Distance vector | Link state | |
|---|---|---|
| Що маршрутизатор отримує | відстані до префіксів від сусідів | описи ланок усіх маршрутизаторів області |
| Що знає про мережу | тільки результат | повну карту |
| Збіжність | повільна, можливі петлі | швидка, петель немає після синхронізації |
| Пам’ять і процесор | мало | більше, пропорційно розміру області |
| Приклади | RIP, основа BGP (path vector) | OSPF, IS-IS |
BGP належить до третьої породи, path vector (вектор шляхів): разом із префіксом він передає не число, а весь перелік автономних систем, крізь які пройшло оголошення. Це й лікує рахунок до нескінченності: маршрутизатор, побачивши в переліку власну систему, відкидає маршрут. Докладніше нижче.
OSPF: link state всередині організації
Section titled “OSPF: link state всередині організації”OSPF (Open Shortest Path First) є основним IGP у корпоративних мережах і в мережах операторів, поряд із IS-IS. Він працює безпосередньо поверх IP (номер протоколу 89, не TCP і не UDP), а сусіди спілкуються на мультикаст-адресах 224.0.0.5 і 224.0.0.6.
Сусіди, бази й області
Section titled “Сусіди, бази й області”Спочатку маршрутизатори знаходять один одного: кожен періодично шле пакети Hello. Якщо параметри сумісні, два маршрутизатори стають сусідами, обмінюються описами баз і доходять до стану Full, коли бази ідентичні. Якщо Hello від сусіда немає довше, ніж dead interval, сусід вважається зниклим, ланка з карти видаляється, а всі перераховують SPF.
Опис ланок розсилається в LSA (link-state advertisement). Щоб зрозуміти ідею, досить LSA маршрутизатора («ось мої інтерфейси, ось їхня вартість і кому вони ведуть»), LSA мережі (те саме, але для спільного сегмента, де сидить кілька маршрутизаторів одразу) і LSA зовнішніх маршрутів («за мною є префікси, які я отримав не з OSPF»). Кожна LSA має номер послідовності та вік: свіжіший запис замінює старіший, а маршрутизатор-власник перевипускає свою LSA періодично, щоб вона не зістарилася.
Якщо мережа велика, кожна зміна ланки викликає SPF на всіх маршрутизаторах. Щоб це стримати, OSPF ділить мережу на області (areas). Область 0 називається магістральною (backbone), решта під’єднуються до неї. Маршрутизатор на межі двох областей (ABR, area border router) не передає деталей ланок з однієї області в іншу: він передає лише підсумок «префікс і відстань». Усередині області всі бачать повну карту, а про інші області мають лише вектор відстаней, тож у великій мережі OSPF поєднує обидва підходи.
Вартість
Section titled “Вартість”OSPF обирає шлях із найменшою сумарною вартістю (cost) ланок, а не з найменшою кількістю переходів. Вартість інтерфейсу задається числом: його можна вказати вручну, а реалізації за замовчуванням виводять його з пропускної здатності (швидша ланка дешевша). Якщо два шляхи мають однакову суму, протокол може користуватися обома одразу (ECMP, модуль 7).
Збіжність
Section titled “Збіжність”Збіжність (convergence) означає, що після зміни топології всі маршрутизатори дійшли згоди про нові шляхи. Поки вона триває, пакети можуть губитися або ходити колами. Спершу треба зрозуміти, що ланка зникла, потім розіслати нову LSA й перерахувати SPF.
Розсилання й перерахунок швидкі, зазвичай мілісекунди або частки секунди на невеликій мережі. А от виявлення залежить від того, як сталася відмова. Якщо інтерфейс бачить втрату несучої, маршрутизатор дізнається негайно. Якщо ж кабель живий, а сусід мовчки перестав відповідати (зависла програма, фільтр на шляху, несправність на проміжному обладнанні), маршрутизатору залишається чекати на dead interval. За замовчуванням на типових ланках hello дорівнює 10 секундам, а dead дорівнює 40; коли кажуть, що «OSPF збігається за 40 секунд», мають на увазі саме цей випадок. Нижче ми самі змоделюємо обидва випадки.
BGP: протокол між автономними системами
Section titled “BGP: протокол між автономними системами”Навіщо потрібна ще одна система
Section titled “Навіщо потрібна ще одна система”Інтернет складається з автономних систем (AS, autonomous system): мереж під єдиним адміністративним керуванням із власною політикою маршрутизації. Кожна має номер (ASN). Це провайдери, великі компанії, університети, хмарні платформи. Усередині AS працює свій IGP. Між AS працює BGP (Border Gateway Protocol), на який спирається весь інтернет.
OSPF у масштабі інтернету не підходить. Заважає вже сам розмір: у глобальній таблиці близько мільйона префіксів IPv4, і вони змінюються постійно. Далі довіра: OSPF вимагає, щоб усі учасники були чесні й налаштовані узгоджено. Але головне — мета. Всередині мережі ви хочете найкоротший шлях. Між організаціями шлях визначають гроші й договори. Ваш провайдер платить вищому провайдеру за транзит, а трафік до конкурента може не хотіти пропускати взагалі. Найкоротший шлях може лежати через того, з ким ви не хочете ділитися мережею.
Як BGP влаштований
Section titled “Як BGP влаштований”Два сусідні маршрутизатори встановлюють між собою TCP-з’єднання на порт 179 і обмінюються повідомленнями OPEN, KEEPALIVE, UPDATE. Маршрутизатор, який «говорить BGP», називають спікером. Сусідів задають вручну: автоматичного виявлення в BGP немає, бо між організаціями має бути явна домовленість. Оскільки сесія іде поверх TCP, надійна доставка вже забезпечена, і BGP не повторює оголошень, як OSPF. Він надсилає лише зміни: новий маршрут або його відкликання (withdraw).
Сесія між різними AS називається eBGP, між маршрутизаторами однієї AS iBGP. Різниця суттєва. Коли маршрутизатор передає маршрут у eBGP, він додає свій номер AS на початок переліку, що йде разом із маршрутом. Цей перелік зветься AS_PATH. Коли маршрутизатор отримує маршрут по iBGP, AS_PATH він не змінює, а маршрут, отриманий від iBGP-сусіда, не передає іншому iBGP-сусідові. Тому всередині AS або з’єднують усі BGP-маршрутизатори в повну сітку, або користуються route reflector, який порушує це правило за домовленістю.
Маршрут у BGP має кілька атрибутів, окрім самого префікса. Головні: AS_PATH, NEXT_HOP (куди слати пакет), LOCAL_PREF (наскільки ми віддаємо перевагу цьому маршруту; передається лише всередині AS) та MED (підказка сусідній AS, крізь який вхід ви віддаєте перевагу).
Вибір найкращого маршруту
Section titled “Вибір найкращого маршруту”Якщо для одного префікса є кілька маршрутів, BGP порівнює їх у фіксованому порядку, і перша відмінність вирішує. Початок цього порядку такий:
- Вищий
LOCAL_PREF. - Коротший
AS_PATH. - Решта атрибутів (походження,
MED, eBGP краще за iBGP, менша вартість до next hop за IGP і, врешті, менший router ID).
Зверніть увагу: довжина шляху стоїть на другому місці, а на першому локальна політика. Оператор, який купив транзит і платить за трафік, ставить вищий LOCAL_PREF на маршрути від клієнтів (від них він заробляє) і нижчий на маршрути від платного провайдера (йому треба платити). Маршрут через клієнта буде обраний, навіть якщо AS_PATH через провайдера коротший.
Політика замість найкоротшого шляху
Section titled “Політика замість найкоротшого шляху”BGP не шукає найкращого шляху в технічному сенсі: він обирає шлях, який дозволяє політика. Між AS зазвичай буває так: клієнт платить провайдерові за транзит, а співмірні оператори обмінюються трафіком між собою безкоштовно (пірінг). З цього прямо випливають правила експорту:
- маршрути від клієнтів оголошують усім: чим більше людей бачить шляхи до клієнта, тим більше він платить вам за трафік;
- маршрути від провайдерів і пірингових партнерів оголошують лише клієнтам: ви не збираєтеся безкоштовно возити трафік одного провайдера до іншого.
Практичним виразом цих правил є фільтри на вході й виході (import і export) на кожній сесії. У BGP вони і є головним механізмом керування. Навіть BIRD відмовляється стартувати, якщо не заданий явний імпорт для eBGP (докладно в розділі про Linux).
Коли політика ламається
Section titled “Коли політика ламається”BGP будувався на довірі: маршрутизатор за замовчуванням вірить, що сусід оголошує лише те, що має право оголошувати. Цю довіру підважують і помилки, і зловмисники.
Перехоплення (hijack): хтось оголошує префікс, який йому не належить. Якщо оголошення збігається з чужим префіксом, решта вибирає між двома джерелами за коротшим AS_PATH, тобто частина інтернету піде до зловмисника, а частина до власника. Якщо оголошується довший префікс (наприклад, /25 усередині чужого /24), він перемагає всюди, куди дійшов, незалежно від AS_PATH: спрацьовує найдовший префікс із модуля 7, а BGP порівнює маршрути лише для однакового префікса. Рисунок вище показує саме цей випадок. Відомий приклад: у 2008 році один пакистанський оператор, намагаючись заблокувати YouTube усередині власної країни, оголосив зовнішньому світові довший префікс із адресного простору сервісу, і значна частина світового трафіку до нього потрапила на ту чорну діру.
Витік маршруту (route leak): маршрут, отриманий від одного провайдера чи піра, хтось передає іншому провайдерові або піру, всупереч політиці. Ніхто нічого не підробляє: усі оголошення справжні, просто нелогічні. Маленька мережа раптом виглядає найкоротшим шляхом до тисяч префіксів і засмоктує трафік, який не витримує її канали. Подібні інциденти траплялися з великими операторами, і майже завжди причиною була відсутність фільтра на сесії або помилка в ньому.
Окремо згадаймо інцидент 2021 року у Facebook. Помилкова команда під час обслуговування відрізала магістраль компанії від датацентрів, і авторитетні DNS-сервери, втративши зв’язок із ними, самі відкликали BGP-оголошення своїх префіксів. Назви сервісів перестали розв’язуватися, і сервіс став недоступним для всього світу. Це вже не перехоплення й не витік, а «самовідкликання»: точкою відмови тут стала сама BGP-таблиця.
Фільтри, prefix-list і RPKI
Section titled “Фільтри, prefix-list і RPKI”Перший захист простий: фільтрувати те, що приймаєте від клієнта, за переліком префіксів, які клієнт може оголошувати, і обмежувати кількість префіксів на сесію. Це працює для клієнтів, але не масштабується на весь інтернет, бо ніхто не збере вручну список чужих префіксів.
Для решти інтернету з’явилася RPKI (Resource Public Key Infrastructure): криптографічно підписана інфраструктура, яка прив’язує префікс до автономної системи, що має право його оригінувати. Власник адрес через свого реєстратора (RIR, regional internet registry: RIPE NCC, ARIN, APNIC, LACNIC і AFRINIC) створює підписаний запис ROA (Route Origin Authorization): «префікс 192.0.2.0/24, максимальна довжина 24, походить із AS65001». Оператори запускають програму-валідатор, яка збирає ROA з публічних сховищ, перевіряє підписи й передає маршрутизаторам список допустимих пар за протоколом RTR. Маршрутизатор звіряє кожне отримане оголошення з цим списком і відносить його до одного зі станів:
| Стан | Що означає |
|---|---|
| valid | є ROA, що покриває префікс, з таким origin AS і довжиною не більше допустимої |
| invalid | ROA для цього префікса є, але origin AS інший або префікс довший за дозволений |
| not found | жоден ROA не покриває префікс |
Перевірка називається ROV (route origin validation). Оператор зазвичай відкидає invalid, а not found приймає, бо ROA створено ще не для всіх префіксів.
Поле maxLength у ROA закриває якраз атаку довшим префіксом із попереднього розділу. Якщо власник створив ROA на /24 з максимальною довжиною 24, то /25 від зловмисника буде invalid навіть за правильного origin.
ROV перевіряє лише початок шляху (хто оригінує префікс), а не сам шлях. Зловмисник може додати в AS_PATH ім’я справжнього власника, і для ROV оголошення виглядатиме валідним. Від підробки шляху ROV не захищає; засоби для цього (BGPsec, ASPA) існують, але поширені значно менше. І ROV діє лише там, де його ввімкнено: якщо ваш сусід не відкидає invalid, вигода від вашого фільтра обмежена.
Як це насправді в Linux
Section titled “Як це насправді в Linux”Обидва протоколи запускаємо в просторах імен із BIRD 2: по одному процесу на простір імен, кожен зі своїм конфігом і сокетом керування. Так працює й лабораторна B3. Вивід нижче отримано на BIRD 2.14. Службові рядки BIRD 2.14 ready. і частину записів опущено, назви просторів імен спрощено.
OSPF на трьох маршрутизаторах
Section titled “OSPF на трьох маршрутизаторах”Трикутник із трьох просторів імен: r1, r2, r3. Між кожною парою лінк із мережею /24, на кожному на lo адреса 10.255.0.N/32. Конфіг r1 (на решті змінюється лише router id):
router id 10.255.0.1;protocol device {}protocol kernel { ipv4 { export all; }; }protocol ospf v2 o { ipv4 { import all; export all; }; area 0 { interface "lo" { stub; }; interface "m8-*" { type ptp; cost 10; hello 1; dead 4; }; };}protocol device потрібен, щоб BIRD бачив інтерфейси. protocol kernel експортує маршрути BIRD у таблицю ядра: без нього вони лишилися б усередині демона. interface "lo" { stub; } оголошує адресу петлі в OSPF, не шукаючи там сусідів. type ptp каже, що лінк двоточковий, і тому на ньому не обирають виділений маршрутизатор. Таймери hello 1; dead 4 взято малими навмисно, щоб збіжність було видно за секунди. Стандартні значення, як сказано вище, 10 і 40.
Запуск (на кожен простір імен окремо):
sudo ip netns exec r1 bird -c /tmp/r1.conf -s /tmp/r1.ctl -P /tmp/r1.pidЩо бачить r1 за кілька секунд:
$ ip netns exec r1 birdc -s /tmp/r1.ctl show ospf neighborso:Router ID Pri State DTime Interface Router IP10.255.0.2 1 Full/PtP 3.978 m8-12a 10.0.12.210.255.0.3 1 Full/PtP 3.990 m8-13a 10.0.13.3Обидва сусіди у стані Full, а DTime показує, скільки секунд лишилось до оголошення сусіда мертвим. З кожним Hello він скидається, тож якщо поспостерігати, значення коливається між 4 і 3 секундами.
$ ip netns exec r1 birdc -s /tmp/r1.ctl show route10.255.0.2/32 unicast [o 07:17:06.926] * I (150/10) [10.255.0.2] via 10.0.12.2 on m8-12a10.0.23.0/24 unicast [o 07:17:07.927] * I (150/20) [10.255.0.3] via 10.0.12.2 on m8-12a weight 1 via 10.0.13.3 on m8-13a weight 110.255.0.3/32 unicast [o 07:17:07.927] * I (150/10) [10.255.0.3] via 10.0.13.3 on m8-13aНа початку рядка префікс. [o ...] протокол, що дав маршрут, і час його появи. I позначає внутрішньозонний маршрут OSPF (intra-area), а (150/10) це пара «пріоритет протоколу / метрика»: пріоритет 150 BIRD присвоює OSPF, а 10 сума вартостей. Мережа 10.0.23.0/24 віддалена на 20 і досяжна двома шляхами з однаковою вартістю, тому BIRD записав обидва (ECMP). У ядрі це окремий маршрут із двома nexthop:
$ ip -n r1 route10.0.23.0/24 proto bird metric 32 nexthop via 10.0.12.2 dev m8-12a weight 1 nexthop via 10.0.13.3 dev m8-13a weight 110.255.0.2 via 10.0.12.2 dev m8-12a proto bird metric 3210.255.0.3 via 10.0.13.3 dev m8-13a proto bird metric 32proto bird у ip route показує, що маршрут поставлено демоном, а не адміністратором вручну.
Базу ланок, з якої SPF будує ці маршрути, видно командою show ospf state:
$ ip netns exec r1 birdc -s /tmp/r1.ctl show ospf statearea 0.0.0.0 router 10.255.0.1 distance 0 router 10.255.0.3 metric 10 stubnet 10.255.0.1/32 metric 0 stubnet 10.0.13.0/24 metric 10 router 10.255.0.3 distance 10 router 10.255.0.2 metric 10 router 10.255.0.1 metric 10 stubnet 10.255.0.3/32 metric 0 ...Це вміст LSA-баз: для кожного маршрутизатора його ланки до інших маршрутизаторів (router) і приєднані мережі (stubnet). distance це вартість шляху від нас, обчислена алгоритмом Дейкстри.
Обрив ланки
Section titled “Обрив ланки”Спершу просто погасимо інтерфейс:
sudo ip -n r1 link set m8-12a downveth-пара падає з обох боків, обидва маршрутизатори бачать втрату несучої, тому збіжність відбувається практично миттєво: вже за секунду 10.255.0.2/32 у r1 іде через 10.0.13.3 із вартістю 20.
Куди реалістичніший випадок: ланка формально жива, але сусід перестав відповідати. Змоделюємо його фільтром nftables на r2, який мовчки відкидає все, що приходить із боку r1:
sudo ip netns exec r2 nft add table inet fsudo ip netns exec r2 nft 'add chain inet f i { type filter hook input priority 0; }'sudo ip netns exec r2 nft add rule inet f i iifname '"m8-12b"' dropОдночасно з r1 пінгуємо 10.255.0.2 кожні кілька десятків мілісекунд і записуємо час кожної відповіді. Результат у нашому прогоні: пінг пропадав приблизно п’ять секунд, далі знову відповідав уже через r3:
-1.0 ok # до фільтра 0.1 lost # фільтр увімкнено 5.02 ok # dead interval (4 с) минув, SPF перерахував шляхП’ять секунд це наш dead 4 плюс час на розсилання LSA й перерахунок. На мережі зі стандартним dead 40 пауза була б близько сорока секунд. Через цей розрив у серйозних мережах, крім таймерів OSPF, використовують окремі швидші засоби виявлення відмови, зокрема BFD (Bidirectional Forwarding Detection).
eBGP між трьома AS
Section titled “eBGP між трьома AS”Чотири простори імен у ряд: a (AS65001) — b (AS65002) — c (AS65003) — x (AS65666). Номери з діапазону приватних, тому в публічному інтернеті їх не буде. a володіє 192.0.2.0/24, c володіє 198.51.100.0/24 (обидва префікси з діапазонів, зарезервованих для документації). Конфіг b, транзитного оператора:
router id 10.1.1.2;protocol device {}protocol kernel { ipv4 { import none; export all; }; }protocol bgp toA { local 10.1.1.2 as 65002; neighbor 10.1.1.1 as 65001; ipv4 { import all; export all; };}protocol bgp toC { local 10.1.2.1 as 65002; neighbor 10.1.2.2 as 65003; ipv4 { import all; export all; };}Якщо ж забути import, BIRD не стартує:
bird: t1.conf:3:80 EBGP requires explicit import policyТак BIRD виконує рекомендацію, за якою eBGP за замовчуванням має відкидати все, і новачок не відкриє невідомому сусідові увесь свій реєстр випадково.
Після встановлення сесій c бачить префікс a із довгим шляхом:
$ ip netns exec c birdc -s /tmp/c.ctl show route all 192.0.2.0/24192.0.2.0/24 unicast [toB 07:18:10.107] * (100) [AS65001i] via 10.1.2.1 on m8-bcb Type: BGP univ BGP.origin: IGP BGP.as_path: 65002 65001 BGP.next_hop: 10.1.2.1 BGP.local_pref: 100[AS65001i] показує, звідки маршрут походить: i означає origin IGP. BGP.as_path: 65002 65001 читається справа наліво: префікс створила AS65001, а AS65002 передала його далі. next_hop за eBGP це адреса сусіда.
Політика виглядає як код фільтра. Щоб b надавав перевагу маршрутам від a, достатньо змінити імпорт:
ipv4 { import filter { bgp_local_pref = 200; accept; }; export all; };і в show route all з’являється BGP.local_pref: 200 замість стандартних 100.
Перехоплення в дії
Section titled “Перехоплення в дії”Тепер x (AS65666), під’єднаний до c, оголошує 192.0.2.0/25. c приймає все підряд:
$ ip netns exec c birdc -s /tmp/c.ctl show route192.0.2.0/25 unicast [toX 07:18:09.528] * (100) [AS65666i] via 10.1.3.2 on m8-cxa192.0.2.0/24 unicast [toB 07:18:10.107] * (100) [AS65001i] via 10.1.2.1 on m8-bcb$ ip netns exec c ip route get 192.0.2.5192.0.2.5 via 10.1.3.2 dev m8-cxa src 10.1.3.1Таблиця c тепер має і /24 від справжнього власника, і /25 від x. Для адреси 192.0.2.5 перемагає /25, і пакет іде до x.
Додаємо на c локальний ROA-набір і фільтр для сесії з x:
roa4 table roas;protocol static { roa4 { table roas; }; route 192.0.2.0/24 max 24 as 65001; route 198.51.100.0/24 max 24 as 65003;}filter from_customer { if roa_check(roas, net, bgp_path.last) = ROA_INVALID then reject; accept;}У конфіг сесії toX замінюємо import all на import filter from_customer. Після birdc configure:
$ ip netns exec c birdc -s /tmp/c.ctl show route198.51.100.0/24 blackhole [static2 07:18:27.604] * (200)192.0.2.0/24 unicast [toB 07:18:10.107] * (100) [AS65001i] via 10.1.2.1 on m8-bcb$ ip netns exec c ip route get 192.0.2.5192.0.2.5 via 10.1.2.1 dev m8-bcb src 10.1.2.2Маршрут від x відкинуто як invalid: ROA для 192.0.2.0/24 дозволяє лише origin AS65001 і довжину не більшу за 24. У реальній мережі ROA не пишуть вручну, їх завантажує валідатор за протоколом RTR, а в BIRD 2 для цього є protocol rpki. Ми тут використали статичну таблицю, щоб не залежати від зовнішніх серверів, і це єдина відмінність.
Корисні команди на щодень:
birdc show protocols # стан усіх протоколів і сесійbirdc show protocols all toA # деталі сесії, лічильники прийнятих і відхилених маршрутівbirdc show route protocol toC # маршрути, отримані від конкретного сусідаbirdc show route export toC # що ми оголошуємо цьому сусідовіbirdc show route for 192.0.2.5 # який маршрут спрацює для адресиbirdc configure # застосувати змінений конфіг без перезапускуТипові помилки розуміння
Section titled “Типові помилки розуміння”BGP обирає найкоротший шлях. Найкоротший AS_PATH лише другий критерій, після LOCAL_PREF. Перший вирішує політика оператора, тож трафік часто йде довшою дорогою, бо вона дешевша чи вигідніша за договором.
Більше AS у шляху означає більше переходів маршрутизаторів. Одна AS може складатися з одного маршрутизатора, а може з тисяч, і транзитний пакет пройде всередині неї десятки переходів, які AS_PATH не рахує. Довжина AS_PATH це кількість організацій, а не затримка й не відстань.
Якщо маршрут прийшов, за ним можна їхати. Маршрут у таблиці BGP означає лише «сусід каже, що вміє доставити». Вузол за сусідом може бути недоступний, а сам сусід може брехати чи помилятися. Перевірка походження (RPKI) і фільтри потрібні й тоді, коли сесія встановлена й усе «працює».
RPKI захищає від усіх підробок маршрутів. Вона підтверджує лише походження префікса, а не шлях. Вона не допоможе, якщо зловмисник вставить справжнього власника в AS_PATH, а також нічого не робить там, де оператор її не ввімкнув.
OSPF збігається за секунди. Тільки коли вихід з ладу помітний одразу, наприклад несуча зникла. Якщо сусід мовчки зник, це триватиме до dead interval, і це ті самі 40 секунд за стандартних налаштувань. Швидше можна, але це окреме налаштування (менші таймери або BFD).
Динамічний протокол заміняє статичні маршрути. Зазвичай вони співіснують. Маршрут за замовчуванням на межі мережі найчастіше статичний, а динамічний протокол поширює решту. Різні джерела маршрутів для одного префікса порівнюються за пріоритетом (administrative distance у термінології деяких вендорів), який у BIRD задає число в дужках (150/10).
Перевір себе
Лабораторна
Section titled “Лабораторна”B3. OSPF і BGP. Чотири маршрутизатори в просторах імен із BIRD 2: спершу OSPF і заміри збіжності після розриву ланки, потім eBGP між двома AS із політикою на вході й виході. Саме там ви обірвете ланку двома способами, як у цьому модулі, і виміряєте різницю.
Джерела
Section titled “Джерела”- Kurose, Ross, Computer Networking: A Top-Down Approach, розділи про маршрутизацію всередині AS (OSPF) і між AS (BGP)
- Peterson, Davie, Computer Networks: A Systems Approach, розділ про маршрутизацію
- Tanenbaum, Feamster, Wetherall, Computer Networks, розділ про мережевий рівень
- Документація BIRD 2: bird.network.cz, розділи про OSPF, BGP, фільтри й RPKI
- RFC 2328 (OSPF версії 2), RFC 4271 (BGP-4), RFC 8212 (типова політика eBGP), RFC 6811 (перевірка походження маршруту на основі RPKI)
man ip-route(8),man nft(8)