BGP Route Filtering: Prefix Lists, AS-Path фильтры, отклонение богонов и GTSM
Практический справочник по усилению BGP-сессий на Linux с помощью многоуровневых фильтров. Рассматриваются prefix-list, отклонение богонов, AS-path фильтрация, лимиты max-prefix и GTSM в синтаксисе BIRD2 и FRR с шагами проверки.
RPKI (Resource Public Key Infrastructure, инфраструктура открытых ключей для интернет-ресурсов) проверяет, что AS авторизована на анонс определённого префикса. Но он не защищает от route leak (утечек маршрутов), инъекции богонов, взрыва таблицы от некорректно настроенного пира или подделанных BGP-пакетов от несмежных хостов. Эта статья описывает фильтры, которые закрывают всё то, что RPKI не охватывает.
Каждый фильтр показан в синтаксисе BIRD2 и FRR, с примерами для IPv4 и IPv6. В каждом разделе объясняется, от чего защищает фильтр, приводится конфигурация и описывается, как убедиться, что всё работает.
Если вы ещё не настроили RPKI origin validation, сделайте это сначала. См. RPKI ROA Setup for BGP.
Для базовой настройки BGP-сессии см. BIRD2 BGP Configuration on Linux (BIRD2) или FRR BGP Configuration on Linux (FRR). Предполагается, что рабочая BGP-сессия уже есть и вам нужно её усилить.
Зачем BGP нужна фильтрация маршрутов помимо RPKI?
BGP route filtering (фильтрация маршрутов) — это практика принятия или отклонения BGP-анонсов на основе префикса, AS-path или атрибутов origin. Она предотвращает route leak, перехваты префиксов, инъекцию богонов и взрыв таблицы маршрутизации. RPKI покрывает только origin validation. Без дополнительных фильтров ваш роутер уязвим ко всем остальным категориям BGP-инцидентов.
Что блокирует каждый уровень:
| Тип фильтра | Заблокированная угроза | Что происходит без него |
|---|---|---|
| Отклонение bogon-префиксов | Приватное/зарезервированное пространство в DFZ | Роутер пытается форвардить трафик в RFC 1918 пространство. Black hole. |
| Отклонение слишком мелких префиксов | More-specific hijacks (/25+, /49+) | Атакующий анонсирует /32, перекрывающий часть /24, который вы принимаете. Его маршрут побеждает по longest match. |
| Фильтрация bogon-ASN | Приватные/зарезервированные ASN в путях | Маршруты с AS 65535 или AS 4200000000 попадают в вашу таблицу. Вы форвардите трафик по мусорным путям. |
| Ограничение длины AS-path | Path inflation атаки, разбухание таблицы | Пир присылает маршруты с 50+ AS-хопами. Память забивается бесполезными записями. |
| Max-prefix limit | Route leak, перегрузка сессии | Пир случайно льёт полную таблицу (1M+ префиксов) в сессию. Роутер выходит из памяти. |
| GTSM (TTL security) | Подделанные BGP-пакеты от удалённых хостов | Атакующий за несколько хопов инжектирует BGP OPEN или UPDATE пакеты в сессию. |
| RPKI origin validation | Origin hijacks | Кто-то анонсирует ваш префикс из своей AS. Уже описано в RPKI ROA Setup for BGP. |
Реальные инциденты показывают, почему важен каждый уровень. В 2008 году Pakistan Telecom анонсировал more-specific маршруты для префиксов YouTube, чтобы реализовать внутреннюю блокировку. Эти маршруты утекли к международным transit-провайдерам и на несколько часов создали black hole для YouTube по всему миру. Фильтр богонов или small-prefix на стороне транзитных провайдеров дропнул бы эти анонсы. В июне 2019 года небольшой ISP в Пенсильвании (AS396531) случайно слил маршруты Cloudflare, Amazon и Linode в Verizon, которые распространились глобально. Max-prefix limit разорвал бы сессию до того, как утечка распространилась.
Как фильтровать bogon-префиксы в BIRD2 и FRR?
Bogon-префиксы (богоны) — это диапазоны адресов, которые никогда не должны появляться в глобальной таблице маршрутизации. Они включают приватное пространство RFC 1918, link-local адреса, документационные диапазоны и зарезервированные блоки. Принятие их означает, что роутер будет пытаться форвардить трафик на адреса без легитимного глобального назначения, создавая black hole.
IPv4 bogon-префиксы
| Префикс | Ссылка | Назначение |
|---|---|---|
| 0.0.0.0/8 | RFC 1122 | "This" network |
| 10.0.0.0/8 | RFC 1918 | Приватное пространство |
| 100.64.0.0/10 | RFC 6598 | Carrier-grade NAT |
| 127.0.0.0/8 | RFC 1122 | Loopback |
| 169.254.0.0/16 | RFC 3927 | Link-local |
| 172.16.0.0/12 | RFC 1918 | Приватное пространство |
| 192.0.2.0/24 | RFC 5737 | TEST-NET-1 |
| 192.88.99.0/24 | RFC 7526 | Deprecated 6to4 relay |
| 192.168.0.0/16 | RFC 1918 | Приватное пространство |
| 198.18.0.0/15 | RFC 2544 | Benchmarking |
| 198.51.100.0/24 | RFC 5737 | TEST-NET-2 |
| 203.0.113.0/24 | RFC 5737 | TEST-NET-3 |
| 224.0.0.0/4 | RFC 5771 | Multicast |
| 240.0.0.0/4 | RFC 1112 | Зарезервировано для будущего использования |
IPv6 bogon-префиксы
| Префикс | Ссылка | Назначение |
|---|---|---|
| ::/8 | Various | IPv4-compatible, loopback, mapped |
| 100::/64 | RFC 6666 | Discard-only |
| 2001:2::/48 | RFC 5180 | BMWG benchmarking |
| 2001:10::/28 | RFC 4843 | ORCHID |
| 2001:db8::/32 | RFC 3849 | Документация |
| 3fff::/20 | RFC 9637 | Документация |
| 2002::/16 | RFC 7526 | Deprecated 6to4 |
| 3ffe::/16 | RFC 3701 | Former 6bone |
| 5f00::/16 | RFC 9602 | SRv6 SIDs |
| fc00::/7 | RFC 4193 | Unique local unicast |
| fe80::/10 | RFC 4291 | Link-local unicast |
| fec0::/10 | RFC 3879 | Deprecated site-local |
| ff00::/8 | RFC 4291 | Multicast |
Эти списки меняются, когда IANA выделяет новые блоки или устаревают старые. Team Cymru bogon reference предоставляет BGP-фид fullbogons (нераспределённое + зарезервированное пространство), который обновляется автоматически. Для статических списков периодически сверяйтесь с NLNOG BGP Filter Guide.
BIRD2 bogon-фильтр
# /etc/bird/bogons.conf - include this from your main bird.conf
define BOGON_PREFIXES_V4 = [
0.0.0.0/8+,
10.0.0.0/8+,
100.64.0.0/10+,
127.0.0.0/8+,
169.254.0.0/16+,
172.16.0.0/12+,
192.0.2.0/24+,
192.88.99.0/24+,
192.168.0.0/16+,
198.18.0.0/15+,
198.51.100.0/24+,
203.0.113.0/24+,
224.0.0.0/4+,
240.0.0.0/4+
];
define BOGON_PREFIXES_V6 = [
::/8+,
0100::/64+,
2001:2::/48+,
2001:10::/28+,
2001:db8::/32+,
3fff::/20+,
2002::/16+,
3ffe::/16+,
5f00::/16+,
fc00::/7+,
fe80::/10+,
fec0::/10+,
ff00::/8+
];
function reject_bogon_prefixes_v4() {
if (net ~ BOGON_PREFIXES_V4) then {
print "REJECTED bogon prefix: ", net, " path: ", bgp_path;
reject;
}
}
function reject_bogon_prefixes_v6() {
if (net ~ BOGON_PREFIXES_V6) then {
print "REJECTED bogon prefix: ", net, " path: ", bgp_path;
reject;
}
}
Символ + после каждого префикса означает «этот префикс и все more-specific». 10.0.0.0/8+ матчит 10.0.0.0/8, 10.0.0.0/9, 10.1.0.0/16 и так далее. Это ловит атакующего, анонсирующего /24 внутри RFC 1918 пространства.
Вызовите эти функции в вашем import-фильтре:
filter import_from_upstream_v4 {
reject_bogon_prefixes_v4();
# ... other filters ...
accept;
}
protocol bgp upstream_v4 {
local as 64500;
neighbor 198.51.100.1 as 64501;
ipv4 {
import filter import_from_upstream_v4;
export none;
};
}
FRR bogon-фильтр
! IPv4 bogon prefix-list
ip prefix-list BOGONS_v4 seq 10 deny 0.0.0.0/8 le 32
ip prefix-list BOGONS_v4 seq 20 deny 10.0.0.0/8 le 32
ip prefix-list BOGONS_v4 seq 30 deny 100.64.0.0/10 le 32
ip prefix-list BOGONS_v4 seq 40 deny 127.0.0.0/8 le 32
ip prefix-list BOGONS_v4 seq 50 deny 169.254.0.0/16 le 32
ip prefix-list BOGONS_v4 seq 60 deny 172.16.0.0/12 le 32
ip prefix-list BOGONS_v4 seq 70 deny 192.0.2.0/24 le 32
ip prefix-list BOGONS_v4 seq 80 deny 192.88.99.0/24 le 32
ip prefix-list BOGONS_v4 seq 90 deny 192.168.0.0/16 le 32
ip prefix-list BOGONS_v4 seq 100 deny 198.18.0.0/15 le 32
ip prefix-list BOGONS_v4 seq 110 deny 198.51.100.0/24 le 32
ip prefix-list BOGONS_v4 seq 120 deny 203.0.113.0/24 le 32
ip prefix-list BOGONS_v4 seq 130 deny 224.0.0.0/4 le 32
ip prefix-list BOGONS_v4 seq 140 deny 240.0.0.0/4 le 32
ip prefix-list BOGONS_v4 seq 999 permit 0.0.0.0/0 le 32
! IPv6 bogon prefix-list
ipv6 prefix-list BOGONS_v6 seq 10 deny ::/8 le 128
ipv6 prefix-list BOGONS_v6 seq 20 deny 100::/64 le 128
ipv6 prefix-list BOGONS_v6 seq 30 deny 2001:2::/48 le 128
ipv6 prefix-list BOGONS_v6 seq 40 deny 2001:10::/28 le 128
ipv6 prefix-list BOGONS_v6 seq 50 deny 2001:db8::/32 le 128
ipv6 prefix-list BOGONS_v6 seq 60 deny 3fff::/20 le 128
ipv6 prefix-list BOGONS_v6 seq 70 deny 2002::/16 le 128
ipv6 prefix-list BOGONS_v6 seq 80 deny 3ffe::/16 le 128
ipv6 prefix-list BOGONS_v6 seq 90 deny 5f00::/16 le 128
ipv6 prefix-list BOGONS_v6 seq 100 deny fc00::/7 le 128
ipv6 prefix-list BOGONS_v6 seq 110 deny fe80::/10 le 128
ipv6 prefix-list BOGONS_v6 seq 120 deny fec0::/10 le 128
ipv6 prefix-list BOGONS_v6 seq 130 deny ff00::/8 le 128
ipv6 prefix-list BOGONS_v6 seq 999 permit ::/0 le 128
Операторы le 32 (IPv4) и le 128 (IPv6) матчат префикс и все more-specific, как и оператор + в BIRD2. Финальная строка permit в seq 999 пропускает всё, что не было задено выше.
Примените prefix-list к своему neighbour:
router bgp 64500
neighbor 198.51.100.1 remote-as 64501
address-family ipv4 unicast
neighbor 198.51.100.1 prefix-list BOGONS_v4 in
address-family ipv6 unicast
neighbor 2001:db8::1 prefix-list BOGONS_v6 in
Внимание: запись 2001:db8::/32 есть в списке богонов. Не используйте документационные адреса в продакшне. Замените адреса neighbour выше на реальные IP вашего пира.
Отклонение слишком мелких префиксов
Маршруты мельче /24 (IPv4) или /48 (IPv6) не будут надёжно распространяться в глобальном DFZ. Помимо этого, их принятие открывает вас для more-specific hijack атак. Фильтруйте входящие.
BIRD2:
function reject_small_prefixes_v4() {
if (net.len > 24) then {
print "REJECTED too-small prefix: ", net, " path: ", bgp_path;
reject;
}
}
function reject_small_prefixes_v6() {
if (net.len > 48) then {
print "REJECTED too-small prefix: ", net, " path: ", bgp_path;
reject;
}
}
FRR:
! Add to the same prefix-lists, before the final permit
ip prefix-list BOGONS_v4 seq 150 deny 0.0.0.0/0 ge 25 le 32
ipv6 prefix-list BOGONS_v6 seq 140 deny ::/0 ge 49 le 128
Это ловит любой префикс конкретнее /24 (IPv4) или /48 (IPv6). Эти строки должны быть перед записями seq 999 permit.
Как AS-path фильтры предотвращают route leak?
AS-path фильтры проверяют последовательность автономных систем, через которые прошёл маршрут. Они решают три проблемы: bogon ASN, которые не должны появляться в пути; чрезмерно длинные пути, указывающие на утечку или манипуляцию; и приватные ASN, не убранные перед анонсом.
Фильтрация bogon ASN
Bogon ASN — это зарезервированные номера, которые никогда не должны появляться в BGP-пути в публичном интернете:
| Диапазон ASN | Ссылка | Назначение |
|---|---|---|
| 0 | RFC 7607 | Зарезервировано |
| 23456 | RFC 4893 | AS_TRANS (переход 4-байтных AS) |
| 64496-64511 | RFC 5398 | Документация/примеры |
| 64512-65534 | RFC 6996 | Приватное использование (16-bit) |
| 65535 | RFC 7300 | Последний 16-bit ASN |
| 65536-65551 | RFC 5398 | Документация/примеры (32-bit) |
| 65552-131071 | IANA | Зарезервировано |
| 4200000000-4294967294 | RFC 6996 | Приватное использование (32-bit) |
| 4294967295 | RFC 7300 | Последний 32-bit ASN |
BIRD2:
define BOGON_ASNS = [
0,
23456,
64496..64511,
64512..65534,
65535,
65536..65551,
65552..131071,
4200000000..4294967294,
4294967295
];
function reject_bogon_asns()
int set bogon_asns;
{
bogon_asns = BOGON_ASNS;
if (bgp_path ~ bogon_asns) then {
print "REJECTED bogon ASN in path: ", net, " path: ", bgp_path;
reject;
}
}
Оператор bgp_path ~ bogon_asns проверяет, является ли какой-либо ASN в пути членом множества. Один bogon ASN где угодно в пути — и маршрут отклоняется.
FRR:
bgp as-path access-list BOGON_ASNS deny _0_
bgp as-path access-list BOGON_ASNS deny _23456_
bgp as-path access-list BOGON_ASNS deny _6449[6-9]_
bgp as-path access-list BOGON_ASNS deny _6450[0-9]_
bgp as-path access-list BOGON_ASNS deny _6451[01]_
bgp as-path access-list BOGON_ASNS deny _64[5-9][1-9][2-9]_
bgp as-path access-list BOGON_ASNS deny _6[5-9][0-9][0-9][0-9]_
bgp as-path access-list BOGON_ASNS deny _[1-9][0-9][0-9][0-9][0-9]_
bgp as-path access-list BOGON_ASNS deny _[1-3][0-9][0-9][0-9][0-9][0-9]_
bgp as-path access-list BOGON_ASNS permit .*
FRR использует regex-матчинг по строке AS-path. Подчёркивания _ матчат разделители AS-path (пробел, начало, конец). Этот подход менее точен, чем матчинг по integer-множеству в BIRD2. Для более простого, но менее гранулярного подхода используйте route-map с as-path access-list:
route-map IMPORT_FILTER deny 10
match as-path BOGON_ASNS
route-map IMPORT_FILTER permit 100
router bgp 64500
address-family ipv4 unicast
neighbor 198.51.100.1 route-map IMPORT_FILTER in
Примечание: приведённые regex-шаблоны упрощены. Матчинг полного диапазона 32-bit приватных ASN (4200000000-4294967294) через regex ненадёжен. Для продакшн-деплоев используйте bgpq4 для генерации prefix-list и AS-path фильтров из IRR-данных — это точнее и поддаётся автоматизации.
Ограничение длины AS-path
Легитимный BGP-путь редко превышает 10-15 ASN. Пути длиннее обычно указывают на route leak, path manipulation или запущенный prepending. Установите жёсткий лимит.
BIRD2:
function reject_long_paths() {
if (bgp_path.len > 25) then {
print "REJECTED long AS-path (", bgp_path.len, "): ", net, " path: ", bgp_path;
reject;
}
}
FRR:
bgp as-path access-list LONG_PATHS deny ^([0-9]+_){25,}
bgp as-path access-list LONG_PATHS permit .*
route-map IMPORT_FILTER deny 20
match as-path LONG_PATHS
Лимит 25 консервативен. Большинство легитимных маршрутов имеют путь короче 10. Если вы принимаете полную таблицу, изучите самые длинные пути в вашем RIB перед выбором порога:
# BIRD2
birdc 'show route where bgp_path.len > 15' | head -20
# FRR
vtysh -c "show ip bgp regexp ^([0-9]+_){15,}"
Удаление приватных ASN на выходе
Если вы используете iBGP с приватными ASN внутри сети, убедитесь, что они не утекают к вашим upstreamам.
BIRD2:
filter export_to_upstream_v4 {
# Strip private ASNs before advertising
bgp_path.delete([64512..65534, 4200000000..4294967294]);
# ... your export policy ...
accept;
}
FRR:
router bgp 64500
address-family ipv4 unicast
neighbor 198.51.100.1 remove-private-AS all
Ключевое слово all удаляет все приватные ASN, даже если в пути присутствуют публичные. Без all FRR удаляет приватные ASN только если весь путь состоит исключительно из приватных ASN.
Какой max-prefix limit правильно устанавливать для BGP-сессии?
Max-prefix limit (лимит максимального числа префиксов) — это предохранительный клапан, разрывающий BGP-сессию, если пир анонсирует больше префиксов, чем задан порог. Он предотвращает взрыв таблицы маршрутизации при случайной утечке полной таблицы или компрометации пира. Без него один некорректно настроенный пир может вычерпать всю память роутера.
Устанавливайте лимит исходя из ожиданий по каждому пиру:
| Тип пира | Ожидаемые префиксы (IPv4) | Рекомендуемый лимит | Рекомендуемый лимит (IPv6) |
|---|---|---|---|
| Full table upstream | ~1 200 000 (март 2026) | 1 500 000 | 300 000 |
| Partial table / IXP peer | Зависит | 1.5x текущего количества | 1.5x текущего количества |
| Клиент single-homed | 1-10 | 50 | 50 |
| Клиент multi-homed | 10-100 | 200 | 200 |
Проверьте текущий размер полной таблицы на bgp.potaroo.net перед установкой лимитов для upstream. Ставьте лимит примерно в 1.2x от ожидаемого числа, чтобы поглотить нормальный рост без ложных срабатываний.
BIRD2:
protocol bgp upstream_v4 {
local as 64500;
neighbor 198.51.100.1 as 64501;
ipv4 {
import limit 1500000 action restart;
import filter import_from_upstream_v4;
export none;
};
}
protocol bgp customer_v4 {
local as 64500;
neighbor 203.0.113.10 as 64502;
ipv4 {
import limit 50 action disable;
import filter import_from_customer_v4;
export filter export_to_customer_v4;
};
}
BIRD2 предлагает три действия при достижении лимита:
action restart— разрывает сессию и перезапускает её через паузу. Лучший вариант для upstream.action disable— разрывает и отключает протокол. Требует ручногоbirdc enableдля восстановления. Лучший вариант для клиентов, где срабатывание лимита означает что-то серьёзное.action block— прекращает импорт новых маршрутов, но держит сессию. Полезно, если хотите сохранить существующие маршруты пока разбираетесь.
FRR:
router bgp 64500
neighbor 198.51.100.1 remote-as 64501
address-family ipv4 unicast
neighbor 198.51.100.1 maximum-prefix 1500000 90 restart 5
neighbor 203.0.113.10 remote-as 64502
address-family ipv4 unicast
neighbor 203.0.113.10 maximum-prefix 50 80
В FRR maximum-prefix 1500000 90 restart 5 означает: предупреждение при 90% (1 350 000 префиксов), разрыв при 1 500 000, перезапуск сессии через 5 минут. Без ключевого слова restart FRR разрывает сессию и требует ручного clear bgp neighbor для восстановления.
Проверка конфигурации max-prefix
# BIRD2 - check current prefix count and limit
birdc show protocols all upstream_v4 | grep -E "Routes|Limit"
# FRR - check prefix count per neighbor
vtysh -c "show ip bgp summary"
Вывод показывает текущее количество префиксов рядом с настроенным лимитом. Если счётчик близок к лимиту, увеличьте порог до срабатывания.
Как GTSM защищает BGP-сессии от подделанных пакетов?
GTSM (Generalized TTL Security Mechanism, обобщённый механизм TTL-безопасности, RFC 5082) ограничивает принимаемые BGP-пакеты только непосредственно подключёнными пирами через проверку поля TTL/Hop Limit. При включении BGP-пакеты отправляются с TTL 255. Получатель дропает BGP-пакеты с TTL ниже 254 (для прямо подключённого пира). Поскольку роутеры декрементируют TTL на каждом хопе, атакующий более чем в одном хопе не может отправить пакеты, которые доберутся с TTL 255.
Это блокирует remote TCP RST injection, SYN-флуды на порт BGP 179 и сформированные BGP OPEN/UPDATE пакеты от несмежных атакующих. GTSM несовместим с eBGP multihop на той же сессии. Оба пира должны включить его.
BIRD2:
protocol bgp upstream_v4 {
local as 64500;
neighbor 198.51.100.1 as 64501;
ttl security yes;
ipv4 {
import limit 1500000 action restart;
import filter import_from_upstream_v4;
export none;
};
}
FRR:
router bgp 64500
neighbor 198.51.100.1 remote-as 64501
neighbor 198.51.100.1 ttl-security hops 1
hops 1 означает, что пир должен быть ровно в 1 хопе (прямое подключение). Устанавливайте это значение соответственно фактическому числу хопов. Для eBGP-пиров через IXP switching fabric hops 1 корректен. Для multihop сессий (например, BGP через GRE туннель) GTSM использовать нельзя. Вместо этого используйте MD5-аутентификацию:
BIRD2 MD5 альтернатива:
protocol bgp multihop_peer {
local as 64500;
neighbor 198.51.100.5 as 64503;
multihop 2;
password "your-md5-secret";
# ...
}
FRR MD5 альтернатива:
router bgp 64500
neighbor 198.51.100.5 remote-as 64503
neighbor 198.51.100.5 ebgp-multihop 2
neighbor 198.51.100.5 password your-md5-secret
Храните MD5-пароль в файле с ограниченным доступом (chmod 600), а не в основном конфиге. Для FRR ссылайтесь на него из /etc/frr/frr.conf, который уже должен быть 640 с owner frr:frr. Для BIRD2 держите /etc/bird/bird.conf в режиме 640 с owner bird:bird.
Какие BGP-фильтры требует MANRS?
MANRS (Mutually Agreed Norms for Routing Security, взаимосогласованные нормы безопасности маршрутизации) определяет базовые действия для сетевых операторов. Действия 1, 3 и 4 обязательны для участия в MANRS. Вот как фильтры из этой статьи соотносятся с действиями MANRS.
Action 1: предотвращение распространения некорректной маршрутной информации.
Это основное действие по фильтрации. Требует явных фильтров на уровне префиксов для клиентских соединений и рекомендует AS-path фильтры для предотвращения route leak.
| Фильтр из этой статьи | Покрытие MANRS Action 1 |
|---|---|
| Фильтрация prefix-list (богоны) | Предотвращает анонс/принятие зарезервированного пространства |
| Отклонение мелких префиксов | Блокирует more-specific маршруты, указывающие на hijack |
| Фильтрация bogon ASN | Отклоняет маршруты с приватными/зарезервированными ASN |
| Max-prefix limits | Останавливает распространение утёкших полных таблиц |
| Клиентские prefix-фильтры | Не в этой статье. Стройте на каждого клиента через IRR с помощью bgpq4. |
Action 2 (рекомендуется): предотвращение трафика с поддельными source-адресами.
Не BGP-фильтр. Это BCP 38/84 source address validation (uRPF). Вне рамок этой статьи, но не менее важен.
Action 3: содействие глобальной операционной коммуникации.
Поддерживайте актуальные контактные данные в PeeringDB и базе вашего RIR. Не фильтр, но операторы, правильно настраивающие фильтры, как правило, поддерживают и контактную информацию.
Action 4: содействие распространению маршрутной информации в глобальном масштабе.
Публикуйте свою политику маршрутизации в IRR (RIPE, RADB) с использованием RPSL-объектов. Создавайте ROA для RPKI. Это позволяет вашим пирам строить точные prefix-фильтры для ваших анонсов.
Комбинация bogon-фильтрации (префиксы + ASN) + отклонение мелких префиксов + max-prefix limits + клиентские prefix-list закрывает MANRS Action 1. Добавьте RPKI (RPKI ROA Setup for BGP) и регистрацию в IRR для Action 4.
Собираем всё вместе: полный import-фильтр
Вот комбинированный import-фильтр, использующий все описанные техники.
BIRD2 полный import-фильтр
# /etc/bird/filters.conf
include "/etc/bird/bogons.conf"; # BOGON_PREFIXES_V4, BOGON_PREFIXES_V6, BOGON_ASNS
function import_checks_v4() {
# 1. Reject bogon prefixes
if (net ~ BOGON_PREFIXES_V4) then {
print "REJECT bogon prefix: ", net, " ", bgp_path;
reject;
}
# 2. Reject too-small prefixes
if (net.len > 24) then {
print "REJECT small prefix: ", net, " ", bgp_path;
reject;
}
# 3. Reject bogon ASNs in path
if (bgp_path ~ [0, 23456, 64496..64511, 64512..65534, 65535,
65536..65551, 65552..131071,
4200000000..4294967294, 4294967295]) then {
print "REJECT bogon ASN: ", net, " ", bgp_path;
reject;
}
# 4. Reject excessively long paths
if (bgp_path.len > 25) then {
print "REJECT long path: ", net, " ", bgp_path;
reject;
}
# 5. Reject RPKI invalid (if RPKI is configured)
if (roa_check(rpki4, net, bgp_path.last) = ROA_INVALID) then {
print "REJECT RPKI invalid: ", net, " ", bgp_path;
reject;
}
}
filter import_upstream_v4 {
import_checks_v4();
accept;
}
protocol bgp upstream_v4 {
local as 64500;
neighbor 198.51.100.1 as 64501;
ttl security yes;
ipv4 {
import limit 1500000 action restart;
import filter import_upstream_v4;
export none;
};
}
FRR полный import-фильтр
! /etc/frr/frr.conf
! --- Prefix lists (bogons + small prefix rejection) ---
ip prefix-list IMPORT_V4 seq 10 deny 0.0.0.0/8 le 32
ip prefix-list IMPORT_V4 seq 20 deny 10.0.0.0/8 le 32
ip prefix-list IMPORT_V4 seq 30 deny 100.64.0.0/10 le 32
ip prefix-list IMPORT_V4 seq 40 deny 127.0.0.0/8 le 32
ip prefix-list IMPORT_V4 seq 50 deny 169.254.0.0/16 le 32
ip prefix-list IMPORT_V4 seq 60 deny 172.16.0.0/12 le 32
ip prefix-list IMPORT_V4 seq 70 deny 192.0.2.0/24 le 32
ip prefix-list IMPORT_V4 seq 80 deny 192.88.99.0/24 le 32
ip prefix-list IMPORT_V4 seq 90 deny 192.168.0.0/16 le 32
ip prefix-list IMPORT_V4 seq 100 deny 198.18.0.0/15 le 32
ip prefix-list IMPORT_V4 seq 110 deny 198.51.100.0/24 le 32
ip prefix-list IMPORT_V4 seq 120 deny 203.0.113.0/24 le 32
ip prefix-list IMPORT_V4 seq 130 deny 224.0.0.0/4 le 32
ip prefix-list IMPORT_V4 seq 140 deny 240.0.0.0/4 le 32
ip prefix-list IMPORT_V4 seq 150 deny 0.0.0.0/0 ge 25 le 32
ip prefix-list IMPORT_V4 seq 999 permit 0.0.0.0/0 le 32
! --- AS-path filters (bogon ASNs + path length) ---
bgp as-path access-list BOGON_ASNS deny _0_
bgp as-path access-list BOGON_ASNS deny _23456_
bgp as-path access-list BOGON_ASNS deny _6449[6-9]_
bgp as-path access-list BOGON_ASNS deny _6450[0-9]_
bgp as-path access-list BOGON_ASNS deny _6451[01]_
bgp as-path access-list BOGON_ASNS permit .*
bgp as-path access-list LONG_PATHS deny ^([0-9]+_){25,}
bgp as-path access-list LONG_PATHS permit .*
! --- Route-map combining all checks ---
route-map IMPORT_UPSTREAM deny 10
match as-path BOGON_ASNS
route-map IMPORT_UPSTREAM deny 20
match as-path LONG_PATHS
route-map IMPORT_UPSTREAM permit 100
! --- BGP neighbor configuration ---
router bgp 64500
neighbor 198.51.100.1 remote-as 64501
neighbor 198.51.100.1 ttl-security hops 1
address-family ipv4 unicast
neighbor 198.51.100.1 prefix-list IMPORT_V4 in
neighbor 198.51.100.1 route-map IMPORT_UPSTREAM in
neighbor 198.51.100.1 maximum-prefix 1500000 90 restart 5
В FRR оцениваются и prefix-list, и route-map. Prefix-list выполняется первым и дропает bogon-префиксы и мелкие префиксы. Маршруты, прошедшие prefix-list, попадают в route-map, который проверяет AS-path фильтры. Оба должны пропустить маршрут для его принятия.
Как проверить, что BGP-фильтры работают?
Фильтры полезны только если они действительно отклоняют то, что должны. Проверяйте после каждого изменения.
Проверка BIRD2
# Check what routes were rejected (requires print statements in filters)
grep "REJECT" /var/log/bird.log | tail -20
# Show the routing table with filter details
birdc show route filtered
# Show routes from a specific protocol
birdc show route protocol upstream_v4
# Count accepted routes per protocol
birdc show protocols all upstream_v4 | grep "Routes:"
# Test a specific prefix against your import filter
birdc show route for 10.0.0.0/8 all
Команда show route filtered показывает маршруты, которые были получены, но отклонены import-фильтром. Если bogon-фильтр работает, в принятой таблице не должно быть bogon-префиксов, а все полученные богоны должны быть в filtered table.
Проверка FRR
# Show accepted routes from a neighbor
vtysh -c "show ip bgp neighbors 198.51.100.1 received-routes"
# Show routes filtered by inbound policy
vtysh -c "show ip bgp neighbors 198.51.100.1 filtered-routes"
# Check the prefix count per neighbor
vtysh -c "show ip bgp summary"
# Test if a specific prefix is accepted
vtysh -c "show ip bgp 10.0.0.0/8"
# Check max-prefix status
vtysh -c "show ip bgp neighbors 198.51.100.1" | grep -A2 "Maximum prefix"
Для работы received-routes и filtered-routes необходимо включить soft-reconfiguration inbound для neighbour:
router bgp 64500
address-family ipv4 unicast
neighbor 198.51.100.1 soft-reconfiguration inbound
Это использует дополнительную память (хранит все полученные маршруты до фильтрации). На full-table сессии это примерно 2x памяти для RIB. На продакшн-роутерах с ограниченной RAM используйте избирательно.
Внешняя проверка
Ваши фильтры защищают ваш RIB. Чтобы проверить, что вы анонсируете другим, используйте внешние looking glass:
- bgp.tools — поищите ваш ASN, чтобы увидеть, что вы анонсируете глобально
- RIPE RIS — BGP routing information service, показывает видимость маршрутов через коллекторы
- Hurricane Electric BGP Toolkit — поиск префиксов и ASN
Проверяйте после изменения фильтров, чтобы убедиться, что вы не фильтруете случайно легитимные маршруты и не утекаете маршруты, которые не должны быть анонсированы.
Для автоматизированного мониторинга см. .
Сравнение синтаксиса BIRD2 и FRR
Краткий справочник для перевода между двумя демонами:
| Тип фильтра | BIRD2 | FRR |
|---|---|---|
| Bogon prefix | if (net ~ BOGON_PREFIXES) then reject |
ip prefix-list BOGONS deny 10.0.0.0/8 le 32 |
| Мелкий префикс | if (net.len > 24) then reject |
ip prefix-list X deny 0.0.0.0/0 ge 25 le 32 |
| Bogon ASN | if (bgp_path ~ [64512..65534]) then reject |
bgp as-path access-list X deny _64[5-9][1-9][2-9]_ |
| Длина пути | if (bgp_path.len > 25) then reject |
bgp as-path access-list X deny ^([0-9]+_){25,} |
| Max-prefix | import limit 50 action disable |
neighbor X maximum-prefix 50 |
| GTSM | ttl security yes |
neighbor X ttl-security hops 1 |
| MD5 auth | password "secret" |
neighbor X password secret |
| Strip private AS | bgp_path.delete([64512..65534]) |
neighbor X remove-private-AS all |
| Применить фильтр | import filter name |
neighbor X prefix-list/route-map name in |
BIRD2 использует единую функцию-фильтр, объединяющую все проверки. FRR разделяет проверки по prefix-list (матчинг префиксов), as-path access-list (матчинг путей) и route-map (объединение нескольких условий). Оба подхода работают. Подход BIRD2 читается лучше при сложных политиках. Подход FRR привычнее операторам Cisco.
Что-то пошло не так?
Сессия разорвана по max-prefix: проверьте journalctl -u bird или journalctl -u frr на предмет сообщения о срабатывании лимита. Увеличьте лимит, если пир легитимно вырос, или расследуйте как утечку. В BIRD2 восстановите с помощью birdc enable upstream_v4. В FRR очистите командой vtysh -c "clear bgp 198.51.100.1".
Легитимные маршруты фильтруются: проверьте birdc show route filtered или vtysh -c "show ip bgp neighbors X filtered-routes", чтобы увидеть, что было дропнуто. Частая причина: список богонов слишком агрессивен, или порог мелкого префикса отклоняет легитимные /25 от клиента. Скорректируйте фильтр и перезагрузите: birdc configure или vtysh -c "write memory", затем systemctl reload frr.
GTSM отклоняет валидного пира: оба конца должны включить GTSM. Если на одной стороне включён, а на другой нет, пакеты приходят с TTL 1 и дропаются стороной с GTSM. Проверьте через tcpdump -i eth0 port 179 -v и посмотрите на значение TTL.
Фильтры не применились после изменения: в BIRD2 запустите birdc configure для перезагрузки. В FRR при изменении prefix-list или route-map инициируйте soft reset: vtysh -c "clear bgp 198.51.100.1 in". Без этого существующие маршруты в RIB не переоцениваются по новому фильтру.
Логи: оба демона по умолчанию пишут в systemd journal.
# BIRD2
journalctl -u bird -f
# FRR
journalctl -u frr -f
Операторы print в функциях-фильтрах BIRD2 пишут в bird log. В FRR включите debug-логирование с debug bgp updates в vtysh для временного диагностирования. Отключайте после завершения — это генерирует большой объём вывода.
Эта статья является частью серии BGP Bring Your Own IP on a VPS.
Copyright 2026 Virtua.Cloud. Все права защищены.
Готовы попробовать?
Разверните свой сервер за секунды. Linux, Windows или FreeBSD.
Смотреть тарифы VPS