Выберите продукт

Debian/Ubuntu: nftables sets с timeout и interval для динамических списков IP

Показываю, как в Debian и Ubuntu применять nftables sets для больших списков IP, временных банов и диапазонов адресов. Разберём timeout и interval, типичные ошибки, поведение при reload, расход памяти и удобные шаблоны конфигурации для реального сервера.
Debian/Ubuntu: nftables sets с timeout и interval для динамических списков IP

NFTables давно стал стандартным firewall-стеком для Debian и Ubuntu, но многие администраторы по привычке продолжают мыслить отдельными правилами: одно правило на один IP, ещё одно на подсеть, ещё десяток на временные блокировки. На маленьком сервере это ещё терпимо, а на нагруженном узле быстро превращается в плохо читаемую конфигурацию, долгую загрузку правил и лишний расход ресурсов.

Именно здесь полезны nftables sets — наборы элементов, к которым можно обращаться из одного правила. Вместо сотен и тысяч строк вы храните IP-адреса, сети или диапазоны в отдельной структуре, а правило проверки остаётся коротким и понятным. В результате проще сопровождать конфигурацию, быстрее обновлять блок-листы и безопаснее внедрять временные ограничения.

В этой статье разберём три ключевые возможности: обычные sets для списков IP, параметр timeout для автоматического удаления временных блокировок и флаг interval для хранения сетей и диапазонов адресов без создания бесконечной простыни правил. Всё будет на примерах для Debian и Ubuntu с акцентом на практику.

Дополнительно посмотрим, где dynamic sets действительно удобны, как они ведут себя при перезагрузке правил, почему важно понимать ограничения на типы элементов и как не испортить себе firewall попыткой смешать постоянные и временные данные в одной таблице.

Если коротко, sets в nftables — один из самых полезных инструментов для временного бана агрессивных клиентов, оптимизации доступа к SSH и API, а также компактного описания доверенных сетей. А ещё это хороший способ снизить сложность конфигурации без потери гибкости.

Что такое nftables sets и зачем они нужны

Set в nftables — это именованный набор элементов определённого типа. Например, набор IPv4-адресов, IPv6-адресов, портов, подсетей или сочетаний нескольких полей. В правиле firewall вы не перечисляете каждый адрес вручную, а проверяете условие вида «если источник входит в этот набор».

Практически это даёт несколько преимуществ:

  • одна логика фильтрации для большого числа IP;
  • простое пополнение и удаление адресов без переписывания цепочек;
  • удобное хранение временных блокировок через timeout;
  • компактное описание диапазонов и подсетей через interval;
  • лучшее сопровождение правил по сравнению с длинными списками ip saddr в каждой цепочке.

Типичный пример: у вас есть SSH на нестандартном порту, несколько офисных подсетей, подсеть мониторинга и пул адресов, которые временно блокируются после подозрительной активности. Вместо набора разрозненных правил можно завести несколько sets и опираться на них в одной-двух цепочках.

Главная идея простая: правила должны описывать политику, а списки адресов — храниться отдельно. Тогда firewall становится не только короче, но и предсказуемее в сопровождении.

Базовая структура таблицы и набора IP в Debian/Ubuntu

На современных Debian и Ubuntu обычно используется семейство inet, чтобы в одной таблице обслуживать IPv4 и IPv6 там, где это уместно. Но для IP-наборов есть важный нюанс: тип элемента должен быть конкретным. Для IPv4 это ipv4_addr, для IPv6 — ipv6_addr.

Ниже — минимальный пример таблицы с отдельным набором IPv4-адресов для блокировки:

table inet filter {
    set blacklist4 {
        type ipv4_addr;
    }

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

        iif lo accept
        ct state established,related accept
        ip saddr @blacklist4 drop
        tcp dport 22 accept
    }
}

Такой набор уже полезен: в него можно добавлять адреса без правки самого правила. Например, после загрузки конфигурации:

nft add element inet filter blacklist4 { 198.51.100.10 }
nft add element inet filter blacklist4 { 203.0.113.44 }

Проверить содержимое можно так:

nft list set inet filter blacklist4

Если нужен отдельный набор для IPv6, создаётся второй set с типом ipv6_addr. Смешивать IPv4 и IPv6 в одном наборе нельзя, и это одна из самых частых ошибок при первом знакомстве с nftables.

Такой подход особенно удобен на сервере с полным контролем над сетевой конфигурацией, например на VDS, где правила фильтрации и runtime-обновления не ограничены типовым окружением.

Как работает timeout в nftables sets

Параметр timeout нужен для элементов, которые должны жить ограниченное время. Это удобно для временных банов, автоматических карантинов, защитных реакций на перебор паролей, flood и похожие сценарии. Вместо отдельного механизма очистки вы добавляете IP в набор, а nftables сам удаляет его по истечении таймера.

Создаётся такой набор с указанием поддержки таймаутов:

table inet filter {
    set quarantine4 {
        type ipv4_addr;
        timeout 1h;
    }

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

        iif lo accept
        ct state established,related accept
        ip saddr @quarantine4 drop
        tcp dport 22 accept
    }
}

Здесь timeout 1h задаёт значение по умолчанию для новых элементов. Добавим адрес:

nft add element inet filter quarantine4 { 198.51.100.77 }

Через час запись исчезнет автоматически. При необходимости можно задать таймаут для конкретного элемента:

nft add element inet filter quarantine4 { 203.0.113.55 timeout 10m }

Это удобно для dynamic sets: одна и та же структура может принимать адреса с разным временем жизни. Например, краткий бан на 10 минут для подозрительного клиента и более долгий на 6 часов для повторного события.

Важно понимать, что таймаут относится именно к элементу, а не к правилу. Правило ip saddr @quarantine4 drop остаётся постоянным, а список внутри него сам меняется по мере добавления и истечения элементов.

Пример набора IP-адресов в nftables и базовой структуры таблицы filter

Где timeout особенно полезен

На практике timeout чаще всего применяют в трёх сценариях: временный blacklist для SSH, панели управления или API; краткоживущие блокировки после аномального поведения клиента; обмен данными с внешними инструментами и скриптами, когда адрес попадает в набор по событию и исчезает без ручной уборки.

Это снижает количество служебной логики вокруг firewall. Вам не нужно запускать отдельную очистку только для того, чтобы вычистить устаревшие IP из текстового списка.

Если вы выносите такие правила на отдельный сервер с полным доступом к сети и ядру, имеет смысл смотреть в сторону VDS: так проще строить собственную схему фильтрации, автоматические блокировки и отладку runtime-состояния.

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

Подводный камень: persistence и reload

Самый частый вопрос: сохраняются ли элементы с таймаутом после перезагрузки сервиса или перезаписи правил? Если вы полностью пересоздаёте таблицу через flush ruleset и затем загружаете конфигурацию заново, динамически добавленные элементы пропадут. Для постоянного хранения нужна отдельная стратегия: либо выгружать текущее состояние, либо разделять статическую конфигурацию и runtime-изменения.

Это особенно важно, если вы строите защиту вокруг временного бана IP и одновременно используете автоматическую генерацию правил из конфиг-менеджмента. Иначе можно случайно стирать активные блокировки при каждом деплое.

Как использовать interval для сетей и диапазонов IP

Флаг interval нужен, когда вы хотите хранить в set не только отдельные адреса, но и интервалы: подсети CIDR или диапазоны адресов. Это ключевой инструмент для компактных allowlist и denylist, где есть офисные сети, адресные пулы, сегменты внутренней инфраструктуры и похожие сущности.

Пример набора доверенных IPv4-сетей:

table inet filter {
    set trusted4 {
        type ipv4_addr;
        flags interval;
    }

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

        iif lo accept
        ct state established,related accept
        ip saddr @trusted4 tcp dport { 22, 443 } accept
    }
}

Теперь можно добавить как отдельный адрес, так и подсеть:

nft add element inet filter trusted4 { 192.0.2.10 }
nft add element inet filter trusted4 { 198.51.100.0/24 }
nft add element inet filter trusted4 { 203.0.113.10-203.0.113.50 }

Вот здесь и раскрывается смысл interval. Без него диапазоны и сети пришлось бы описывать отдельными правилами или хранить в менее удобной форме. С interval set остаётся компактным, а проверка в цепочке — одинаковой.

Почему interval полезен для оптимизации firewall

Когда у вас десятки подсетей и диапазонов, набор с flags interval почти всегда выигрывает у длинного списка правил по читабельности. Кроме того, логика фильтрации становится централизованной: вы меняете только содержимое набора, а не порядок правил в цепочке. Это снижает риск ошибки, когда новое правило случайно встаёт не туда и перекрывает старую логику.

Если вам интересны смежные приёмы организации фильтрации, посмотрите также материал про настройку firewall для Docker с iptables и nftables.

Можно ли совмещать timeout и interval

Да, но тут важно чётко понимать задачу. Технически можно использовать набор, который поддерживает интервалы и таймауты, если вы хотите временно блокировать не только отдельные IP, но и целые сети или диапазоны. Однако в реальной эксплуатации это не всегда хорошая идея.

Проблема не в синтаксисе, а в сопровождении. В одном наборе начинают жить статические доверенные сети, временные баны, ручные исключения и аварийные диапазоны. Через пару месяцев такой set становится нечитаемым. Поэтому на практике я рекомендую разделять роли:

  • отдельный set для постоянных allowlist-адресов;
  • отдельный set с interval для сетей и диапазонов;
  • отдельный set с timeout для временных блокировок;
  • при необходимости — независимые наборы для IPv4 и IPv6.

Такой подход упрощает аудит firewall и уменьшает шанс случайно заблокировать слишком широкую сеть на долгое время.

Dynamic sets: ручное управление и автоматизация

Динамические наборы особенно хороши, когда адреса добавляются не только из статического конфига, но и в runtime. Например, скрипт разбора логов может отправлять команды nft add element при подозрительных событиях. Для админа это заметно удобнее, чем генерировать целые фрагменты правил и перегружать весь ruleset.

Базовый сценарий может выглядеть так:

nft add element inet filter quarantine4 { 198.51.100.90 timeout 30m }
nft add element inet filter quarantine4 { 198.51.100.91 timeout 2h }
nft delete element inet filter quarantine4 { 198.51.100.90 }

То есть вы можете как ждать естественного истечения таймера, так и снимать блокировку вручную. Для интеграции со скриптами это очень удобно: логика остаётся простой, а firewall не нужно пересобирать целиком.

Отдельный плюс — скорость реакции. Добавление элемента в set обычно дешевле и безопаснее, чем постоянная модификация цепочек с большим числом правил.

Расход памяти и масштабирование: что важно знать

Вопрос расхода памяти закономерен, когда речь идёт о больших наборах IP. Универсальной цифры «один элемент = столько-то байт» здесь нет: всё зависит от типа набора, архитектуры, версии ядра, наличия таймаутов, интервалов и внутренней организации структуры. Но несколько практических выводов сделать можно.

Во-первых, set почти всегда удобнее в сопровождении, чем тысячи отдельных правил. Во-вторых, элемент с timeout обычно требует больше служебных данных, чем статический. В-третьих, interval-наборы для подсетей и диапазонов нередко позволяют радикально сократить число записей, если раньше вы хранили адреса поштучно.

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

  • это отдельные адреса или крупные сети;
  • адреса живут долго или это короткие баны;
  • список почти статичный или постоянно обновляется;
  • есть ли смысл агрегировать соседние адреса в диапазоны или CIDR.

Часто самая эффективная оптимизация — не подкрутить ядро, а правильно выбрать структуру набора. Если 20 000 IP на деле укладываются в 150 подсетей, flags interval даст заметно более компактную и понятную модель.

Главная экономия ресурсов в nftables часто достигается не магическими настройками, а уменьшением количества сущностей: меньше правил, меньше дублирования, больше агрегации через sets и interval.

Проверка содержимого nftables sets и оценка структуры правил на Linux-сервере

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

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Практический шаблон для Debian/Ubuntu

Ниже — более приземлённый пример для сервера, где есть SSH только для доверенных адресов, временный карантин и общий denylist для известных плохих IP. Это не универсальный готовый firewall, а шаблон для адаптации под свою схему доступа. Для production-сервисов с собственными приложениями и нестандартной сетевой логикой такой шаблон особенно уместен на VDS, где у вас полный контроль над сетевым стеком.

table inet filter {
    set admin4 {
        type ipv4_addr;
        flags interval;
        elements = { 192.0.2.10, 198.51.100.0/24 }
    }

    set blacklist4 {
        type ipv4_addr;
        flags interval;
        elements = { 203.0.113.0/28 }
    }

    set quarantine4 {
        type ipv4_addr;
        timeout 1h;
    }

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

        iif lo accept
        ct state established,related accept
        ct state invalid drop

        ip saddr @quarantine4 drop
        ip saddr @blacklist4 drop

        ip saddr @admin4 tcp dport 22 accept
        tcp dport 80 accept
        tcp dport 443 accept

        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept
    }
}

Почему это хороший базовый шаблон:

  • постоянные и временные данные разделены;
  • для сетей и диапазонов используется interval;
  • временный бан реализован через отдельный timeout-набор;
  • правила читаются сверху вниз без лишних повторений;
  • расширение схемы не требует переписывать половину конфигурации.

Типичные ошибки

При работе с sets в nftables администраторы чаще всего спотыкаются не о синтаксис, а о модель мышления. Вот самые частые ошибки, которые встречаются на Debian и Ubuntu-серверах.

Смешивание IPv4 и IPv6 в одном наборе

Для каждого семейства нужен свой тип элемента. Если у вас dual stack, проектируйте это сразу: blacklist4, blacklist6, trusted4, trusted6. Попытка сделать универсальный IP set обычно заканчивается разочарованием.

Хранение всего подряд в одном set

Постоянные подсети, временные баны, ручные исключения и аварийные диапазоны не должны жить в одной куче. Да, так можно быстрее стартовать, но сопровождать потом будет тяжело.

Полный reload правил без понимания последствий

Если ваши dynamic sets пополняются в runtime, полный пересоздающий reload может стереть текущее состояние. Для production-узлов это критично: вы можете незаметно потерять активные блокировки во время обычного деплоя конфигурации.

Использование interval там, где нужны только отдельные IP

Флаг interval сам по себе не вреден, но не стоит включать его на всякий случай во все наборы подряд. Конфигурация должна отражать реальную модель данных. Если в наборе всегда только одиночные адреса с временным баном, достаточно простого типа и timeout.

Как проверять и отлаживать

После изменения наборов не ограничивайтесь только просмотром файла конфигурации. Полезно регулярно проверять фактическое состояние ruleset и содержимое конкретных sets.

nft list ruleset
nft list table inet filter
nft list set inet filter quarantine4
nft list set inet filter trusted4

Если поведение кажется странным, сначала убедитесь, что адрес действительно попал в нужный набор и что правило проверки находится в правильной цепочке и порядке. На практике проблемы чаще вызваны не багом nftables, а несоответствием между статическим конфигом и runtime-состоянием.

Для углубления темы пригодится и разбор динамических наборов и blocklist-подходов в nftables, если вы строите автоматические карантины или реакцию на события из логов.

Когда sets особенно оправданы

Если подвести итог по сценариям, то nftables sets особенно полезны в следующих случаях:

  • большой список IP для блокировки или разрешения;
  • временные баны с автоматическим истечением через timeout;
  • работа с диапазонами и подсетями через interval;
  • динамическое обновление firewall без полной перегрузки правил;
  • оптимизация читаемости и структуры production-конфигурации.

Если же у вас два адреса для SSH и один локальный сегмент, можно обойтись и без наборов. Но как только правила начинают расти, sets быстро окупаются по удобству.

Вывод

Для Debian и Ubuntu связка nftables sets, timeout и interval — это не экзотика, а практический инструмент для нормального администрирования firewall. Наборы позволяют отделить политику от данных, упростить поддержку IP-списков, аккуратно внедрить временные блокировки и компактно описывать диапазоны адресов.

Если вам нужен понятный и масштабируемый firewall, начинайте с простой схемы: отдельные sets для постоянных IP, отдельные для диапазонов, отдельные для временных банов. Не смешивайте роли, контролируйте reload и регулярно проверяйте runtime-состояние. Такой подход даёт и лучшую читаемость, и более предсказуемое поведение, и нормальную основу для дальнейшей автоматизации.

А главное — избавляет от соблазна писать по одному правилу на каждый IP, что почти всегда плохо заканчивается, когда сервер выходит за пределы домашнего масштаба.

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

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

Debian и Ubuntu: как работает cloud-init на first boot, где искать datasource, cache и почему не применяется user-data OpenAI Статья написана AI (GPT 5)

Debian и Ubuntu: как работает cloud-init на first boot, где искать datasource, cache и почему не применяется user-data

Разбираем, почему в Debian и Ubuntu cloud-init не применяет user-data, как определяется datasource, что хранится в /var/lib/cloud ...
Debian/Ubuntu: как исправить x509: certificate signed by unknown authority в Docker, containerd и kubelet OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить x509: certificate signed by unknown authority в Docker, containerd и kubelet

Если Docker, containerd или kubelet на Debian/Ubuntu не могут скачать образ из registry и отвечают x509: certificate signed by unk ...
Debian/Ubuntu: как исправить stale file handle в NFS OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить stale file handle в NFS

Ошибка stale file handle в NFS на Debian и Ubuntu обычно появляется после перезагрузки сервера, failover, отката snapshot или пере ...