Защита самого роутера: CoPP, фильтры management-plane и пример на Linux
Транзитный трафик и пакеты, адресованные самому роутеру, попадают в разные контуры. Разбираем, как защитить control plane и management plane на Linux-маршрутизаторе с помощью nftables — и чего в этой схеме не хватает.
Защита маршрутизатора сводится к простому вопросу: что роутер обязан слышать, от кого и с какой скоростью, — а всё остальное нужно отбрасывать как можно раньше.
Два контура на одном процессоре
У маршрутизатора по факту две работы, которые делят один CPU. Первая — транзит: пересылка чужого трафика, чем обычно занимается аппаратный fast path или ядро в режиме форвардинга. Вторая — служебная логика: протоколы маршрутизации, ответы на управляющие запросы, принятие решений. Это control plane (контур управления) и management plane (контур администрирования).
Именно второй контур уязвим. Он медленный, программный и открытый по определению: BGP, SSH, SNMP, ICMP, hello-пакеты протоколов маршрутизации — всё это обрабатывает софт. Шторм пакетов, адресованных самому устройству, или одна неудачная конфигурация способны уронить управление, тогда как трафик через роутер продолжит идти. Формально сеть «живая», но управлять ей уже нельзя.
Практика, которая это предотвращает, называется control-plane policing (CoPP) и management-plane protection. На коммерческих платформах CoPP — это per-class policers для трафика, который уходит на CPU (punted traffic); у каждого вендора свои детали реализации. На Linux та же идея ложится на цепочку input файрвола, которая видит только пакеты, назначенные самому роутеру. Транзит идёт через forward — это отдельное решение, и путать их не нужно.
Что вообще прилетает на процессор
Трафик к роутеру стоит разбить на классы, потому что лечение у них разное:
| Класс | Примеры | Как обрабатывать |
|---|---|---|
| Протоколы маршрутизации | BGP (TCP 179), OSPF, IS-IS, BFD | Принимать только от известных соседей, жёстко не ограничивать |
| Обнаружение соседей | ARP, IPv6 ND | Разрешить, ограничивать только при экстремальных скоростях |
| Управление | SSH, SNMP, NTP, syslog | Принимать только из сети управления |
| Диагностика | ICMP echo, ответы traceroute | Разрешить с ограничением скорости |
| Всё остальное | Случайное сканирование, флуд | Отбрасывать с ограниченным логированием |
Логика табличная, но важна её крайность: протоколы маршрутизации и обнаружение соседей нельзя резать тем же лимитом, что и диагностический ping. Оборвать ND — значит сломать резолвинг адресов под нагрузкой, оборвать BGP — значит потерять маршрутность.
Политика input на Linux
Ниже — рабочий каркас таблицы для nftables. Адреса учебные: 192.0.2.1 и 2001:db8:ffff::1 — сам роутер, 192.0.2.2 и 2001:db8:ffff::2 — BGP-сосед, 192.0.2.0/27 — сеть управления.
table inet cp {
set peers4 { type ipv4_addr; elements = { 192.0.2.2 } }
set peers6 { type ipv6_addr; elements = { 2001:db8:ffff::2 } }
set mgmt4 { type ipv4_addr; flags interval; elements = { 192.0.2.0/27 } }
set mgmt6 { type ipv6_addr; flags interval; elements = { 2001:db8:100::/48 } }
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
ct state invalid drop
iif lo accept
# Neighbour discovery and path MTU discovery must work
meta l4proto ipv6-icmp icmpv6 type { nd-router-solicit, nd-router-advert,
nd-neighbor-solicit, nd-neighbor-advert, packet-too-big,
destination-unreachable, time-exceeded, parameter-problem } accept
ip protocol icmp icmp type { destination-unreachable, time-exceeded } accept
# ARP is filtered in the separate arp family, not in this inet table
# Routing
ip saddr @peers4 tcp dport 179 accept
ip6 saddr @peers6 tcp dport 179 accept
ip6 saddr fe80::/10 ip6 nexthdr 89 accept
ip saddr @peers4 udp dport { 3784, 4784 } accept
# Management
ip saddr @mgmt4 tcp dport 22 accept
ip6 saddr @mgmt6 tcp dport 22 accept
ip saddr @mgmt4 udp dport 161 accept
# Ping: allowed but rate-limited
ip protocol icmp icmp type echo-request limit rate 20/second burst 40 packets accept
meta l4proto ipv6-icmp icmpv6 type echo-request limit rate 20/second burst 40 packets accept
limit rate 5/minute log prefix "cp-drop: " counter drop
counter drop
}
}
Разберём решения, которые здесь не случайны.
Политика по умолчанию — drop, и это главное в конфиге. Не список запретов определяет безопасность, а перечень разрешённого.
Ветка ct state established,related accept стоит первой и закрывает ответы на исходящие соединения роутера: запросы NTP, отправку syslog, любые исходящие сервисы. Для сервиса, который работает только наружу, входящее правило не нужно вообще.
Перечисленные типы ICMPv6 — это тот минимум, который нельзя блокировать никогда: router/neighbor solicitation и advertisement, packet-too-big (без него ломается Path MTU Discovery), destination-unreachable, time-exceeded, parameter-problem. Обнаружение соседей при этом намеренно не лимитируется: под нагрузкой лимит здесь превращается в отказ адресации.
OSPFv3 принимается только из link-local (fe80::/10), BGP — только по IP конкретного соседа, BFD — только по известным peer-адресам. Echo-request разрешён, но с лимитом 20 пакетов в секунду и burst 40: пинг нужен операторам, полностью резать его бессмысленно.
Последние две строки закрывают проблему логирования: сэмпл в 5 записей в минуту даёт видимость, а счётчик на drop — статистику. Полный лог всех отброшенных пакетов при атаке забил бы диск за минуты.
Отдельно: ARP в семействе inet не фильтруется — ему нужна своя цепочка в семействе arp. Это частая ошибка при переносе правил с других платформ.
Сессионная защита: файрвол не панацея
Файрвол определяет, кто имеет право разговаривать с процессом. Он не определяет, что легитимный сосед может сделать. Поэтому BGP стоит защищать и на уровне сессии: TCP-AO или MD5-аутентификация, TTL security (GTSM) против спуфинга с удалённых узлов, ограничение числа префиксов (maximum-prefix), BFD с разумными таймерами.
Это разные слои, и подменять один другим нельзя. Правило «принимать TCP 179 только от 192.0.2.2» не спасёт от компрометированного соседа, который внезапно начнёт лить десятки тысяч маршрутов.
Управление: пять практических правил
-
Отделить management от транзита. Отдельный management VRF или out-of-band сеть означает, что транзитный флуд не отрежет вам доступ к устройству. Это самое дешёвое и самое эффективное решение из всех.
-
Выключить неиспользуемое. Каждый слушающий сервис — это объект для патчинга.
ss -tulpnна Linux-роутере покажет, что открыто: лишнее удалять, нужное привязывать к адресу управления. -
Аутентификация и шифрование. SSH по ключам, SNMPv3 вместо v1/v2c (которые передают community-строки в открытом виде), аутентифицируемый NTP там, где это реализуемо.
-
Мониторинг счётчиков. Рост counter на правилах дропа — это сигнал, а не рутина.
-
Лимитировать то, что атакующий может заставить делать роутер. Любая работа, которую вызывает пакет, — например, TCP SYN к открытому порту, — ограничивается per-source метром в nftables.
Как тестировать, не уронив прод
Три несложных правила безопасности при внедрении: валилочная лаборатория вместо боевого роутера, синтаксическая проверка через nft -c -f file перед применением и откат по таймеру, если что-то пошло не так.
После применения смотрим, что политика действительно делает:
nft list ruleset
nft list chain inet cp input
Счётчики покажут, какие правила срабатывали. Затем из лабораторного хоста даёте управляемый флуд в роутер — например, ping -f по правилу с рейт-лимитом — и проверяете, что BGP-сессии пережили тест. Если не можете показать, что маршрутизация выжила, контроль вы не защитили.
Здесь нужна прямая оговорка: приведённый конфиг составлен по документации и на реальном маршрутизаторе не прогонялся. Это хороший отправный шаблон, но не сертифицированный профиль безопасности. Разумный минимум проверок перед выкаткой — прогон синтаксиса, тест в лаборатории и постепенное применение с наблюдением за счётчиками.
Чего в статье нет
Материал намеренно плоский и относится к инфраструктурным операторам, а не к домашним пользователям: на домашнем роутере с закрытым WAN вопрос CoPP решается короче — не слушать служебные сервисы на внешнем интерфейсе. Отдельных цифр по накладным расходам nftables на слабых CPU или сравнения с iptables/ebpf здесь не даётся, и для оценки производительности на конкретной платформе нужны собственные замеры.
Ещё один момент прозрачности: разбор сделан от лица компании IPYE, которая занимается арендой IPv4-, IPv6- и ASN-пространства и упоминается в оригинальной публикации в рекламных целях. К самим техническим рекомендациям это отношения не имеет, но читатель имеет право знать, кто их публикует.
Итог
Control-plane protection — это не набор хитрых правил, а дисциплина описания разрешённого. Идентифицировать, что роутер обязан слышать, от кого и с какой скоростью, разрешить ровно это, а всё остальное дропать на входе. Львиную долю пользы даёт самая простая часть: отказ обслуживать management- и routing-трафик с адресов, с которых он не должен приходить никогда. Всё остальное — рейт-лимиты, сессионная защита BGP, раздельный management VRF — уже вторая линия, которая делает систему устойчивой к сценариям за пределами случайного шума.