NetLab Academy

Сетевые лаборатории в браузере

Войти Начать бесплатно

Теория: BGP: политики и атрибуты

Как заставить трафик идти нужным путём: LOCAL_PREF для исходящего, prepend и MED для входящего, route-map и prefix-list как механизм, communities как договорённость с провайдером и iBGP со своими особенностями. Прочитайте материал, а затем пройдите тест — следующий пункт курса откроется после верных ответов.

Почему BGP выбирает не самый быстрый путь

В OSPF всё честно: у каждого линка есть cost, роутер складывает их и берёт минимум. Кратчайший путь — он и есть лучший.

В BGP лучшего пути в этом смысле нет вовсе. BGP не знает ни задержки, ни ширины канала, ни загрузки: AS_PATH считает границы AS, а не километры и не миллисекунды. Путь через одного крупного оператора формально короче, чем через двух мелких, даже если реально он идёт вокруг половины планеты.

И это не недостаток. BGP — протокол не про физику, а про договорённости: через какого провайдера мы платим меньше, кого держим как резерв, кому вообще запрещено ходить через нас транзитом. Всё это выражается атрибутами маршрута, а расставляет их администратор. Отсюда и слово «политика»: набор правил, которые превращают договор с провайдером в конкретные атрибуты на конкретных префиксах.

Главная асимметрия: исходящий решаешь ты, входящий — просишь

Прежде чем крутить любой атрибут, надо понять, на что он вообще влияет. Направления два, и рычаги у них разные.

Исходящий трафик — куда пакеты уходят от нас. Решение принимаем мы сами, на своих роутерах, из тех маршрутов, что нам анонсировали. Здесь наша власть полная.
Входящий трафик — как к нам заходят снаружи. Решение принимает чужая AS на своём оборудовании. Мы можем только сделать один вход менее привлекательным, чем другой, и надеяться, что сосед не переопределит это своей политикой.

Отсюда практическое правило, которое экономит часы отладки: LOCAL_PREF управляет исходящим трафиком, AS-PATH prepend и MED — входящим. Классическая ошибка новичка — накрутить prepend, чтобы разгрузить свой аплинк на отдачу, и удивляться, что ничего не изменилось: prepend влияет на то, как ходят к нам, а не от нас.

LOCAL_PREF — рычаг для исходящего трафика

LOCAL_PREF отвечает на вопрос «какой из наших выходов наружу мы предпочитаем». Чем больше значение, тем желаннее маршрут; значение по умолчанию — 100.

Важное свойство: LOCAL_PREF не передаётся через eBGP. Он живёт только внутри нашей AS, зато расходится по всем своим роутерам через iBGP. Именно поэтому им удобно объявлять решение уровня компании: «весь исходящий идёт через дешёвого провайдера, дорогой — только резерв». Ставим на маршруты от дешёвого 200, от резервного оставляем 100 — и все внутренние роутеры одинаково выбирают первого. Упал он — маршрутов с 200 больше нет, и трафик молча уходит на резервного.

LOCAL_PREF — первый содержательный шаг в выборе лучшего маршрута, до сравнения длины AS_PATH. Поэтому он перебивает любую длину пути: маршрут через восемь чужих AS с LOCAL_PREF 200 победит прямого соседа со 100. Это одновременно и сила, и способ выстрелить себе в ногу.

AS-PATH prepend — просьба заходить с другой стороны

Чтобы сделать один из наших входов менее привлекательным снаружи, к анонсу приписывают свой же номер AS несколько раз. Путь становится формально длиннее, и чужие роутеры, дойдя до шага сравнения AS_PATH, выберут другой вход.

Было: 65001. Стало после двойного prepend: 65001 65001 65001. Сеть та же, дорога до неё «выглядит» на два перехода длиннее.

Дальше начинаются оговорки, о которых стоит знать заранее:
• Prepend работает только до тех пор, пока чужая политика не вмешалась. Соседняя AS сравнивает LOCAL_PREF раньше AS_PATH — если у неё стоит правило «через этого пира ходим всегда», никакой prepend его не перебьёт.
• Чем дальше от нас, тем слабее эффект: удлинение на два перехода заметно ближайшим соседям и почти не видно на другом конце интернета.
• Приписывать десяток номеров бессмысленно: два-три — обычная практика, дальше растёт только риск попасть под чужие фильтры длины пути.

Отсюда честная формулировка: prepend — это просьба, а не команда. Гарантий он не даёт, но в большинстве случаев работает.

MED — подсказка соседу, в какую из наших дверей заходить

MED (Multi-Exit Discriminator) нужен, когда с одной и той же соседней AS у нас несколько стыков. Он говорит: «заходи вот через этот, он у нас основной». Меньше значение — привлекательнее вход, то есть логика обратная LOCAL_PREF.

У MED две особенности, из-за которых он работает не так часто, как от него ждут:
• По умолчанию MED сравнивается только между маршрутами от одной и той же соседней AS. Сравнивать MED от двух разных провайдеров бессмысленно — они назначают его по своим шкалам, и режим bgp always-compare-med включают, понимая зачем.
• В цепочке критериев MED стоит после AS_PATH. Если пути разной длины, до сравнения MED дело просто не дойдёт.

Практический вывод: MED — инструмент для двух стыков с одним партнёром. Для выбора между разными провайдерами он не годится, там работает prepend.

Порядок выбора лучшего маршрута — полностью

Когда до одной сети есть несколько путей, BGP идёт по списку критериев сверху вниз и останавливается на первом, который дал победителя. Порядок важно знать наизусть: он объясняет, почему настройка «не сработала».

1. Больше WEIGHT — лучше. Живёт только на одном роутере, соседям не передаётся вовсе.
2. Больше LOCAL_PREF — лучше. Расходится по своей AS.
3. Свой собственный маршрут (объявленный через network или redistribute) предпочитается полученному.
4. Короче AS_PATH — лучше.
5. Ниже ORIGIN: i лучше e, e лучше ?.
6. Меньше MED — лучше (по умолчанию только в рамках одной соседней AS).
7. eBGP предпочтительнее iBGP.
8. Меньше метрика IGP до NEXT_HOP — то есть до выхода ближе по своей же внутренней маршрутизации.
9. Дальше идут правила устойчивости: предпочесть более старый eBGP-маршрут, затем меньший router-id, затем меньший адрес соседа.

Первые два шага — это и есть рычаги администратора, остальное протокол решает сам. И обратите внимание на девятый пункт: последние критерии существуют не ради оптимальности, а чтобы результат был одинаковым при каждом пересчёте. Без них сеть колебалась бы между равнозначными путями.
Два пути до одной сети: BGP идёт по списку сверху вниз, пока кто-то не выиграет
критерии по порядку
Список проходится до первого различия — дальше сравнивать нечего. Поэтому LOCAL_PREF перебивает любую длину пути: он стоит вторым, а AS_PATH — четвёртым. Победитель считается здесь той же логикой, что и на роутере, а не выбран заранее.

Route-map — механизм, которым политика вообще делается

Все атрибуты расставляются одним инструментом — route-map. Устроен он как список пронумерованных правил, каждое со своим действием permit или deny:

route-map TO-ISP1 permit 10
 match ip address prefix-list MY-NETS
 set as-path prepend 65001 65001
route-map TO-ISP1 permit 20
Читается сверху вниз до первого совпадения. Правило без match подходит всем — это способ сказать «остальное пропустить как есть».

И здесь спрятана ловушка, на которой обжигаются все: в конце route-map стоит неявный deny. Забыли последнее пустое permit 20 — и всё, что не совпало с первым правилом, будет молча отброшено. Сессия при этом поднята, соседство в порядке, ошибок в логе нет, а половина префиксов исчезла.

Применяется карта к конкретному соседу и в конкретном направлении: in — к тому, что мы принимаем, out — к тому, что отдаём. Одну и ту же карту на обе стороны вешать нельзя: prepend имеет смысл только на out, LOCAL_PREF — только на in.

Фильтрация префиксов: что принимать и что отдавать

Политика — это не только атрибуты, но и вопрос «пускать ли этот маршрут вообще». Работают prefix-list: список сетей с точным указанием, какие длины маски разрешены.

ip prefix-list MY-NETS seq 5 permit 192.168.14.0/24
ip prefix-list MY-NETS seq 10 deny any
Два правила, которые стоит завести всегда:
Наружу отдаём только свои сети. Если по недосмотру отдать провайдеру всё, что мы знаем, мы объявим себя транзитом для чужого трафика — и он придёт. Так и происходят аварии, когда небольшая сеть внезапно принимает на себя поток, который ей не по силам.
Внутрь не принимаем что попало. Свои собственные префиксы, пришедшие снаружи, приватные диапазоны, слишком мелкие куски — всё это отбрасывают на входе.

Модификатор le задаёт разрешённую длину маски: permit 10.0.0.0/8 le 24 пропустит любую подсеть внутри /8 с маской не длиннее /24. Без него правило совпадает только с точной сетью и точной маской — частая причина «фильтр стоит, а не фильтрует».

Communities — метки, по которым договариваются

Community — это просто число вида 65001:100, приклеенное к маршруту. Само по себе оно не значит ничего: смысл ему придаёт договорённость двух сторон.

Работает это так. Провайдер публикует таблицу: «пометь маршрут 64500:80 — и мы понизим ему у себя LOCAL_PREF; пометь 64500:90 — сделаем один prepend». Клиенту не нужно просить инженера провайдера что-то настроить — он вешает метку сам, своей route-map, и политика применяется на чужой стороне автоматически.

Есть и несколько общепринятых значений, которые понимают все:
no-export — сосед может использовать маршрут у себя, но не отдаст его дальше в другие AS.
no-advertise — не передавать вообще никому.

Мелочь, которая стоит нервов: здесь community соседям отправляются по умолчанию, а в Cisco IOS стандартные — нет, там нужен явный neighbor X send-community. Метка, поставленная и не отправленная, выглядит как «политика не работает».

iBGP: почему внутри AS всё сложнее

Правило защиты от петель внутри AS звучит просто: маршрут, полученный по iBGP, не передаётся другому iBGP-соседу. AS_PATH внутри своей AS не растёт, значит по нему петлю не поймать — приходится запрещать пересылку целиком.

Следствие: чтобы все внутренние роутеры узнали маршрут, каждый должен слышать его напрямую. Это full mesh — сессия между каждой парой. Для четырёх роутеров это шесть сессий, для десяти — сорок пять. Считается по формуле n(n−1)/2, и растёт неприлично быстро.

Отсюда Route Reflector: один роутер получает право нарушать правило и пересылать iBGP-маршруты своим клиентам. Тогда каждому клиенту достаточно одной сессии — с рефлектором. Настраивается это на самом рефлекторе одной строкой neighbor X route-reflector-client, клиенты о своей роли не знают вовсе.

Второй сюрприз iBGP — NEXT_HOP. При eBGP-анонсе роутер подставляет туда свой адрес, а при передаче маршрута по iBGP оставляет исходный, то есть адрес чужого пограничного роутера. Внутренние роутеры такой адрес обычно не знают, маршрут получается недостижимым и в таблицу не попадает. Лечится командой neighbor X next-hop-self на пограничном роутере.

Что здесь ломается

Route-map без завершающего permit. Самая частая авария. Половина префиксов исчезает молча, сессия при этом в состоянии Established. Проверяется сравнением advertised-routes с тем, что мы ожидали отдать.

Политику применили, а маршруты не пересчитались. Route-map сама по себе к уже полученным маршрутам не применяется. Нужен мягкий сброс clear ip bgp X soft in — сессия при этом не рвётся, соседа просят прислать анонсы заново.

Prepend не в ту сторону. Повешенный на in он меняет наш собственный выбор вместо чужого, и обычно не меняет ничего полезного.

LOCAL_PREF, который никто не увидел. Поставлен на eBGP-выходе out — соседу он не уйдёт, атрибут через границу AS не передаётся.

prefix-list без le. Совпадает только с точной маской, все подсети проходят мимо фильтра.

Забытый next-hop-self. Маршруты в show ip bgp есть, помечены как недоступные, в таблицу маршрутизации не попадают ни один.

Отдали наружу лишнее. Нет фильтра на out — и мы объявили себя транзитом. Ошибка тихая ровно до момента, когда чужой трафик заполнит канал.

Как проверять

show bgp ipv4 unicast summary — состояние сессий и число принятых префиксов от каждого соседа. Резко изменившееся число — первый признак, что фильтр сработал не так.

show ip bgp 192.168.14.0/24 — всё про конкретный маршрут: все известные пути, атрибуты каждого и пометка best у победителя. Главная команда при разборе «почему выбрался не тот путь».

show ip bgp neighbors X advertised-routes — что мы реально отдаём этому соседу, уже после применения out-политики.

show ip bgp neighbors X received-routes — что сосед прислал до нашей in-политики. Требует включённого neighbor X soft-reconfiguration inbound, иначе исходные анонсы просто не хранятся.

show route-map TO-ISP1 — какие правила есть и сколько раз сработало каждое. Счётчик 0 напротив правила означает, что match не совпадает ни с чем.

show ip prefix-list MY-NETS — содержимое списка и счётчики совпадений по строкам.

Команды — шпаргалка

# фильтр: только свои сети
ip prefix-list MY-NETS seq 5 permit 192.168.14.0/24
                                       # seq — номер строки, правила смотрятся
                                       #   по возрастанию, первое совпадение решает
ip prefix-list ISP-IN seq 5 permit 0.0.0.0/0 le 24
                                       # le 24 — «длина маски до 24 включительно»:
                                       #   пустит /8…/24 и отсечёт мелкую нарезку.
                                       #   Есть и ge — «не короче чем»

# исходящий трафик: предпочитаем дешёвого провайдера
route-map FROM-ISP1 permit 10          # имя, действие (permit/deny) и номер
                                       #   строки: чем меньше, тем раньше проверяется
 set local-preference 200              # LOCAL_PREF: чем БОЛЬШЕ, тем охотнее
                                       #   наша AS выбирает этот путь наружу

# входящий трафик: просим заходить не через нас
route-map TO-ISP2 permit 10
 match ip address prefix-list MY-NETS  # условие: к каким префиксам применять
 set as-path prepend 65001 65001       # приписать свой номер AS лишний раз:
                                       #   путь становится длиннее и менее заманчив.
                                       #   Сколько раз повторили — столько и добавится
route-map TO-ISP2 permit 20            # пустая строка в конце: иначе неявный
                                       #   deny съест всё, что не совпало выше

# метки для чужой политики
route-map TO-ISP1 permit 10
 set community 64500:90 additive       # метка вида «номер AS : число»;
                                       #   additive — добавить к уже имеющимся,
                                       #   без него старые метки затрутся
 set community no-export               # зарезервированное значение: сосед
                                       #   не понесёт маршрут дальше своей AS

# применение к соседу — обязательно с направлением
router bgp 65001
 neighbor 10.0.12.2 route-map FROM-ISP1 in    # in — к тому, что ПРИШЛО от соседа
 neighbor 10.0.13.2 route-map TO-ISP2 out     # out — к тому, что мы ему ОТДАЁМ
 neighbor 10.0.12.2 prefix-list MY-NETS out   # простой фильтр без route-map
 neighbor 10.0.12.2 soft-reconfiguration inbound
                                       # хранить полученное «как есть», чтобы
                                       #   переприменять политику без разрыва сессии

# iBGP
 neighbor 10.0.0.2 next-hop-self       # подставлять свой адрес как NEXT_HOP
 neighbor 10.0.0.3 route-reflector-client
                                       # считать соседа клиентом: ему можно
                                       #   пересылать чужие iBGP-маршруты

# применить политику без разрыва сессии
clear ip bgp 10.0.12.2 soft in         # soft — не рвать сессию; in — заново
                                       #   прогнать через политику полученное
clear ip bgp 10.0.13.2 soft out        # out — переотправить свои анонсы

# проверка
show bgp ipv4 unicast summary          # состояние сессий одной таблицей
show ip bgp 192.168.14.0/24            # всё, что известно про один префикс
show ip bgp neighbors 10.0.12.2 advertised-routes   # что мы ОТДАЛИ соседу
show ip bgp neighbors 10.0.12.2 received-routes     # что ПОЛУЧИЛИ от него
                                       #   (нужен soft-reconfiguration inbound)
show route-map TO-ISP2                 # текст политики и счётчики совпадений
show ip prefix-list MY-NETS            # строки фильтра и счётчики совпадений
Контрольные вопросы

Дальше — лабораторная работа «BGP: заставь трафик идти нужным путём»

Для неё нужен аккаунт: стенд поднимается персонально под вас — свои роутеры, свои конфиги, никто в них не мешает. Регистрация — почта и пароль.

Теория прочитана. Дальше — руками.

Личный стенд из настоящих роутеров разворачивается за секунды. Платформа проверяет не ответы на тесты, а состояние вашей сети: поднялись ли соседства, сошлись ли маршруты, ходит ли ping. Рядом — AI-наставник, который видит ваши конфиги и ведёт к решению, не выдавая готовое.

Начать бесплатно → бета открыта, доступ бесплатный