Сети для самых маленьких. Часть 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          недостающее
  1. Init — получил Hello от соседа. 2-Way — сосед включил меня в свой список: связь в обе стороны.
  2. ExStart — договориться, кто ведущий (по Router ID), и с какого номера нумеровать DBD.
  3. Exchange — обменяться описаниями баз: не самими LSA, а их заголовками с номерами версий. Каждый сравнивает со своей базой.
  4. Loading — запросить (LSR) те LSA, которых нет или которые у соседа новее, получить их (LSU), подтвердить (LSAck).
  5. 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, как выбирается лучший путь и как им управляют, и как сегодня защищаются от угона префиксов.


Серия «Сети для самых маленьких»

  1. Модели OSI и TCP/IP — зачем сетевой стек разбит на уровни и как данные обрастают заголовками по пути пакета.
  2. Ethernet — кадр по байтам, MAC-адреса и как коммутатор решает, в какой порт отправить кадр.
  3. Wi-Fi — чем радио отличается от кабеля, как клиент подключается к точке доступа и как защищается эфир.
  4. PPPoE — как провайдер заворачивает сессию абонента в Ethernet и откуда берётся MTU 1492.
  5. IPv4: адреса, маски и подсети — как читать адрес и маску, делить сеть на подсети и решать, нужен ли шлюз.
  6. IPv4: заголовок, маршрутизация и NAT — как роутер выбирает маршрут для пакета и как вся квартира выходит в интернет с одного адреса.
  7. ARP — как по IP-адресу соседа узнать его MAC-адрес и почему соседа так легко подменить.
  8. ICMP — служебные сообщения IP, как на самом деле работают ping и traceroute и что ломается, когда их режут.
  9. UDP — восемь байт заголовка, порты и почему отправка без соединения иногда лучше.
  10. TCP — как из ненадёжного IP получается надёжный поток байтов и почему потеря пакета режет скорость.
  11. DHCPv4 — как машина без адреса получает адрес, маску, шлюз и DNS четырьмя сообщениями.
  12. DNS — как имя превращается в адрес: дерево зон, рекурсивные серверы, записи и кеширование.
  13. IPv6: адреса и заголовок — как записываются 128-битные адреса, какие они бывают и чем заголовок IPv6 отличается от IPv4.
  14. ICMPv6 и Neighbor Discovery — как в IPv6 без ARP и широковещания находят соседей и роутер.
  15. SLAAC — как хост собирает себе адрес IPv6 из объявления роутера без всякого сервера.
  16. DHCPv6 — зачем DHCP, если есть SLAAC, и как провайдер выдаёт домашнему роутеру целый блок сетей.
  17. VLAN — как один коммутатор и один кабель несут несколько независимых сетей.
  18. VXLAN — как растянуть сеть Ethernet через роутеры, завернув кадры в UDP.
  19. IPsec и IKEv2 — как шифруют пакеты на сетевом уровне и договариваются о ключах.
  20. VPN и прокси — куда уходит каждый пакет при включённом VPN и чем прокси отличается от VPN.
  21. OSPF (эта статья) — как роутеры одной сети сами строят общую карту и считают по ней кратчайшие пути.
  22. BGP — как десятки тысяч независимых сетей интернета договариваются о маршрутах.
  23. TLS и сертификаты — как защищают одно TCP-соединение и откуда браузер знает, что сервер настоящий.

Оставить комментарий могут только зарегистрированные пользователи.

Войдите на сайт или зарегистрируйтесь, чтобы оставить комментарий.