Сети для самых маленьких. Часть 21: OSPF
В шестой части таблица маршрутов роутера заполнялась тремя способами: подключённые сети появлялись сами, статические писал администратор, а динамические «приходили от протоколов маршрутизации, по которым роутеры рассказывают друг другу о своих сетях». Пора разобрать, как именно рассказывают. Внутри одной организации — офиса, кампуса, дата-центра, сети провайдера — это почти всегда OSPF, Open Shortest Path First, RFC 2328. Между организациями — BGP, и он в следующей части.
Зачем динамическая маршрутизация
Три роутера, пять сетей — статические маршруты пишутся за десять минут. Тридцать роутеров, две сотни сетей и резервные линки — уже нет: каждую новую сеть надо прописать на каждом роутере, а при обрыве кабеля кто-то должен руками переключить маршруты на обходной путь. Динамический протокол решает обе задачи: роутеры сами узнают обо всех сетях и сами перестраивают пути при отказах.
Два семейства протоколов, и разница между ними — главное, что нужно понять.
Distance-vector: каждый роутер периодически отдаёт соседям всю свою таблицу — «до сети X мне 3 хопа», — и сосед записывает «до X 4 хопа через него». Никто не знает карты сети, все знают только расстояния по слухам. Так работает RIP, протокол 1988 года: метрика — число хопов, не больше 15, таблицы рассылаются каждые 30 секунд, сходимость после отказа — минуты, а петли между соседями, которые верят друг другу, — классическая проблема. RIP жив в учебниках и в маленьких сетях, где его хватает.
Link-state: каждый роутер описывает только свои линки — «у меня есть интерфейсы в такие-то сети с такой-то стоимостью, за ними такие-то соседи» — и рассылает это описание всем роутерам сети. У всех собирается одинаковая карта, и каждый сам считает по ней кратчайшие пути от себя. Карта точная, петель по построению нет, сходимость — секунды. Это OSPF и его двойник IS-IS (та же идея, другой формат, работает прямо поверх канального уровня без IP; его любят крупные провайдеры).
Протоколы внутри одной организации называют IGP (interior gateway protocol), между организациями — EGP. OSPF — IGP; граница его ответственности — ваша сеть.
Где живёт OSPF
OSPF — не поверх UDP или TCP, а прямо в IP, протокол номер 89. Надёжность доставки он обеспечивает сам, подтверждениями. Пакеты уходят на групповые адреса 224.0.0.5 (все OSPF-роутеры) и 224.0.0.6 (только DR и BDR, об этом ниже), с TTL 1: за пределы сегмента ничего не уходит, разговор всегда между соседями по кабелю.
Пять типов пакетов, общий заголовок:
байты: 1 1 2 4 4 2 2 8
┌───────┬───────┬────────┬────────────┬────────────┬────────┬────────┬──────────┐
│ Ver=2 │ Type │ Length │ Router ID │ Area ID │ Chksum │ AuType │ Auth │
└───────┴───────┴────────┴────────────┴────────────┴────────┴────────┴──────────┘
| Type | Пакет | Для чего |
|---|---|---|
| 1 | Hello | найти соседей и держать соседство |
| 2 | Database Description (DBD) | список заголовков LSA, которые у меня есть |
| 3 | Link State Request (LSR) | «пришли мне вот эти LSA целиком» |
| 4 | Link State Update (LSU) | сами LSA, одна или несколько |
| 5 | Link State Ack | подтверждение получения LSU |
Router ID — 32-битный идентификатор роутера, записывается как IP-адрес, но адресом не является: его задают руками (10.0.0.1), а если не задали, роутер возьмёт старший адрес loopback-интерфейса. Все LSA подписаны им, и два роутера с одинаковым Router ID ломают сеть молча: их LSA перезаписывают друг друга.
Hello: найти соседей
Роутер с включённым OSPF на интерфейсе шлёт Hello каждые 10 секунд (на медленных линках 30) на 224.0.0.5:
$ sudo tcpdump -i eth1 -n -v proto ospf
IP (tos 0xc0, ttl 1, id 0, offset 0, flags [none], proto OSPF (89), length 68)
10.1.12.1 > 224.0.0.5: OSPFv2, Hello, length 48
Router-ID 10.0.0.1, Backbone Area, Authentication Type: none (0)
Options [External]
Hello Timer 10s, Dead Timer 40s, Mask 255.255.255.252, Priority 1
Designated Router 10.1.12.1
Neighbor List:
10.0.0.2
В Hello — параметры, которые у соседей обязаны совпадать: Area ID, таймеры Hello и Dead, маска подсети (на Ethernet-сегментах), тип аутентификации. Не совпали — соседства не будет, и в логе появится сообщение вроде «Hello timer mismatch». Это первое, что проверяют, когда «OSPF не поднимается». Ещё в Hello — список соседей, от которых я сам слышал Hello: увидев себя в чужом списке, роутер понимает, что связь двусторонняя.
Dead Timer — 40 секунд, четыре пропущенных Hello: сосед считается мёртвым, его LSA помечаются недостижимыми, пути пересчитываются. Если линк физически упал, интерфейс сообщит об этом сразу, не дожидаясь 40 секунд; ждать приходится, когда линк «вроде есть», а сосед не отвечает — за коммутатором, например. Для быстрого обнаружения есть BFD: отдельный протокол, в котором соседи обмениваются крошечными пакетами каждые 50–300 мс и сообщают OSPF об обрыве за доли секунды.
Соседство: от Hello до Full
Два роутера, услышавшие друг друга, проходят состояния:
Down ──► Init ──► 2-Way ──► ExStart ──► Exchange ──► Loading ──► Full
Hello вижу кто обмен DBD: LSR/LSU: базы
получен себя в ведущий, заголовки запросить одинаковы
его Hello номера LSA недостающее
- Init — получил Hello от соседа. 2-Way — сосед включил меня в свой список: связь в обе стороны.
- ExStart — договориться, кто ведущий (по Router ID), и с какого номера нумеровать DBD.
- Exchange — обменяться описаниями баз: не самими LSA, а их заголовками с номерами версий. Каждый сравнивает со своей базой.
- Loading — запросить (LSR) те LSA, которых нет или которые у соседа новее, получить их (LSU), подтвердить (LSAck).
- Full — базы одинаковы. С этого момента новые LSA просто пересылаются, по мере появления.
$ vtysh -c 'show ip ospf neighbor'
Neighbor ID Pri State Dead Time Address Interface RXmtL RqstL DBsmL
10.0.0.2 1 Full/- 38.123s 10.1.12.2 eth1:10.1.12.1 0 0 0
10.0.0.3 1 Full/- 35.456s 10.1.13.3 eth2:10.1.13.1 0 0 0
Full — норма. Застрявшее в ExStart или Exchange соседство — почти всегда несовпадение MTU: оно передаётся в DBD, и роутер с MTU 1500 отказывается разговаривать с соседом, объявившим 9000. Застрявшее в 2-Way — норма для DROther на сегменте с DR, см. ниже, и ошибка во всех остальных случаях.
DR и BDR
На Ethernet-сегменте с пятью роутерами полное соседство каждого с каждым — десять соседств и десятикратное дублирование LSA. Поэтому на многоточечных сегментах выбирается Designated Router и запасной BDR: все остальные (DROther) держат Full только с ними, а между собой остаются в 2-Way. LSA отправляются DR на 224.0.0.6, DR рассылает их всем на 224.0.0.5. Выбор — по приоритету из Hello (0 — не участвовать), при равенстве по старшему Router ID, и DR не переизбирается, пока жив: первый поднявшийся остаётся, даже если потом появился роутер с большим приоритетом.
На линке точка-точка (два роутера на одном кабеле или /30) DR не нужен, и его отключают: ip ospf network point-to-point. В примере выше состояние Full/- — именно поэтому: на /30 выбор DR бессмысленен и только замедляет сходимость.
LSA: описание линков
LSA (link-state advertisement) — запись в общей базе. Каждая описывает один объект сети и живёт в LSDB каждого роутера области. Заголовок LSA:
┌──────────┬──────┬──────────────┬────────────────────┬────────────┬──────────┬────────┐
│ LS Age │ Type │ Link State ID│ Advertising Router │ Seq Number │ Checksum │ Length │
│ секунды │ │ что описано │ кто создал (RID) │ версия │ │ │
└──────────┴──────┴──────────────┴────────────────────┴────────────┴──────────┴────────┘
Главные типы:
| Type | Имя | Кто создаёт | Что описывает |
|---|---|---|---|
| 1 | Router LSA | каждый роутер | все свои линки в области: сосед или сеть за ними, стоимость |
| 2 | Network LSA | DR сегмента | сегмент и список роутеров на нём |
| 3 | Summary LSA | ABR | сеть из другой области: префикс и стоимость до него |
| 4 | ASBR Summary | ABR | как добраться до роутера, который ввёл внешние маршруты |
| 5 | External LSA | ASBR | маршрут снаружи OSPF: статический, из BGP, из другого процесса |
| 7 | NSSA External | ASBR в NSSA | то же, но внутри особой области, см. ниже |
Правила жизни LSA: создатель переиздаёт свою LSA каждые 30 минут с увеличенным Seq Number; получив LSA с бо́льшим номером, роутер заменяет старую и пересылает дальше всем соседям, кроме того, от кого получил (это и есть flooding); LSA, которую никто не обновлял 60 минут (LS Age = 3600), удаляется. При изменении — упал линк, появилась сеть — создатель немедленно издаёт новую версию, и за секунды она оказывается у всех.
Базу видно целиком:
$ vtysh -c 'show ip ospf database'
OSPF Router with ID (10.0.0.1)
Router Link States (Area 0.0.0.0)
Link ID ADV Router Age Seq# CkSum Link count
10.0.0.1 10.0.0.1 312 0x8000000a 0x1a2b 3
10.0.0.2 10.0.0.2 298 0x80000009 0x3c4d 3
10.0.0.3 10.0.0.3 301 0x8000000b 0x5e6f 3
Три Router LSA — три роутера в области, у каждого три линка. Базы на всех трёх роутерах побайтово одинаковы; если на одном роутере Seq# у чьей-то LSA отстаёт, flooding сломан, и начинать искать надо оттуда.
SPF: считаем пути
У каждого роутера одинаковая карта; дальше каждый считает от себя алгоритмом Дейкстры — кратчайшие пути во взвешенном графе, где вершины — роутеры и сегменты, а веса — стоимости интерфейсов.
Стоимость интерфейса = эталонная полоса / полоса интерфейса. Умолчание эталона — 100 Мбит/с, выбрано в 1990-х, и с ним все линки от 100 Мбит/с и выше получают стоимость 1: гигабит и 10 гигабит неразличимы. Первое, что делают в любой современной сети, — auto-cost reference-bandwidth 100000 (100 Гбит/с) на всех роутерах одинаково: тогда 10G = 10, 1G = 100, 100M = 1000. Стоимость пути — сумма стоимостей исходящих интерфейсов по дороге, включая интерфейс последнего роутера в сеть назначения.
Пример, с которым дальше будем работать:
R2 10.0.0.2
╱ ╲
1G, 100 ╱ ╲ 1G, 100
╱ ╲
R1 10.0.0.1 ────────────── R3 10.0.0.3 ──── 192.168.10.0/24 (1G, 100)
100M, 1000
Кратчайший путь из R1 в 192.168.10.0/24: напрямую через R3 — 1000 + 100 = 1100; через R2 — 100 + 100 + 100 = 300. Побеждает путь через R2, хотя он длиннее в хопах: OSPF считает полосу, а не хопы. В таблице R1:
$ vtysh -c 'show ip route ospf'
O>* 192.168.10.0/24 [110/300] via 10.1.12.2, eth1, weight 1, 00:10:12
O>* 10.0.0.2/32 [110/100] via 10.1.12.2, eth1, weight 1, 00:10:12
O>* 10.0.0.3/32 [110/200] via 10.1.12.2, eth1, weight 1, 00:10:12
O 10.1.23.0/30 [110/200] via 10.1.12.2, eth1, weight 1, 00:10:12
[110/300] — административная дистанция 110 (приоритет источника маршрута: подключённые 0, статические 1, OSPF 110, iBGP 200: при одинаковом префиксе из разных источников побеждает меньшая) и стоимость 300. Если два пути получат одинаковую стоимость, в таблицу попадут оба — ECMP, и трафик разложится по ним по хешу потоков.
Обрыв линка R1–R2: интерфейс eth1 падает, R1 немедленно издаёт новую Router LSA без этого линка, R2 — свою; LSA разлетаются за секунду; все роутеры запускают SPF (миллисекунды на сотнях узлов); у R1 путь в 192.168.10.0/24 становится 1100 через R3. Никто ничего не настраивал.
Области
LSDB всей сети у каждого роутера и SPF по всему графу — это масштабируется до нескольких сотен роутеров, а дальше базы и пересчёты становятся тяжёлыми, и любая моргающая линия на краю сети заставляет всех пересчитывать всё. Поэтому OSPF делит сеть на области (areas):
R10 ── R11 ── R12 ── ABR-A ── R1 ── R2 ── R3 ── ABR-B ── R20 ── R21
└──────── area 1 ────────┘ └──── area 2 ─────┘
└────── area 0, backbone ──────┘
ABR-A и ABR-B стоят в двух областях сразу; трафик area 1 ↔ area 2 идёт через area 0
- Внутри области — полная карта и SPF, как описано выше. Router и Network LSA (типы 1, 2) не выходят за границу области.
- Area 0, backbone — обязательная область, к которой подключены все остальные; трафик между двумя не-backbone областями идёт через неё.
- ABR (area border router) стоит в двух областях, держит две LSDB и передаёт из одной в другую не карту, а итоги: Summary LSA (тип 3) — «сеть
192.168.10.0/24, стоимость до неё от меня 300». Между областями OSPF ведёт себя как distance-vector: чужую топологию никто не видит, только расстояния до префиксов через ABR. - Чтобы совсем не грузить маленькие области, их делают stub: ABR не передаёт внутрь внешние маршруты (тип 5), только маршрут по умолчанию; totally stubby — не передаёт и Summary, только default; NSSA — stub, который сам может вводить внешние маршруты типом 7, а ABR превращает их в тип 5 для остальных.
Для сети из десяти роутеров области не нужны: одна area 0. Границу в несколько сотен роутеров на область сегодня, с быстрыми процессорами, проходят легко, и дробят сеть чаще по административным причинам, чем по техническим.
Внешние маршруты
Маршрут, которого OSPF не знает сам — статический в интернет, маршрут из BGP, из другого процесса OSPF, — вводит в OSPF роутер, который называется ASBR (autonomous system boundary router), командой redistribute. Он издаёт External LSA (тип 5), и они расходятся по всем областям, кроме stub. Два вида метрики: E2 (по умолчанию) — стоимость, заданная при вводе, не растёт по пути: «интернет стоит 20 отовсюду»; E1 — к ней прибавляется внутренняя стоимость до ASBR, и ближний ASBR выигрывает. Самый частый внешний маршрут — 0.0.0.0/0, маршрут по умолчанию, который граничный роутер объявляет остальным: default-information originate.
Чтобы остальные роутеры знали, как дойти до ASBR из другой области, ABR издаёт тип 4 — путь до него.
Безопасность и мелочи
- Аутентификация. Без неё любой хост в сегменте, запустив OSPF, станет роутером сети и получит всю карту, а при желании — и трафик. OSPFv2 умеет MD5 и SHA по общему ключу на интерфейс (
ip ospf authentication message-digest), OSPFv3 отдаёт это IPsec AH/ESP (девятнадцатая часть). - Passive-interface. На интерфейсах к хостам (LAN, серверные сегменты) OSPF не должен искать соседей: сеть объявлять надо, Hello слать не надо.
passive-interface defaultплюс явное включение на линках к роутерам — стандарт. - OSPFv3 (RFC 5340) — версия для IPv6: работает по link-local адресам (тринадцатая часть), соседство привязано к линку, а не к подсети, Router ID по-прежнему 32-битный, адресная информация вынесена в отдельные LSA (типы 8 и 9), и через address families один процесс может нести и IPv6, и IPv4.
- Stub-сети и loopback:
/32на loopback-интерфейсе — лучший Router ID и лучший адрес для управления роутером, он доступен, пока жив хоть один линк.
Два роутера на FRR
FRR — набор демонов маршрутизации для Linux, с конфигурацией в синтаксисе, похожем на Cisco. На R1 из примера:
$ sudo vtysh
R1# configure terminal
R1(config)# router ospf
R1(config-router)# ospf router-id 10.0.0.1
R1(config-router)# auto-cost reference-bandwidth 100000
R1(config-router)# passive-interface default
R1(config-router)# no passive-interface eth1
R1(config-router)# no passive-interface eth2
R1(config-router)# network 10.1.12.0/30 area 0
R1(config-router)# network 10.1.13.0/30 area 0
R1(config-router)# network 10.0.0.1/32 area 0
R1(config-router)# exit
R1(config)# interface eth1
R1(config-if)# ip ospf network point-to-point
R1(config-if)# ip ospf authentication message-digest
R1(config-if)# ip ospf message-digest-key 1 md5 s3cret
network … area 0 — «интерфейсы с адресами из этого префикса участвуют в OSPF в области 0». На R2 и R3 — симметрично, плюс на R3 network 192.168.10.0/24 area 0 для LAN, который остаётся passive. Через 40 секунд show ip ospf neighbor покажет Full, show ip ospf database — одинаковые базы, show ip route ospf — маршруты со стоимостями из раздела про SPF. Нужна только пересылка в ядре: net.ipv4.ip_forward = 1.
Диагностика по порядку: соседи есть? (show ip ospf neighbor; нет — смотреть параметры Hello, аутентификацию, passive); соседи Full? (нет — MTU, DR); базы одинаковы? (show ip ospf database, сравнить Seq#); маршрут в таблице? (show ip ospf route покажет, что насчитал SPF, show ip route — что попало в ядро; разница — административная дистанция или фильтр).
Что запомнить
- Динамическая маршрутизация нужна, когда сетей и линков больше, чем можно вести руками, и когда отказы должны лечиться сами. Link-state (OSPF, IS-IS): все знают карту и считают пути сами; distance-vector (RIP): все знают только расстояния по слухам.
- OSPF — протокол 89 поверх IP, multicast
224.0.0.5, пять типов пакетов. Hello каждые 10 с находит соседей; параметры в Hello должны совпадать. Соседство идёт до Full через обмен описаниями баз и догрузку LSA. - LSA описывают линки (1), сегменты (2), итоги других областей (3, 4), внешние маршруты (5, 7); flooding с номерами версий даёт всем одинаковую LSDB.
- Стоимость = эталон / полоса, путь — сумма исходящих стоимостей, SPF по Дейкстре от себя; равные пути — ECMP. Эталонную полосу поднимать на всех роутерах одинаково.
- Area 0 — backbone, ABR передаёт между областями итоги, ASBR вводит внешние маршруты; stub-области получают только default.
- Аутентификация на линках, passive на LAN, DR только на многоточечных сегментах, point-to-point на
/30.
Дальше — Часть 22: BGP: протокол, которым семьдесят тысяч сетей интернета договариваются о маршрутах. Почему он поверх TCP и без автоматического поиска соседей, что такое автономная система, сообщения OPEN и UPDATE, атрибуты пути, чем eBGP отличается от iBGP и зачем iBGP нужен OSPF, как выбирается лучший путь и как им управляют, и как сегодня защищаются от угона префиксов.
Серия «Сети для самых маленьких»
- Модели OSI и TCP/IP — зачем сетевой стек разбит на уровни и как данные обрастают заголовками по пути пакета.
- Ethernet — кадр по байтам, MAC-адреса и как коммутатор решает, в какой порт отправить кадр.
- Wi-Fi — чем радио отличается от кабеля, как клиент подключается к точке доступа и как защищается эфир.
- PPPoE — как провайдер заворачивает сессию абонента в Ethernet и откуда берётся MTU 1492.
- IPv4: адреса, маски и подсети — как читать адрес и маску, делить сеть на подсети и решать, нужен ли шлюз.
- IPv4: заголовок, маршрутизация и NAT — как роутер выбирает маршрут для пакета и как вся квартира выходит в интернет с одного адреса.
- ARP — как по IP-адресу соседа узнать его MAC-адрес и почему соседа так легко подменить.
- ICMP — служебные сообщения IP, как на самом деле работают ping и traceroute и что ломается, когда их режут.
- UDP — восемь байт заголовка, порты и почему отправка без соединения иногда лучше.
- TCP — как из ненадёжного IP получается надёжный поток байтов и почему потеря пакета режет скорость.
- DHCPv4 — как машина без адреса получает адрес, маску, шлюз и DNS четырьмя сообщениями.
- DNS — как имя превращается в адрес: дерево зон, рекурсивные серверы, записи и кеширование.
- IPv6: адреса и заголовок — как записываются 128-битные адреса, какие они бывают и чем заголовок IPv6 отличается от IPv4.
- ICMPv6 и Neighbor Discovery — как в IPv6 без ARP и широковещания находят соседей и роутер.
- SLAAC — как хост собирает себе адрес IPv6 из объявления роутера без всякого сервера.
- DHCPv6 — зачем DHCP, если есть SLAAC, и как провайдер выдаёт домашнему роутеру целый блок сетей.
- VLAN — как один коммутатор и один кабель несут несколько независимых сетей.
- VXLAN — как растянуть сеть Ethernet через роутеры, завернув кадры в UDP.
- IPsec и IKEv2 — как шифруют пакеты на сетевом уровне и договариваются о ключах.
- VPN и прокси — куда уходит каждый пакет при включённом VPN и чем прокси отличается от VPN.
- OSPF (эта статья) — как роутеры одной сети сами строят общую карту и считают по ней кратчайшие пути.
- BGP — как десятки тысяч независимых сетей интернета договариваются о маршрутах.
- TLS и сертификаты — как защищают одно TCP-соединение и откуда браузер знает, что сервер настоящий.
Оставить комментарий могут только зарегистрированные пользователи.
Войдите на сайт или зарегистрируйтесь, чтобы оставить комментарий.