Files
poc-frr-anycast/docs/2026-09-10-bgp-outbound-filter-summary.md
T
ayurishchevandClaude Sonnet 5 804fee4ffa Fix BGP route leak: mandatory outbound prefix-filter on every neighbor
Prod-инцидент: FRR реэкспортировал входящий 10.0.0.0/8 обратно
eBGP-соседям. Причина — ни у одного соседа не было outbound-фильтра
(no bgp ebgp-requires-policy отключал защиту FRR, единственный
route-map RM-PREPEND-OUT permit-all фильтрации не делал).

frr.conf.j2: добавлен ip prefix-list PL-ANYCAST-OUT (permit только
anycast_prefix) и route-map RM-OUT / RM-OUT-PREPEND (фильтр, либо
фильтр+prepend), оба с явным deny в конце. Назначены outbound на
ВСЕХ соседей без исключения — наружу теперь уходит исключительно
анонсируемый anycast-префикс, что бы ни попало в локальную
BGP-таблицу от других соседей.

Уязвимость структурная (в общей роли), поэтому фикс задел и
площадку A — golden-файлы frr/a{1,2,3}/frr.conf синхронизированы
с новым рендером (намеренно, не регресс). no bgp ebgp-requires-policy
сознательно не тронут — его включение требует ещё inbound-policy на
каждого соседа, отдельная задача.

render-check.sh 6/6, render-check-cloud.sh 84/84 (включая nft -c).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bc3HkMiDwooSyLBLoMKNyF
2026-09-10 17:57:51 +03:00

4.3 KiB
Raw Blame History

Summary: outbound-фильтр BGP (устранение утечки 10.0.0.0/8)

Дата: 2026-09-10 План: 2026-09-10-bgp-outbound-filter-plan.md

Инцидент и причина

В PROD (site-cloud) FRR реэкспортировал входящий маршрут 10.0.0.0/8 обратно eBGP-соседям. Причина — структурная: ни у одного соседа (ни в site-a, ни в site-cloud) не было outbound-фильтра. no bgp ebgp-requires-policy отключал защитный механизм FRR (RFC 8212), который иначе не дал бы поднять eBGP-сессию без явной policy; единственный существующий route-map (RM-PREPEND-OUT, только на резервном канале site-cloud) не фильтровал — permit 10 без match пропускал всё. Роутеры многодомны в разные внешние AS без изоляции по префиксам → любой маршрут в локальной BGP-таблице реэкспортировался всем eBGP-соседям.

Что сделано

ansible/roles/frr_anycast/templates/frr.conf.j2:

  • Добавлен ip prefix-list PL-ANYCAST-OUT seq 5 permit <anycast_prefix>.
  • Добавлены route-map RM-OUT (только фильтр) и route-map RM-OUT-PREPEND (фильтр + prepend, рендерится только при наличии соседей с prepend: true) — оба матчат PL-ANYCAST-OUT, оба с явным deny 20 в конце.
  • Каждому соседу в bgp_neighbors теперь назначен outbound route-map: RM-OUT-PREPEND, если prepend: true, иначе RM-OUT — раньше route-map вообще не навешивался на не-prepend соседей (0% фильтрации на основном канале site-cloud и на обоих соседях site-a).
  • no bgp ebgp-requires-policy сознательно оставлен — включение потребовало бы также inbound-policy на каждого соседа (иначе FRR перестанет принимать вообще все входящие маршруты), это отдельная, не запрошенная сейчас задача.

Golden-файлы площадки A обновлены (frr/a{1,2,3}/frr.conf) — добавлен тот же prefix-list/route-map-блок. Это намеренное изменение: та же уязвимость структурно присутствовала и в Docker-лабе (просто менее заметна, т.к. там оба BGP-соседа логически «свои»), фикс применён единообразно везде, где используется роль.

Результаты проверки

  • render-check.sh (площадка A) — 6/6 OK против обновлённых golden-файлов.
  • render-check-cloud.sh — 80/80 проверок: у всех 4 узлов ровно один outbound route-map на каждого из 4 соседей (по правильному типу), nft -c -f подтверждает синтаксическую валидность nftables (без изменений в этой части).
  • --syntax-check — OK для обоих playbook'ов.

Не входит в этот фикс (сознательно)

  • Inbound-фильтрация (RFC1918/bogon-фильтр на приём) — рекомендована как defense-in-depth, но не реализована.
  • Включение bgp ebgp-requires-policy обратно — требует отдельной проработки inbound-policy на каждого соседа.

Изменённые файлы

  • ansible/roles/frr_anycast/templates/frr.conf.j2.
  • frr/a1/frr.conf, frr/a2/frr.conf, frr/a3/frr.conf (golden, Docker-лаба).
  • ansible/tests/render-check-cloud.sh — обновлены проверки под новые имена route-map/prefix-list.
  • README.md — пояснение про обязательный outbound-фильтр.
  • docs/2026-09-10-bgp-outbound-filter-plan.md, docs/2026-09-10-bgp-outbound-filter-summary.md.