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
This commit is contained in:
1 parent
1e287ee81c
commit
804fee4ffa
8 files changed
+113
-9
No files matched your search
@@ -4,10 +4,20 @@ hostname {{ inventory_hostname }}
|
||||
log stdout informational
|
||||
no ipv6 forwarding
|
||||
!
|
||||
ip prefix-list PL-ANYCAST-OUT seq 5 permit {{ anycast_prefix }}
|
||||
!
|
||||
route-map RM-OUT permit 10
|
||||
match ip address prefix-list PL-ANYCAST-OUT
|
||||
!
|
||||
route-map RM-OUT deny 20
|
||||
!
|
||||
{% if bgp_neighbors | selectattr('prepend') | list | length > 0 %}
|
||||
route-map RM-PREPEND-OUT permit 10
|
||||
route-map RM-OUT-PREPEND permit 10
|
||||
match ip address prefix-list PL-ANYCAST-OUT
|
||||
set as-path prepend {{ ((local_asn ~ ' ') * (as_path_prepend_count | default(0) | int)) | trim }}
|
||||
!
|
||||
route-map RM-OUT-PREPEND deny 20
|
||||
!
|
||||
{% endif %}
|
||||
router bgp {{ local_asn }}
|
||||
bgp router-id {{ router_id }}
|
||||
@@ -21,8 +31,8 @@ router bgp {{ local_asn }}
|
||||
{% for n in bgp_neighbors %}
|
||||
neighbor {{ n.ip }} activate
|
||||
{% endfor %}
|
||||
{% for n in bgp_neighbors if n.prepend %}
|
||||
neighbor {{ n.ip }} route-map RM-PREPEND-OUT out
|
||||
{% for n in bgp_neighbors %}
|
||||
neighbor {{ n.ip }} route-map {{ 'RM-OUT-PREPEND' if n.prepend else 'RM-OUT' }} out
|
||||
{% endfor %}
|
||||
exit-address-family
|
||||
!
|
||||
|
||||
@@ -43,12 +43,17 @@ for n in vr01 vr02 vr03 vr04; do
|
||||
check "$n neighbor main2" "$f" " neighbor $MAIN2_NEIGHBOR_IP remote-as 65104" 1
|
||||
check "$n neighbor backup1" "$f" " neighbor $BACKUP1_NEIGHBOR_IP remote-as 65103" 1
|
||||
check "$n neighbor backup2" "$f" " neighbor $BACKUP2_NEIGHBOR_IP remote-as 65103" 1
|
||||
check "$n route-map defined" "$f" "route-map RM-PREPEND-OUT permit 10" 1
|
||||
check "$n prefix-list anycast only" "$f" "ip prefix-list PL-ANYCAST-OUT seq 5 permit 172.31.255.10/32" 1
|
||||
check "$n RM-OUT filters to anycast" "$f" "match ip address prefix-list PL-ANYCAST-OUT" 2 # RM-OUT + RM-OUT-PREPEND
|
||||
check "$n RM-OUT implicit deny" "$f" "route-map RM-OUT deny 20" 1
|
||||
check "$n RM-OUT-PREPEND defined" "$f" "route-map RM-OUT-PREPEND permit 10" 1
|
||||
check "$n prepend value" "$f" "set as-path prepend 65200 65200 65200" 1
|
||||
check "$n route-map on backup1 only" "$f" "neighbor $BACKUP1_NEIGHBOR_IP route-map RM-PREPEND-OUT out" 1
|
||||
check "$n route-map on backup2 only" "$f" "neighbor $BACKUP2_NEIGHBOR_IP route-map RM-PREPEND-OUT out" 1
|
||||
check "$n NO route-map on main1" "$f" "neighbor $MAIN1_NEIGHBOR_IP route-map RM-PREPEND-OUT out" 0
|
||||
check "$n NO route-map on main2" "$f" "neighbor $MAIN2_NEIGHBOR_IP route-map RM-PREPEND-OUT out" 0
|
||||
check "$n filter+prepend on backup1" "$f" "neighbor $BACKUP1_NEIGHBOR_IP route-map RM-OUT-PREPEND out" 1
|
||||
check "$n filter+prepend on backup2" "$f" "neighbor $BACKUP2_NEIGHBOR_IP route-map RM-OUT-PREPEND out" 1
|
||||
check "$n filter-only on main1" "$f" "neighbor $MAIN1_NEIGHBOR_IP route-map RM-OUT out" 1
|
||||
check "$n filter-only on main2" "$f" "neighbor $MAIN2_NEIGHBOR_IP route-map RM-OUT out" 1
|
||||
check "$n NO prepend route-map on main1" "$f" "neighbor $MAIN1_NEIGHBOR_IP route-map RM-OUT-PREPEND out" 0
|
||||
check "$n NO prepend route-map on main2" "$f" "neighbor $MAIN2_NEIGHBOR_IP route-map RM-OUT-PREPEND out" 0
|
||||
|
||||
nft="$OUT_DIR/$n/nftables.conf"
|
||||
check "$n nftables masquerade" "$nft" "masquerade" 1
|
||||
|
||||
Reference in new issue
Block a user