RPKI ROA для BGP: создание ROA, валидация маршрутов в BIRD2 и FRR

10 мин чтения·Matthieu·rpkiroabgpbird2frrroutinatorripe-nccipv6|

Создайте IPv4 и IPv6 ROA в портале RIPE NCC, установите Routinator как RTR-кеш, настройте валидацию RPKI в BIRD2 и FRRouting, проверьте статус префиксов через bgp.tools и RIPE Stat.

Без RPKI любой ASN может анонсировать любой префикс. Route Origin Authorization (ROA) криптографически привязывает ваш префикс к вашему ASN, а Route Origin Validation (ROV) позволяет вашему маршрутизатору отклонять невалидные анонсы. Этот туториал покрывает всю цепочку: создание ROA в портале RIPE NCC, запуск Routinator как локального RPKI-кеша, настройка валидации в BIRD2 и FRRouting, проверка работоспособности.

Предварительные требования: зарегистрированный ASN, выделенные IP-префиксы (PA или PI), работающая BGP-сессия на Linux VPS (BGP со своим IP на VPS), и уже запущенный BIRD2 (Настройка BGP в BIRD2) или FRR (Настройка BGP в FRR).

Что такое RPKI и зачем вашему BGP-префиксу нужен ROA?

Resource Public Key Infrastructure (RPKI) — криптографический фреймворк, определённый в RFC 6480, который привязывает интернет-ресурсы (IP-префиксы, ASN) к их законным владельцам через сертификаты X.509, выданные региональными интернет-регистратурами. Route Origin Authorization (ROA) — подписанный объект, который заявляет: «ASN X авторизован анонсировать префикс Y с максимальной длиной Z». Валидаторы получают эти ROA и передают результат маршрутизаторам по протоколу RPKI-to-Router (RTR) (RFC 8210).

Когда маршрутизатор получает BGP-апдейт, он проверяет origin ASN и префикс по своей локальной ROA-таблице. Каждый префикс получает один из трёх статусов валидации:

Статус Значение Рекомендуемое действие
Valid ROA существует и совпадает с origin ASN и длиной префикса Принять
Invalid ROA существует, но origin ASN или длина префикса не совпадают Отклонить
Not Found Ни один ROA не покрывает этот префикс Принять (опционально с пониженным local-pref)

Без ROA ваши префиксы отображаются как «Not Found». Это лучше, чем «Invalid», но сети, выполняющие ROV, предпочтут «Valid» маршруты от ваших пиров вашим анонсам «Not Found», когда доступны оба варианта. Создание ROA — первый шаг. Валидация входящих маршрутов защищает вашу сеть от принятия угнанных префиксов.

Как создать IPv4 и IPv6 ROA в портале RIPE NCC?

Войдите в портал RIPE NCC, перейдите в Resources, затем RPKI Dashboard. Если вы ещё не инициализировали RPKI, выберите «Hosted» certificate authority. RIPE NCC управляет CA и подписью за вас. После активации Hosted CA переключитесь на вкладку BGP Announcements. RIPE предзаполняет предложения ROA на основе ваших текущих BGP-анонсов.

  1. Нажмите Create ROA (или + New ROA на вкладке ROA).
  2. Установите Origin ASN — ваш номер AS (например, AS213279).
  3. Установите Prefix — вашу IPv4-аллокацию (например, 192.0.2.0/24).
  4. Установите Maximum Length равным длине префикса (/24). Не увеличивайте. См. раздел о maxLength ниже.
  5. Нажмите Publish.
  6. Повторите для вашего IPv6-префикса (например, 2001:db8::/48 с максимальной длиной /48).

Проверьте в RPKI Dashboard, что статус ROA показывает «Published». Распространение до валидаторов занимает обычно от 10 до 20 минут, в зависимости от интервала обновления.

Напоминание о dual-stack: создайте один ROA на префикс. Если вы анонсируете 192.0.2.0/24 и 2001:db8::/48, нужны два ROA. Если вы анонсируете дополнительные more-specific (например, /25 из /24), каждому нужен свой ROA со своей привязкой к ASN.

Как установить Routinator как RPKI-RTR кеш на Linux?

Routinator — RPKI Relying Party (валидатор), разработанный NLnet Labs. Он получает и валидирует ROA от всех пяти trust anchor'ов RIR, затем отдаёт Validated ROA Payloads (VRP) вашему маршрутизатору по протоколу RTR. Текущая стабильная версия: 0.15.1.

Установка из репозитория NLnet Labs

На Debian 12 или Ubuntu 24.04:

sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release

Добавьте ключ подписи и репозиторий NLnet Labs:

curl -fsSL https://packages.nlnetlabs.nl/aptkey.asc | sudo gpg --dearmor -o /usr/share/keyrings/nlnetlabs-archive-keyring.gpg

Для Debian:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/nlnetlabs-archive-keyring.gpg] https://packages.nlnetlabs.nl/linux/debian $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/nlnetlabs.list > /dev/null

Для Ubuntu:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/nlnetlabs-archive-keyring.gpg] https://packages.nlnetlabs.nl/linux/ubuntu $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/nlnetlabs.list > /dev/null

Установите Routinator:

sudo apt update
sudo apt install -y routinator

Пакет устанавливает systemd-сервис, который стартует автоматически. Routinator работает от пользователя routinator.

Проверка сервиса

sudo systemctl status routinator

Вы должны увидеть active (running). Первая синхронизация занимает от 2 до 5 минут — Routinator скачивает все сертификаты trust anchor и валидирует глобальный набор ROA.

Проверьте завершение начальной синхронизации через HTTP API (пакетная версия пишет логи в syslog с минимумом деталей, HTTP API — надёжный источник):

curl -s http://127.0.0.1:8323/api/v1/status | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'IPv4 VRPs: {d[\"payload\"][\"routeOriginsIPv4\"][\"final\"]}, IPv6 VRPs: {d[\"payload\"][\"routeOriginsIPv6\"][\"final\"]}')"

Если синхронизация ещё идёт, счётчики будут нулевыми. Подождите 2–5 минут и попробуйте снова. Когда увидите ненулевые значения (сотни тысяч для IPv4, десятки тысяч для IPv6), начальная синхронизация завершена.

Конфигурация

Конфиг пакета — /etc/routinator/routinator.conf. Дефолтные значения безопасны: RTR слушает на 127.0.0.1:3323, HTTP на 127.0.0.1:8323. Оба привязаны только к localhost.

Ключевые параметры:

Параметр По умолчанию Назначение
rtr-listen ["127.0.0.1:3323"] RTR-сервер для маршрутизаторов
http-listen ["127.0.0.1:8323"] HTTP-интерфейс и API
refresh 600 Секунд между RPKI-синхронизациями
retry 600 Секунд до повторной попытки после неудачной синхронизации
expire 7200 Секунд до истечения кешированных VRP

Если BIRD2 или FRR работает на той же машине (типичная конфигурация для VPS с BGP), оставьте дефолтный binding на 127.0.0.1. Изменения файрвола не нужны.

Если Routinator работает на отдельном сервере, привяжите его к приватному IP и ограничьте доступ:

sudo ufw allow from 10.0.0.0/24 to any port 3323 proto tcp comment "RTR from routers"

Проверьте HTTP-интерфейс:

curl -s http://127.0.0.1:8323/api/v1/status | head -20

Вернёт JSON с текущим количеством VRP, временем последней синхронизации и статусом валидатора.

Как настроить RPKI-валидацию в BIRD2?

BIRD2 нативно поддерживает RPKI через протокол rpki (доступен с BIRD 2.0; Ubuntu 24.04 поставляет BIRD 2.14). Он подключается к Routinator по RTR, заполняет ROA-таблицы и предоставляет функцию roa_check() для импорт-фильтров. Внешние библиотеки не нужны.

Добавьте следующее в конфигурацию BIRD2 (обычно /etc/bird/bird.conf):

Определение ROA-таблиц

roa4 table roa_v4;
roa6 table roa_v6;

Настройка протокола RPKI

protocol rpki rpki_routinator {
    roa4 { table roa_v4; };
    roa6 { table roa_v6; };
    remote 127.0.0.1 port 3323;
    retry keep 90;
    refresh keep 600;
    expire keep 7200;
}

Ключевое слово keep говорит BIRD предпочитать значения таймеров от сервера, откатываясь к указанным дефолтам. retry 90 означает, что BIRD переподключится через 90 секунд после потери RTR-сессии.

Добавление ROA-валидации в импорт-фильтр

filter bgp_import_v4 {
    if (roa_check(roa_v4, net, bgp_path.last_nonaggregated) = ROA_INVALID) then {
        print "RPKI INVALID: ", net, " from AS", bgp_path.last;
        reject;
    }
    if (roa_check(roa_v4, net, bgp_path.last_nonaggregated) = ROA_VALID) then {
        bgp_local_pref = 200;
    }
    accept;
}

filter bgp_import_v6 {
    if (roa_check(roa_v6, net, bgp_path.last_nonaggregated) = ROA_INVALID) then {
        print "RPKI INVALID: ", net, " from AS", bgp_path.last;
        reject;
    }
    if (roa_check(roa_v6, net, bgp_path.last_nonaggregated) = ROA_VALID) then {
        bgp_local_pref = 200;
    }
    accept;
}

bgp_path.last_nonaggregated безопаснее bgp_path.last, так как пропускает записи AS_SET от агрегации. Невалидные маршруты отклоняются. Валидные получают повышенный local-pref. Маршруты Not Found проходят с дефолтным local-pref.

Применение фильтра к BGP-пиру

protocol bgp upstream_v4 {
    local as 213279;
    neighbor 198.51.100.1 as 64500;
    ipv4 {
        import filter bgp_import_v4;
        import table;
        export where source ~ [RTS_STATIC, RTS_BGP];
    };
}

Директива import table важна. Она позволяет BIRD переоценивать отфильтрованные маршруты при изменении ROA-таблицы, без полного сброса сессии.

Перезагрузка и проверка

sudo birdc configure

Проверьте RPKI-сессию:

sudo birdc show protocols all rpki_routinator

Ищите Established в выводе. Затем проверьте содержимое ROA-таблицы:

sudo birdc show route table roa_v4 count

Вы должны увидеть сотни тысяч записей (глобальная ROA-таблица содержит более 800 000 VRP на начало 2026 года).

Проверка валидации конкретного префикса:

sudo birdc show route 192.0.2.0/24 all

Вывод включает поле ROA со значением valid, invalid или unknown (not found).

Как настроить RPKI-валидацию в FRRouting?

FRRouting поддерживает RPKI через модуль rpki, использующий librtr (Ubuntu 24.04 поставляет FRR 8.4.4; FRR 9.x+ и 10.x тоже поддерживаются). Модуль подключается к RTR-серверу Routinator и интегрируется с BGP route-map'ами.

Установка модуля RPKI

На Debian/Ubuntu с уже установленным FRR:

sudo apt install -y frr-rpki-rtrlib

Включение модуля

Отредактируйте /etc/frr/daemons и добавьте -M rpki в опции bgpd:

bgpd_options="  -A 127.0.0.1 -M rpki"

Перезапустите FRR:

sudo systemctl restart frr

Проверьте, загрузил ли bgpd модуль:

sudo vtysh -c "show rpki cache-server"

Если команда выполняется без ошибок (вывод может быть пустым до настройки кеша), модуль загружен. Если получаете % Unknown command, отсутствует флаг -M rpki или не установлен frr-rpki-rtrlib.

Настройка RTR-кеша

Войдите в vtysh и настройте:

sudo vtysh
configure terminal
rpki
 rpki cache 127.0.0.1 3323 preference 1
 rpki polling_period 300
 rpki expire_interval 7200
 rpki retry_interval 600
 exit

Заметка: FRR 9.x+ использует синтаксис rpki cache tcp 127.0.0.1 3323 preference 1 (с явным ключевым словом tcp). FRR 8.x использует rpki cache 127.0.0.1 3323 preference 1 без него. Проверьте версию командой vtysh -c "show version".

Создание route-map для RPKI-статусов

route-map rpki-filter permit 10
 match rpki valid
 set local-preference 200
exit

route-map rpki-filter deny 20
 match rpki invalid
exit

route-map rpki-filter permit 30
 match rpki notfound
exit

Валидные маршруты принимаются с повышенным local-pref, невалидные отклоняются, not-found принимаются с дефолтным local-pref.

Применение route-map к BGP-соседу

router bgp 213279
 neighbor 198.51.100.1 remote-as 64500
 address-family ipv4 unicast
  neighbor 198.51.100.1 route-map rpki-filter in
  neighbor 198.51.100.1 soft-reconfiguration inbound
 exit-address-family
 address-family ipv6 unicast
  neighbor 2001:db8::1 route-map rpki-filter in
  neighbor 2001:db8::1 soft-reconfiguration inbound
 exit-address-family
exit

soft-reconfiguration inbound обязателен. Без него FRR не может переоценить существующие маршруты при обновлении RPKI-кеша. FRR хранит неизменённые маршруты от пира и заново применяет route-map при изменении VRP.

Сохраните конфигурацию:

write memory
end

Проверка

Проверьте RTR-подключение:

sudo vtysh -c "show rpki cache-connection"

Ищите (connected) в выводе. Затем проверьте таблицу префиксов:

sudo vtysh -c "show rpki prefix-table" | head -20

Фильтрация BGP-маршрутов по статусу валидации:

sudo vtysh -c "show bgp ipv4 unicast rpki valid" | head -20
sudo vtysh -c "show bgp ipv4 unicast rpki invalid"

Вывод invalid должен показать маршруты, которые вы активно отклоняете.

BIRD2 vs FRR: конфигурация RPKI одним взглядом

Функция BIRD2 FRR
Установка модуля Встроен (дополнительный пакет не нужен) Пакет frr-rpki-rtrlib + флаг -M rpki
Конфигурация RTR Блок protocol rpki с remote Команда rpki cache в vtysh
ROA-таблицы Явные таблицы roa4/roa6 Внутренние, напрямую не доступны
Механизм фильтрации roa_check() в импорт-фильтре match rpki в route-map
Автоматическая переоценка Директива import table soft-reconfiguration inbound
Показать количество ROA birdc show route table roa_v4 count vtysh show rpki prefix-table
Показать валидацию birdc show route ... all (поле ROA) vtysh show bgp rpki valid/invalid/notfound

Как проверить RPKI-статус вашего префикса?

После создания ROA и настройки валидации проверьте с нескольких точек наблюдения.

Локальная проверка

На самом маршрутизаторе убедитесь, что ваш префикс отображается как валидный:

BIRD2:

sudo birdc show route 192.0.2.0/24 all | grep -i roa

FRR:

sudo vtysh -c "show rpki prefix-table 192.0.2.0/24"

Оба должны показать ваш ASN как авторизованный origin.

HTTP API Routinator

curl -s "http://127.0.0.1:8323/api/v1/validity/AS213279/192.0.2.0/24"

Возвращает JSON со статусом валидации, совпадающими VRP и исходным trust anchor.

bgp.tools

Откройте https://bgp.tools/prefix/192.0.2.0/24 в браузере. Колонка RPKI показывает зелёный щит для Valid, красный для Invalid или серый для Not Found. После создания ROA подождите 15–30 минут, пока внешние инструменты подхватят изменение.

RIPE Stat

Запросите API валидации RPKI:

curl -s "https://stat.ripe.net/data/rpki-validation/data.json?resource=AS213279&prefix=192.0.2.0/24" | python3 -m json.tool

Ищите "status": "valid" в ответе. RIPE Stat также показывает, какие ROA покрывают префикс и совпадает ли maxLength.

Повторите для IPv6

Выполните те же проверки с вашим IPv6-префиксом. Каждая команда выше принимает IPv6-префиксы. Замените 192.0.2.0/24 на 2001:db8::/48 и убедитесь, что обе семейства адресов покрыты.

Почему не стоит ставить maxLength больше длины префикса?

Установите maxLength равным длине вашего префикса. Это рекомендация RFC 9319 (которая обновляет и расширяет RFC 7115).

Когда вы ставите maxLength /24 на ROA /20, вы авторизуете свой ASN анонсировать /20 и каждый more-specific до /24. Это значит, что покрыты 16 /24. Атакующий, угнавший один из этих /24 с вашим ASN в origin, пройдёт RPKI-валидацию как «Valid». Угнанный more-specific побеждает по longest-match routing, и ROA не поможет, потому что вы авторизовали эту длину.

Это называется forged-origin sub-prefix hijack. Замеры 2017 года, цитируемые в RFC 9319, показали, что 84% ROA с maxLength были уязвимы к этой атаке.

Конкретный пример:

ROA Что авторизует
192.0.2.0/20, maxLength /20 Только 192.0.2.0/20 от вашего ASN. Безопасно.
192.0.2.0/20, maxLength /24 /20, /21, /22, /23, /24 от вашего ASN. Любой /24 может быть угнан подменой вашего origin ASN.

Когда maxLength > длина префикса допустим? Только когда вы действительно деагрегируете в продакшене (например, анонсируете /20 и конкретные /24 для traffic engineering) и каждый деагрегированный префикс должен быть провалидирован. В таком случае создавайте отдельные ROA для каждого анонсируемого префикса вместо одного ROA с широким maxLength. Один ROA на анонс — самый безопасный паттерн.

Исключение для DDoS-митигации: если вы используете сервис типа скрабинг-центра, который переанонсирует ваши more-specific от вашего ASN, вам может потребоваться maxLength для покрытия этих префиксов. Задокументируйте это исключение и регулярно его аудитируйте.

Что происходит при падении RPKI-кеша?

Когда Routinator останавливается или становится недоступен, поведение маршрутизатора зависит от таймера expire.

BIRD2 хранит последнюю известную ROA-таблицу в памяти на время expire (по умолчанию 7200 секунд / 2 часа). В этом окне валидация продолжается нормально с устаревшими данными. После истечения BIRD удаляет все ROA-записи, и каждый маршрут откатывается в «Not Found». Маршруты не отклоняются как невалидные, но и не получают бонус valid local-pref.

FRR ведёт себя аналогично. rpki expire_interval определяет, как долго кешированные VRP остаются пригодными после разрыва RTR-соединения.

Снижение риска

Запустите вторую инстанцию Routinator или используйте другой валидатор (StayRTR, Fort) на отдельной машине. Настройте оба как RTR-источники.

BIRD2 поддерживает несколько блоков protocol rpki:

protocol rpki rpki_backup {
    roa4 { table roa_v4; };
    roa6 { table roa_v6; };
    remote 10.0.0.2 port 3323;
    retry keep 90;
    refresh keep 600;
    expire keep 7200;
}

FRR поддерживает несколько кеш-серверов с разными приоритетами:

rpki
 rpki cache 127.0.0.1 3323 preference 1
 rpki cache 10.0.0.2 3323 preference 2
exit

Меньшие значения preference пробуются первыми. FRR переключается на вторичный, если основной упал.

Мониторьте здоровье Routinator. Проверяйте systemctl status routinator и статусный эндпоинт HTTP API через вашу систему мониторинга. Настройте алерты на падение количества VRP (резкое падение до нуля означает сбой синхронизации) и на потерю RTR-соединений, видимых в journalctl -u routinator.

Устранение неполадок

ROA показывает «Not Found» после создания. Распространение занимает 10–20 минут. Routinator синхронизируется каждые 10 минут по умолчанию (refresh = 600). Принудительный перезапуск синхронизации: sudo systemctl restart routinator, затем подождите завершения начальной синхронизации.

birdc показывает 0 записей в ROA-таблице. Проверьте birdc show protocols all rpki_routinator. Если статус не «Established», убедитесь, что Routinator запущен и слушает порт 3323: ss -tlnp | grep 3323.

FRR «Unknown command» для rpki. Флаг -M rpki отсутствует в /etc/frr/daemons или frr-rpki-rtrlib не установлен. Установите пакет, добавьте флаг, перезапустите FRR.

Маршруты не переоцениваются после изменения ROA. В BIRD2 добавьте import table; в BGP-канал. В FRR включите soft-reconfiguration inbound на соседе.

Все маршруты показывают Invalid. В вашем ROA может быть неправильный ASN или префикс. Перепроверьте в портале RIPE. Также убедитесь, что ASN вашего маршрутизатора совпадает с тем, что указан в ROA.

Следующие шаги: комбинируйте RPKI-валидацию с prefix-list'ами и AS-path фильтрами для эшелонированной защиты . Мониторьте RPKI invalid алерты для ваших префиксов с помощью BGPalerter .


Copyright 2026 Virtua.Cloud. Vse prava zashchishcheny.

Готовы попробовать?

Разверните свой сервер за секунды. Linux, Windows или FreeBSD.

Смотреть тарифы VPS
RPKI ROA: создание ROA и валидация маршрутов BGP