Files
poc-frr-anycast/docs/2026-09-10-bgp-outbound-filter-summary.md
T

37 lines
4.3 KiB
Markdown
Raw Normal View History

# Summary: outbound-фильтр BGP (устранение утечки 10.0.0.0/8)
**Дата:** 2026-09-10
**План:** [2026-09-10-bgp-outbound-filter-plan.md](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`.