ZIM-НИЙ SAAALEЗимние скидки: до −50% на старт и −20% на продление
до 31.01.2026 Подробнее
Выберите продукт

nftables IPv6 firewall: правильный ICMPv6 и Neighbor Discovery без потери сети

IPv6 чаще «падает» не из‑за адресов, а из‑за слишком строгого firewall: блокируют ICMPv6 и ломают Neighbor Discovery, SLAAC и PMTU. Ниже — минимально достаточные типы ICMPv6, шаблон nftables в inet table и проверки, чтобы сеть не отваливалась.
nftables IPv6 firewall: правильный ICMPv6 и Neighbor Discovery без потери сети

Почему IPv6-файрволл чаще ломают, чем защищают

В IPv4 многие привыкли к правилу: «ICMP можно прикрыть — и ничего страшного». В IPv6 это почти всегда приводит к странным, плавающим проблемам. Потому что ICMPv6 — не «только пинг», а часть базовой механики протокола.

Через ICMPv6 работают Neighbor Discovery (замена ARP), Router Discovery (RA/RS), Path MTU Discovery (PMTU) и часть сообщений об ошибках маршрутизации. Если их режете «по привычке» — сервер может быть доступен по SSH, но веб периодически подвисает, TLS-загрузки «залипают», а IPv6 то работает, то нет.

Главная мысль: в IPv6 безопасность достигается не запретом ICMPv6, а минимально достаточным набором разрешённых ICMPv6-типов плюс строгая политика для TCP/UDP и хорошая stateful-логика.

Ключевые принципы: что мы строим в nftables

Соберём шаблон, который подходит большинству серверов и VDS: общий фильтр в table inet (одна логика для IPv4/IPv6), вход по умолчанию закрыт, но «служебный» ICMPv6 разрешён корректно.

  • Используем table inet, чтобы не держать два разных набора правил для IPv4 и IPv6.
  • ICMP/ICMPv6 выносим в отдельную таблицу/цепочку с более высоким приоритетом, чтобы случайно не сломать сеть при рефакторинге.
  • Для ND/RA (локальные протоколы) при желании добавляем ограничения по интерфейсу и link-local источникам.

В IPv6 «правильный минимум» ICMPv6 — это часть стабильности сети. Лучше разрешить несколько обязательных типов и держать строгий input для TCP/UDP, чем отстрелить ICMPv6 целиком и потом ловить зависания.

Если вы поднимаете сервер на VDS, чаще всего у вас один внешний интерфейс и предсказуемый набор сервисов — поэтому такой шаблон проще поддерживать и отлаживать.

Дополнительно по типовым схемам адресации и автоконфигурации IPv6 (SLAAC/DHCPv6/маршруты) удобно свериться с отдельным разбором: SLAAC, DHCPv6 и маршрутизация IPv6 на сервере.

Вывод nftables: таблицы inet и правила для ICMPv6, выделены packet-too-big и ND/RA

Какие ICMPv6 нужны почти всегда

Ниже — практический набор для большинства серверов: даже при статическом IPv6 Neighbor Discovery и PMTU всё равно обязательны. SLAAC может не использоваться, но ND и сообщения об ошибках нужны всегда.

Neighbor Discovery: не ломаем локальную связность

Neighbor Discovery — «IPv6-замена ARP». Если заблокировать эти типы, хост может перестать видеть шлюз или соседей в одном L2-сегменте.

  • nd-neighbor-solicit (NS)
  • nd-neighbor-advert (NA)

В норме такие пакеты приходят с link-local адресов (fe80::/10) и имеют hop limit 255. Это можно использовать для ужесточения.

Router Discovery: когда нужны RA/RS

Если провайдер раздаёт параметры через Router Advertisement или вы используете SLAAC, на вход нужны:

  • nd-router-solicit (RS)
  • nd-router-advert (RA)

На части VDS IPv6 полностью статический, и RA/RS действительно «не требуются». Но в реальных сетях RA иногда несёт важные параметры, поэтому безопаснее разрешить RA/RS ограниченно (по интерфейсу и от link-local источников), чем запретить и получить неочевидные отказы.

PMTU: чтобы соединения не «залипали» на больших пакетах

Обязательный тип:

  • packet-too-big

Если блокируется packet-too-big, TCP может установить соединение, но зависнуть на передаче данных. Чаще всего это проявляется на TLS, больших ответах, VPN/туннелях, «странных» аплинках и при несовпадении MTU по пути.

Ошибки и диагностика: минимум, который реально нужен

Обычно стоит разрешать ещё:

  • destination-unreachable
  • time-exceeded
  • parameter-problem
  • echo-request/echo-reply — по желанию (под мониторинг, часто с rate-limit)

Это не «открывает порты», но помогает корректной работе стека и сильно упрощает диагностику. Пинг удобно ограничить лимитом или разрешить только с адресов мониторинга.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Шаблон nftables: inet table и отдельная обработка ICMPv6

Дальше — рабочий шаблон, где основной фильтр живёт в table inet filter, а ICMP/ICMPv6 вынесены в отдельную таблицу с более высоким приоритетом. Это снижает риск «случайно убить IPv6», когда вы редактируете правила для сервисов.

Важно: пример намеренно простой. Открывайте только нужные сервисы (SSH/HTTP/HTTPS и т.д.), а остальное оставляйте закрытым.

#!/usr/sbin/nft -f

flush ruleset

table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;

    ct state invalid drop
    ct state established,related accept

    iifname "lo" accept

    ip6 saddr ::/128 drop
    ip6 saddr ::1/128 drop

    tcp dport 22 accept
    tcp dport { 80, 443 } accept

    limit rate 10/second burst 20 packets log prefix "nft-in-drop " flags all counter
    drop
  }

  chain forward {
    type filter hook forward priority 0; policy drop;
    ct state established,related accept
    drop
  }

  chain output {
    type filter hook output priority 0; policy accept;
  }
}

table inet icmp {
  chain input {
    type filter hook input priority -5; policy accept;

    ip protocol icmp icmp type { echo-reply, echo-request, destination-unreachable, time-exceeded, parameter-problem } accept

    meta l4proto ipv6-icmp icmpv6 type {
      destination-unreachable,
      packet-too-big,
      time-exceeded,
      parameter-problem,
      echo-request,
      echo-reply,
      nd-router-solicit,
      nd-router-advert,
      nd-neighbor-solicit,
      nd-neighbor-advert
    } accept
  }
}

Почему отдельная таблица и более высокий priority

Цепочка ICMP висит на hook input с priority -5, то есть отрабатывает раньше, чем строгий policy drop в основной таблице. Практически это означает: вы можете спокойно усложнять inet filter (логирование, белые списки, порт-нодки и т.д.), не боясь, что ND/PMTU «случайно» окажутся ниже какого-то раннего drop.

Ужесточаем ND/RA: link-local, интерфейс и hop limit

Если хотите снизить поверхность атак на L2-сегменте (например, опасаетесь «левых» RA), ужесточайте не всё ICMPv6, а конкретно ND/RA:

  • разрешайте ND/RA только на нужном интерфейсе (например, eth0);
  • разрешайте ND/RA только от fe80::/10;
  • дополнительно (по ситуации) можно проверять hop limit 255 через ip6 hoplimit.
table inet icmp {
  chain input {
    type filter hook input priority -5; policy accept;

    meta l4proto ipv6-icmp icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem } accept

    iifname "eth0" ip6 saddr fe80::/10 meta l4proto ipv6-icmp icmpv6 type {
      nd-router-solicit,
      nd-router-advert,
      nd-neighbor-solicit,
      nd-neighbor-advert
    } accept

    meta l4proto ipv6-icmp icmpv6 type echo-request limit rate 5/second burst 10 packets accept
    meta l4proto ipv6-icmp icmpv6 type echo-reply accept
  }
}

Нюанс про RA Guard

Классический RA Guard — это скорее функция коммутатора/виртуальной сети. На хосте наиболее практичный минимум — ограничить RA по интерфейсу и link-local источнику. Это уже отсекает «посторонние» RA из внешних сегментов и снижает риск в пределах одного L2.

Проверка: как убедиться, что ND и PMTU живы

После применения правил проверяйте не только «открылся ли SSH», а базовую связность IPv6. Иначе ошибки всплывут позже под нагрузкой или в неожиданных сценариях.

Соседи, маршруты, шлюз

ip -6 route
ip -6 neigh show

Если соседи постоянно в INCOMPLETE или FAILED, чаще всего проблема в том, что режутся NS/NA, перепутан интерфейс в правилах или вы где-то дропаете link-local целиком.

Диагностика PMTU (Packet Too Big)

Симптомы блокировки packet-too-big — случайные зависания по IPv6 (особенно HTTPS). Для диагностики посмотрите правила и трафик ICMPv6:

nft list ruleset
nft -a list ruleset
tcpdump -n -i eth0 icmp6

Если по пути реально есть MTU-проблема, вы увидите ICMPv6 Packet too big. Ключевое: такие пакеты должны доходить до хоста и матчиться вашим разрешающим правилом, а не уходить в счётчики drop.

Когда проблема «не в ICMPv6»

Иногда IPv6 «ломается» из-за слушающих сервисов, bind на ::, настроек веб-сервера и фильтрации в нескольких местах сразу. Полезно держать под рукой разбор типовых ошибок публикации IPv6 в веб-стеке: AAAA-запись, Nginx/Apache и firewall: где чаще всего рвётся IPv6.

Диагностика IPv6: tcpdump icmp6 и команды ip -6 route и ip -6 neigh на экране

Типовые ошибки в IPv6 firewall и как их избежать

Ошибка 1: «Разрешил established/related — значит ICMPv6 не нужен»

PMTU и часть служебных сообщений не всегда укладываются в ожидания «всё важное придёт как established». В IPv6 не полагайтесь на stateful-правила как на замену корректному списку ICMPv6 типов.

Ошибка 2: Разрозненные table ip и table ip6

Так часто получается, что IPv4 правила обновляют регулярно, а IPv6 забывают. table inet дисциплинирует: общие правила пишутся один раз, а специфичные — точечно.

Ошибка 3: Политика drop в input, а ICMPv6 «где-то внизу»

Если у вас ранний drop или reject, то поздние правила ICMPv6 могут стать недостижимыми. Отдельная цепочка/таблица с более высоким priority — простой способ защититься от этой ошибки.

Ошибка 4: «Дропнуть весь fe80::/10»

Такой запрет почти гарантированно ломает ND/RA. Если хотите быть строже — ограничивайте по типам ICMPv6 и интерфейсу, а не рубите весь link-local.

Мини-шаблон только для IPv6 (если inet не нужен)

Если вы принципиально разделяете IPv4 и IPv6, вот компактный IPv6-вариант. Для большинства серверов всё же удобнее единый inet, но этот пример полезен как «срез» логики ICMPv6.

#!/usr/sbin/nft -f

flush ruleset

table ip6 filter {
  chain input {
    type filter hook input priority 0; policy drop;

    ct state invalid drop
    ct state established,related accept

    iifname "lo" accept

    meta l4proto ipv6-icmp icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem } accept

    iifname "eth0" ip6 saddr fe80::/10 meta l4proto ipv6-icmp icmpv6 type { nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept

    tcp dport 22 accept
    tcp dport { 80, 443 } accept

    drop
  }

  chain output {
    type filter hook output priority 0; policy accept;
  }
}

Чек-лист: безопасный IPv6 с nftables без сюрпризов

  1. Разрешите минимум ICMPv6 для корректной работы: packet-too-big, destination-unreachable, time-exceeded, parameter-problem.

  2. Разрешите Neighbor Discovery: nd-neighbor-solicit и nd-neighbor-advert.

  3. Если используете SLAAC/RA или провайдер присылает параметры через RA — добавьте nd-router-solicit/nd-router-advert (лучше с ограничением fe80::/10 и интерфейса).

  4. Разместите правила ICMPv6 выше общего drop или вынесите в отдельную цепочку/таблицу с более высоким priority.

  5. После изменений проверяйте ip -6 route, ip -6 neigh show и счётчики nft -a list ruleset.

Лучший результат в проде даёт подход «малый, но правильный набор» вместо бесконечных исключений после очередного «IPv6 иногда тупит». В IPv6 корректный ICMPv6 — это не лишняя дыра, а обязательная часть нормальной сетевой работы.

Поделиться статьей

Вам будет интересно

Nginx proxy_cache for static: S3 origin, revalidation, cache lock OpenAI Статья написана AI (GPT 5)

Nginx proxy_cache for static: S3 origin, revalidation, cache lock

Пошагово настраиваем Nginx как edge‑кэш для статики с origin в S3: proxy_cache_path и cache key, revalidation через ETag/Last-Modi ...
WP-CLI: смена URL в WordPress после миграции, правка двойных слешей, проверка cron и diagnose OpenAI Статья написана AI (GPT 5)

WP-CLI: смена URL в WordPress после миграции, правка двойных слешей, проверка cron и diagnose

После переноса WordPress чаще ломаются не PHP и не веб-сервер, а данные: в базе остаются старые URL, абсолютные ссылки и «кривые» ...
KVM/QEMU: virtio и tuned — практический тюнинг производительности и latency OpenAI Статья написана AI (GPT 5)

KVM/QEMU: virtio и tuned — практический тюнинг производительности и latency

Пошагово разбираем, как ускорить KVM/QEMU на Linux-хосте: проверить virtio-устройства, включить multiqueue на virtio-net, подобрат ...