nftset-access: Блокировка IP с нулевой задержкой с использованием наборов nftables ядра Linux
Требуется подписка Pro плана (или выше) на GetPageSpeed NGINX Extras.
Установка
Вы можете установить этот модуль в любой дистрибутив на базе RHEL, включая, но не ограничиваясь:
- RedHat Enterprise Linux 7, 8, 9 и 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 и Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-nftset-access
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-nftset-access
Включите модуль, добавив следующее в начало файла /etc/nginx/nginx.conf:
load_module modules/ngx_http_nftset_access.so;
Этот документ описывает nginx-module-nftset-access v3.0.0, выпущенный 14 февраля 2026 года.
Корпоративный контроль доступа на основе IP для NGINX с использованием наборов nftables Linux. Блокируйте угрозы, ограничивайте злоумышленников, бросайте вызов ботам и защищайте свою инфраструктуру.
⚠️ Коммерческое программное обеспечение Это закрытый премиум модуль, доступный исключительно через GetPageSpeed Repository.
Требование к плану: Требуется Pro план подписки GetPageSpeed NGINX Extras.
✨ Особенности
Основные функции
| Функция | Описание |
|---|---|
| Черный/Белый список | Разрешить или запретить на основе членства в наборе nftables |
| Несколько наборов | Проверка по нескольким наборам nft в одной директиве |
| Живые обновления | Изменение наборов nft без перезагрузки NGINX |
| Пользовательские коды состояния | Возвращать любой HTTP статус при блокировке |
| Поддержка CIDR | Использовать интервальные наборы для диапазонов сети (например, 192.168.1.0/24) |
Функции производительности
| Функция | Описание |
|---|---|
| Сессии на поток | Контексты libnftables, локальные для потока, устраняют конкуренцию за блокировки |
| Кэш LRU | Кэш в общей памяти с настраиваемым временем жизни |
| Коэффициенты попадания в кэш | Обычно более 95% коэффициент попадания снижает вызовы ядра |
Функции безопасности
| Функция | Описание |
|---|---|
| Ограничение скорости | Ограничение запросов на IP с настраиваемыми окнами |
| Авто-бан | Автоматическая блокировка нарушителей ограничения скорости |
| JS Challenge | Задача на доказательство работы останавливает автоматизированные боты |
| Ловушки для меда | Авто-блокировка IP, попадающих на ловушки URL |
| Таймаут на вход | Авто-истечение записей черного списка |
Операционные функции
| Функция | Описание |
|---|---|
| Режим пробного запуска | Тестирование конфигурации без блокировки |
| Fail-open/close | Управление поведением при ошибках набора nft |
| Метрики Prometheus | Нативная конечная точка /metrics для Grafana |
| JSON статистика | Подробный API статистики |
| Переменные NGINX | $nftset_result и $nftset_matched_set |
| ## |
🚀 Быстрый старт
1. Создайте наборы nftables
# Создать таблицу (если не существует)
sudo nft add table ip filter
# Создать черный список с поддержкой таймаута
sudo nft add set ip filter bad_guys '{ type ipv4_addr; flags timeout; timeout 1d; }'
# Создать список для блокировки по ограничению скорости
sudo nft add set ip filter ratelimited '{ type ipv4_addr; flags timeout; timeout 30m; }'
# Создать список ловушек для меда
sudo nft add set ip filter honeypot '{ type ipv4_addr; flags timeout; timeout 1d; }'
# Создать белый список с поддержкой CIDR
sudo nft add set ip filter trusted '{ type ipv4_addr; flags interval; }'
sudo nft add element ip filter trusted '{ 10.0.0.0/8, 192.168.0.0/16 }'
2. Настройте NGINX
load_module modules/ngx_http_nftset_access_module.so;
http {
server {
listen 80;
# Блокировать известные плохие IP (формат: table:setname)
nftset_blacklist filter:bad_guys;
# Ограничение скорости: 100 запросов в минуту
nftset_ratelimit rate=100 window=60s autoban=filter:ratelimited;
# Ваш контент
location / {
root /var/www/html;
}
# Ловушка для меда - по умолчанию возвращает 404
location /wp-admin.php {
nftset_autoadd filter:honeypot timeout=86400;
}
# Конечная точка метрик
location /metrics {
nftset_metrics;
allow 127.0.0.1;
deny all;
}
}
}
3. Протестируйте и перезагрузите
sudo nginx -t && sudo nginx -s reload
📦 Установка
Этот модуль доступен исключительно через GetPageSpeed Premium Repository.
Шаг 1: Подпишитесь на GetPageSpeed Repository
Посетите GetPageSpeed Repository Subscription, чтобы получить доступ.
Шаг 2: Установите репозиторий
# RHEL/CentOS/Rocky/Alma Linux 8+
sudo dnf install https://extras.getpagespeed.com/release-latest.rpm
Шаг 3: Установите модуль
sudo dnf install nginx-module-nftset-access
Шаг 4: Включите модуль
Добавьте в /etc/nginx/nginx.conf перед любыми блоками http {}:
load_module modules/ngx_http_nftset_access_module.so;
Шаг 5: Перезагрузите NGINX
sudo nginx -t && sudo systemctl reload nginx
📖 Справочник по конфигурации
Формат спецификации набора
Все директивы, которые ссылаются на наборы nftables, используют формат: table:setname
table— Имя таблицы nftables (например,filter,firewalld)setname— Имя набора в этой таблице
Семейство IP (ip для IPv4, ip6 для IPv6) автоопределяется по IP-адресу клиента.
Примеры:
nftset_blacklist filter:blocklist; # IPv4 клиент → ip filter blocklist
# IPv6 клиент → ip6 filter blocklist
nftset_whitelist filter:trusted;
nftset_autoadd filter:honeypot timeout=3600;
Контроль доступа
nftset_blacklist table:set1 [table:set2 ...]
Контекст: http, server
По умолчанию: —
Блокирует запросы, если IP клиента присутствует в любом из перечисленных наборов nft. Несколько наборов проверяются по порядку, пока не будет найдено совпадение.
# Один набор
nftset_blacklist filter:bad_guys;
# Несколько наборов (логика ИЛИ - заблокировано, если в ЛЮБОМ наборе)
nftset_blacklist filter:spammers filter:hackers filter:tor_exits;
# Отключить
nftset_blacklist off;
nftset_whitelist table:set1 [table:set2 ...]
Контекст: http, server
По умолчанию: —
Разрешает запросы только если IP клиента присутствует хотя бы в одном из перечисленных наборов nft. Все остальные IP отклоняются.
# Разрешить только доверенные IP
nftset_whitelist filter:trusted_partners filter:office_ips;
Важно: IP в белом списке обходят все ограничения модуля, включая:
- Ограничение скорости (nftset_ratelimit)
- Задачи на JavaScript (nftset_challenge)
Это полезно для IP администраторов, которые не должны подлежать ограничениям по скорости или задачам:
# IP администраторов обходят ограничения по скорости и задачи
nftset_whitelist filter:admin_ips;
nftset_ratelimit rate=100 window=1m autoban=filter:ratelimited ban_time=1800;
nftset_challenge on;
nftset_status code
Контекст: http, server
По умолчанию: 403
HTTP статус код, возвращаемый, когда запрос заблокирован.
nftset_status 403; # Запрещено (по умолчанию)
nftset_status 444; # Закрыть соединение без ответа (специальный NGINX)
nftset_status 429; # Слишком много запросов
nftset_status 503; # Сервис недоступен
Кэширование и производительность
nftset_cache_ttl time
Контекст: http, server
По умолчанию: 60s
Как долго кэшировать результаты поиска наборов nft. Закэшированные результаты избегают повторных вызовов ядра для одного и того же IP.
nftset_cache_ttl 30s; # 30 секунд
nftset_cache_ttl 5m; # 5 минут
nftset_cache_ttl 1h; # 1 час
Примечание по отладке: Если вы удалите IP из набора nft, но модуль все еще сообщает, что он "совпадает", это связано с кэшированием. Закэшированный результат истечет после установленного TTL. Для немедленного эффекта во время тестирования вы можете временно установить nftset_cache_ttl 0;, чтобы отключить кэширование (не рекомендуется для производства из-за влияния на производительность).
Влияние на производительность:
- Более высокий TTL = Лучшая производительность, но медленное отражение изменений в наборе nft
- Более низкий TTL = Более быстрая реакция на изменения в наборе nft, но больше вызовов ядра
- Рекомендуется: 30s до 5m для большинства случаев использования
nftset_fail_open on|off
Контекст: http, server
По умолчанию: off
Управляет поведением, когда поиск набора nft завершается неудачей (например, набор не существует).
nftset_fail_open off; # Запретить при ошибке (безопасно, по умолчанию)
nftset_fail_open on; # Разрешить при ошибке (доступно, но рискованно)
nftset_dryrun on|off
Контекст: http, server
По умолчанию: off
Когда включено, журналирует, что будет заблокировано, но на самом деле не блокирует. Идеально для тестирования новых правил в производстве.
nftset_dryrun on; # Журналировать, но не блокировать
Проверьте журналы на наличие сообщений, подобных:
nftset: DRYRUN would block 1.2.3.4 (matched: filter:bad_guys)
Важно: При использовании переменных $nftset_result и $nftset_matched_set в режиме пробного запуска эти значения отражают состояние в момент времени, когда запрос обрабатывался — не текущее состояние набора nft. Если вы позже вручную проверите набор nft и не найдете IP, возможные причины включают:
- Истечение времени: IP был добавлен с таймаутом (например,
timeout 1d) и с тех пор истек - Задержка кэша: Модуль кэширует результаты поиска (по умолчанию 60s). Запись, удаленная из набора nft, может все еще отображаться как "совпадающая", пока кэш не истечет
- Ручное удаление: Кто-то или что-то (fail2ban, скрипты) удалило запись
Это ожидаемое поведение — пробный запуск показывает вам точно то, что увидит производство во время запроса.
Ограничение скорости
nftset_ratelimit parameters
Контекст: http, server
По умолчанию: —
Ограничивает запросы на IP в пределах временного окна. Может автоматически добавлять нарушителей в набор nft.
Параметры:
| Параметр | Обязательный | Описание |
|---|---|---|
rate=N |
Да | Максимальное количество запросов за окно |
window=TIME |
Нет | Временное окно (по умолчанию: 60s) |
autoban=TABLE:SET |
Нет | набор nft для добавления нарушителей |
ban_time=N |
Нет | Секунды до автоматического истечения (по умолчанию: 3600) |
Примеры:
# Базовый: 100 запросов в минуту
nftset_ratelimit rate=100;
# С пользовательским окном: 1000 запросов в час
nftset_ratelimit rate=1000 window=1h;
# С авто-баном: Добавить нарушителей в набор nft на 30 минут
nftset_ratelimit rate=60 window=1m autoban=filter:ratelimited ban_time=1800;
# Строгая защита API
nftset_ratelimit rate=10 window=1s autoban=filter:api_abusers ban_time=3600;
Как это работает:
1. Каждый IP получает счетчик запросов и время начала окна
2. Счетчик увеличивается с каждым запросом
3. Когда окно истекает, счетчик сбрасывается
4. Если счетчик превышает rate, возвращает 429 Слишком много запросов
5. Если установлен autoban, IP добавляется в указанный набор nft
Примечание: Состояние ограничения скорости хранится в общей памяти и сохраняется при перезапусках рабочих процессов.
Задача на JavaScript
nftset_challenge on|off
Контекст: http, server
По умолчанию: off
Включает режим задачи на JavaScript. Браузеры должны решить задачу на доказательство работы, чтобы получить доступ к сайту. Эффективно против автоматизированных ботов и скрейперов.
nftset_challenge on;
Как это работает:
1. Первый запрос получает страницу с задачей (HTTP 503)
2. Браузер выполняет JavaScript, который решает задачу хеширования
3. Решение сохраняется в куки (_nftset_verified)
4. Последующие запросы с действительными куки проходят
5. Куки истекают через 24 часа
nftset_challenge_difficulty level
Контекст: http, server
По умолчанию: 2
Управляет сложностью задачи (1-8). Чем выше = тем дольше время решения.
| Уровень | Приблизительное время решения |
|---|---|
| 1 | ~100ms |
| 2 | ~500ms (по умолчанию) |
| 3 | ~1 секунда |
| 4 | ~2 секунды |
| 5 | ~5 секунд |
| 6+ | ~10+ секунд |
nftset_challenge on;
nftset_challenge_difficulty 3; # ~1 секунда времени решения
Особенности страницы задачи: - Современный, адаптивный дизайн - Анимированный индикатор загрузки - Обратная связь о прогрессе - Авто-перенаправление при успехе - Без внешних зависимостей
Авто-добавление ловушки для меда
nftset_autoadd table:setname [table:setname2 ...] [timeout=seconds] [status=code]
Контекст: server, location
По умолчанию: —
Автоматически добавляет IP клиента в указанные наборы nft, когда доступ к местоположению осуществляется и возвращает HTTP статус код. Идеально для ловушек для меда.
Параметры:
| Параметр | Обязательный | Описание |
|---|---|---|
| table:setname | Да | Целевой набор nft (можно указать несколько) |
timeout=N |
Нет | Таймаут записи в секундах |
status=N |
Нет | HTTP статус код для возврата (по умолчанию: 404) |
Примеры:
# Базовый: Добавить в набор ловушки для меда и вернуть 404 (по умолчанию)
location /config.php {
nftset_autoadd filter:honeypot;
}
# С таймаутом: Авто-истечение через 24 часа
location /wp-admin.php {
nftset_autoadd filter:scanners timeout=86400;
}
# Вернуть 403 Запрещено вместо 404
location /admin.php {
nftset_autoadd filter:honeypot timeout=86400 status=403;
}
# Добавить в несколько наборов (IPv4 и IPv6)
location /trap {
nftset_autoadd filter:honeypot4 filter:honeypot6 timeout=86400;
}
Общие пути ловушек для меда:
# Ловушки WordPress - возвращают 404, чтобы выглядеть как отсутствующий файл
location ~ ^/(wp-admin\.php|wp-login\.php|xmlrpc\.php)$ {
nftset_autoadd filter:honeypot timeout=86400;
}
# Ловушки конфигурационных файлов - возвращают 403, чтобы имитировать запрещенный доступ
location ~ ^/(\.env|config\.php|phpinfo\.php)$ {
nftset_autoadd filter:honeypot timeout=86400 status=403;
}
# Ловушки оболочки/эксплойта - серьезные, блокировать на 1 неделю
location ~ ^/(shell|cmd|eval|exec)\.php$ {
nftset_autoadd filter:malicious timeout=604800 status=403;
}
Примечание: Когда IP автоматически добавляется, модуль немедленно возвращает указанный HTTP статус код (по умолчанию 404), предотвращая дальнейшую обработку запроса. Подключение keep-alive также отключается, чтобы предотвратить дальнейшие запросы по тому же соединению.
Наблюдаемость
nftset_stats
Контекст: location
По умолчанию: —
Включает конечную точку JSON статистики.
location = /_stats {
nftset_stats;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
Смотрите JSON Stats API для формата ответа.
nftset_metrics
Контекст: location
По умолчанию: —
Включает конечную точку метрик Prometheus.
location = /metrics {
nftset_metrics;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
Смотрите Prometheus Metrics для доступных метрик.
📝 Переменные NGINX
Модуль предоставляет две переменные для использования в журналах, заголовках или условиях.
$nftset_result
Решение о доступе, принятое для этого запроса.
| Значение | Описание |
|---|---|
allow |
Запрос разрешен |
deny |
Запрос заблокирован |
dryrun |
Будет заблокирован (режим пробного запуска) |
ratelimited |
Превышен лимит скорости |
challenged |
Страница задачи обслужена |
$nftset_matched_set
Имя набора nft, который совпал (если есть), в формате table:setname. Пусто, если совпадений нет.
Примечание: Эта переменная отражает состояние совпадения в момент запроса, а не текущее состояние набора nft. Если вы вручную проверите набор nft и не найдете IP: - Запись могла истечь (наборы nft поддерживают таймауты для каждой записи) - Кэш модуля (по умолчанию 60s) может показывать недавно удаленную запись как все еще совпадающую - Что-то могло удалить запись после обработки запроса
Примеры использования
Пользовательский журнал доступа:
log_format security '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'nftset_result="$nftset_result" '
'matched_set="$nftset_matched_set"';
access_log /var/log/nginx/security.log security;
Добавить заголовки для отладки:
add_header X-NFTSet-Result $nftset_result always;
add_header X-NFTSet-Matched $nftset_matched_set always;
Условное логирование:
# Логировать только заблокированные запросы
map $nftset_result $loggable {
"deny" 1;
default 0;
}
access_log /var/log/nginx/blocked.log combined if=$loggable;
📊 Метрики Prometheus
Конечная точка /metrics возвращает метрики в формате экспозиции Prometheus.
Доступные метрики
# HELP nginx_nftset_requests_total Всего обработанных запросов
# TYPE nginx_nftset_requests_total counter
nginx_nftset_requests_total{result="checked"} 1234567
nginx_nftset_requests_total{result="allowed"} 1234000
nginx_nftset_requests_total{result="blocked"} 500
nginx_nftset_requests_total{result="error"} 67
# HELP nginx_nftset_cache_total Операции кэша
# TYPE nginx_nftset_cache_total counter
nginx_nftset_cache_total{result="hit"} 1200000
nginx_nftset_cache_total{result="miss"} 34567
# HELP nginx_nftset_cache_entries Текущие записи кэша
# TYPE nginx_nftset_cache_entries gauge
nginx_nftset_cache_entries 5432
# HELP nginx_nftset_autoadd_total Операции авто-добавления
# TYPE nginx_nftset_autoadd_total counter
nginx_nftset_autoadd_total{result="success"} 42
nginx_nftset_autoadd_total{result="failed"} 3
# HELP nginx_nftset_ratelimit_total События ограничения скорости
# TYPE nginx_nftset_ratelimit_total counter
nginx_nftset_ratelimit_total{action="triggered"} 156
nginx_nftset_ratelimit_total{action="autobanned"} 23
# HELP nginx_nftset_challenge_total События задачи
# TYPE nginx_nftset_challenge_total counter
nginx_nftset_challenge_total{result="issued"} 1000
nginx_nftset_challenge_total{result="passed"} 950
nginx_nftset_challenge_total{result="failed"} 50
# HELP nginx_nftset_uptime_seconds Время работы модуля
# TYPE nginx_nftset_uptime_seconds gauge
nginx_nftset_uptime_seconds 86400
Запросы для панели Grafana
Частота запросов по результату:
rate(nginx_nftset_requests_total[5m])
Частота блокировок:
rate(nginx_nftset_requests_total{result="blocked"}[5m])
Коэффициент попадания в кэш:
rate(nginx_nftset_cache_total{result="hit"}[5m]) /
(rate(nginx_nftset_cache_total{result="hit"}[5m]) + rate(nginx_nftset_cache_total{result="miss"}[5m]))
Триггеры ограничения скорости в минуту:
rate(nginx_nftset_ratelimit_total{action="triggered"}[1m]) * 60
📈 JSON Stats API
Конечная точка /_stats возвращает подробную статистику в формате JSON.
Формат ответа
{
"version": "3.0.0",
"uptime_seconds": 86400,
"requests": {
"checked": 1234567,
"allowed": 1234000,
"blocked": 500,
"errors": 67
},
"cache": {
"hits": 1200000,
"misses": 34567,
"entries": 5432,
"hit_rate": 97.20
},
"autoadd": {
"success": 42,
"failed": 3
},
"ratelimit": {
"triggered": 156,
"autobanned": 23
},
"challenge": {
"issued": 1000,
"passed": 950,
"failed": 50
}
}
Описание полей
| Поле | Описание |
|---|---|
version |
Версия модуля |
uptime_seconds |
Секунды с момента загрузки модуля |
requests.checked |
Всего обработанных запросов |
requests.allowed |
Запросы, которые прошли |
requests.blocked |
Запросы, которые были заблокированы |
requests.errors |
Ошибки поиска набора nft |
cache.hits |
Попадания в кэш (избежаны вызовы ядра) |
cache.misses |
Промахи кэша (требуются вызовы ядра) |
cache.entries |
Текущие записи в кэше |
cache.hit_rate |
Процент попадания |
autoadd.success |
Успешные добавления ловушек для меда |
autoadd.failed |
Неудачные добавления ловушек для меда |
ratelimit.triggered |
Нарушения ограничения скорости |
ratelimit.autobanned |
IP, автоматически добавленные в черный список |
challenge.issued |
Страницы задач, обслуженные |
challenge.passed |
Задачи, успешно решенные |
challenge.failed |
Ошибки задач |
| ## |
🏗️ Архитектура
┌─────────────────────────────────────────────────────────────────────┐
│ ПОТОК ЗАПРОСОВ │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Входящий запрос │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Проверка │──── Превышен? ────▶ 429 + Авто-бан │
│ │ ограничения │ │
│ └───────┬───────┘ │
│ │ ОК │
│ ▼ │
│ ┌───────────────┐ │
│ │ Проверка │──── Нет куки? ────▶ Обслужить JS задачу │
│ │ задачи │ │
│ └───────┬───────┘ │
│ │ Пройдено │
│ ▼ │
│ ┌───────────────┐ ┌─────────────┐ │
│ │ Проверка кэша│────▶│ ПОПАДАНИЕ │────▶ Использовать кэшированный результат │
│ └───────┬───────┘ └─────────────┘ │
│ │ ПРОМАХ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Запрос к nft │──── Контекст libnftables, локальный для потока │
│ │ (ядро) │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Сохранить в кэш│ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Решение │──── Совпадение в черном списке? ────▶ Блокировать (403/444) │
│ │ │──── Промах в белом списке? ────▶ Блокировать (403/444) │
│ └───────┬───────┘ │
│ │ Разрешить │
│ ▼ │
│ ┌───────────────┐ │
│ │ Проверка │──── Совпадение местоположения? ────▶ Добавить в набор nft │
│ │ ловушки │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ Продолжить к │
│ Обработчику контента │
│ │
├─────────────────────────────────────────────────────────────────────┤
│ ОБЩАЯ ПАМЯТЬ │
│ ┌────────────────┬─────────────────┬─────────────────────────────┐ │
│ │ Статистика │ Кэш LRU │ Ведра ограничения скорости │ │
│ │ (счетчики) │ (IP → Результат) │ (IP → Счетчик запросов) │ │
│ └────────────────┴─────────────────┴─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Расположение памяти
| Компонент | Местоположение | Назначение |
|---|---|---|
| Контекст libnftables | Локальный для потока | Контекст на рабочий процесс для избежания блокировок |
| Кэш поиска | Общая память | Кэш LRU сопоставлений IP→результат |
| Ведра ограничения скорости | Общая память | Счетчики запросов для каждого IP |
| Статистика | Общая память | Атомарные счетчики для метрик |
| ## |
📚 Примеры
Пример 1: Базовый черный список
# Создать таблицу и набор nft
sudo nft add table ip filter
sudo nft add set ip filter blacklist '{ type ipv4_addr; }'
sudo nft add element ip filter blacklist '{ 1.2.3.4 }'
server {
listen 80;
nftset_blacklist filter:blacklist;
location / {
root /var/www/html;
}
}
Пример 2: API с ограничением скорости
server {
listen 80;
# Строгое ограничение скорости для API
nftset_ratelimit rate=100 window=1m autoban=filter:api_banned ban_time=3600;
# Разрешить только известным партнерам
nftset_whitelist filter:api_partners;
nftset_status 401;
location /api/ {
proxy_pass http://backend;
}
}
Пример 3: Полный стек безопасности
server {
listen 80 default_server;
# Уровень 1: Известные угрозы
nftset_blacklist filter:malware_ips filter:tor_exits filter:datacenter_ranges;
nftset_status 444;
nftset_cache_ttl 5m;
# Уровень 2: Ограничение скорости
nftset_ratelimit rate=60 window=1m autoban=filter:ratelimited ban_time=1800;
# Уровень 3: Задача для ботов
nftset_challenge on;
nftset_challenge_difficulty 2;
# Реальный контент
location / {
root /var/www/html;
}
# Ловушки для меда - возвращают 404 (по умолчанию), чтобы выглядеть как отсутствующие файлы
location ~ ^/(wp-admin|phpmyadmin|admin)\.php$ {
nftset_autoadd filter:honeypot timeout=86400;
}
# Мониторинг
location = /metrics {
nftset_metrics;
allow 10.0.0.0/8;
deny all;
}
}
Пример 4: Тестирование в режиме пробного запуска
server {
listen 80;
# Тестирование новых правил без блокировки
nftset_blacklist filter:new_threat_list;
nftset_dryrun on;
location / {
root /var/www/html;
}
}
Проверьте журналы:
tail -f /var/log/nginx/error.log | grep "DRYRUN"
Пример 5: Белый список CIDR (диапазоны сети)
# Создать интервальный набор для диапазонов CIDR
sudo nft add table ip filter
sudo nft add set ip filter trusted '{ type ipv4_addr; flags interval; }'
sudo nft add element ip filter trusted '{ 192.168.1.0/24, 10.0.0.0/8 }'
# Версия для IPv6
sudo nft add table ip6 filter
sudo nft add set ip6 filter trusted6 '{ type ipv6_addr; flags interval; }'
sudo nft add element ip6 filter trusted6 '{ 2001:db8::/32 }'
server {
listen 80;
# Белый список целых сетей
nftset_whitelist filter:trusted;
location / {
root /var/www/html;
}
}
🔧 Устранение неполадок
Модуль не загружается
nginx: [emerg] dlopen() failed
Решение: Убедитесь, что NGINX был собран с --with-compat, и модуль был собран для той же версии NGINX.
Набор nft не найден
nftset: set 'filter:myset' does not exist
Решение: Создайте таблицу nft и набор перед запуском NGINX:
sudo nft add table ip filter
sudo nft add set ip filter myset '{ type ipv4_addr; }'
Совет: Список доступных наборов:
nft list sets
Доступ запрещен
nftset: kernel error
Решение: Рабочий процесс NGINX нуждается в праве CAP_NET_ADMIN:
sudo setcap cap_net_admin+ep /usr/sbin/nginx
Отказы SELinux (RHEL/CentOS/AlmaLinux)
SELinux is preventing /usr/sbin/nginx from using netlink_netfilter_socket
Решение: Установите включенный модуль политики SELinux:
cd selinux/
sudo ./install.sh
Или вручную:
# Проверить
semodule -l | grep nginx_nftset
Политика позволяет httpd_t (домен SELinux NGINX) использовать сокеты netlink_netfilter, необходимые для libnftables.
Высокое использование памяти
Решение: Уменьшите TTL кэша или ограничьте размер кэша в конфигурации общей памяти.
Ограничение скорости не работает
Решение: Убедитесь, что набор nft для авто-бана существует и поддерживает таймаут:
sudo nft add table ip filter
sudo nft add set ip filter ratelimited '{ type ipv4_addr; flags timeout; timeout 1h; }'
Журнал показывает "matched=table:setname", но IP не в наборе nft
Это ожидаемое поведение. Модуль сообщает то, что он увидел в момент запроса. Если вы позже проверите набор nft и не найдете IP:
-
Истечение времени: IP был добавлен с таймаутом и с тех пор истек
# Проверьте флаги набора nft list set ip filter setname # Ищите "flags timeout" в выводе -
Кэш модуля: Модуль кэширует результаты поиска (по умолчанию 60s). Недавно удаленный IP может все еще отображаться как "совпадающий"
# Временно отключите кэш для отладки (не для производства!) nftset_cache_ttl 0; -
Запись была удалена: fail2ban, скрипты или ручные команды могли удалить ее
-
Проблема с конфигурацией ловушки: Если вы используете ловушки для меда с
nftset_autoadd, законные боты могли активировать ловушки. Убедитесь, что ваши пути ловушек не пересекаются с законными путями ботов (например, карты сайта, robots.txt). Используйтеrobots.txt, чтобы исключить пути ловушек из индексации.
autoadd не работает с ошибкой таймаута
Это означает, что вы используете timeout=N в nftset_autoadd, но набор был создан без поддержки таймаута.
Решение: Воссоздайте набор nft с поддержкой таймаута:
# Удалите и воссоздайте с флагом таймаута
sudo nft delete set ip filter honeypot
sudo nft add set ip filter honeypot '{ type ipv4_addr; flags timeout; timeout 1d; }'
🔄 Миграция с ipset-access
Если вы мигрируете с более старого ngx_http_ipset_access_module, выполните следующие шаги:
1. Преобразуйте ipset в наборы nft
# Старый ipset
ipset create bad_guys hash:ip timeout 86400
# Новый эквивалент набора nft
nft add table ip filter
nft add set ip filter bad_guys '{ type ipv4_addr; flags timeout; timeout 1d; }'
# Для диапазонов CIDR (hash:net → флаг interval)
# Старый: ipset create networks hash:net
# Новый:
nft add set ip filter networks '{ type ipv4_addr; flags interval; }'
2. Обновите конфигурацию NGINX
| Старый (ipset) | Новый (nftset) |
|---|---|
ipset_blacklist bad_guys; |
nftset_blacklist filter:bad_guys; |
ipset_whitelist trusted; |
nftset_whitelist filter:trusted; |
ipset_autoadd honeypot timeout=3600; |
nftset_autoadd filter:honeypot timeout=3600; |
ipset_ratelimit rate=100 autoban=ratelimited; |
nftset_ratelimit rate=100 autoban=filter:ratelimited; |
ipset_challenge on; |
nftset_challenge on; |
ipset_challenge_difficulty 3; |
nftset_challenge_difficulty 3; |
ipset_dryrun on; |
nftset_dryrun on; |
ipset_fail_open on; |
nftset_fail_open on; |
ipset_cache_ttl 60s; |
nftset_cache_ttl 60s; |
ipset_status 403; |
nftset_status 403; |
ipset_stats; |
nftset_stats; |
ipset_metrics; |
nftset_metrics; |
$ipset_result |
$nftset_result |
$ipset_matched_set |
$nftset_matched_set |
3. Обновите форматы журналов
# Старый
log_format security '... ipset_result="$ipset_result" matched_set="$ipset_matched_set"';
# Новый
log_format security '... nftset_result="$nftset_result" matched_set="$nftset_matched_set"';
4. Обновите запросы Prometheus/Grafana
| Старая метрика | Новая метрика |
|---|---|
nginx_ipset_requests_total |
nginx_nftset_requests_total |
nginx_ipset_cache_total |
nginx_nftset_cache_total |
nginx_ipset_cache_entries |
nginx_nftset_cache_entries |
nginx_ipset_autoadd_total |
nginx_nftset_autoadd_total |
nginx_ipset_ratelimit_total |
nginx_nftset_ratelimit_total |
nginx_ipset_challenge_total |
nginx_nftset_challenge_total |
nginx_ipset_uptime_seconds |
nginx_nftset_uptime_seconds |
5. Ключевые различия
| Функция | ipset-access | nftset-access |
|---|---|---|
| Бэкенд | libipset (ядро ipset) | libnftables (nftables) |
| Формат набора | setname |
table:setname |
| CIDR наборы | тип hash:net |
флаг flags interval |
| Семейство | Указано в типе набора | Автоопределяется по IP клиента |
| firewalld | только бэкенд iptables | совместим с бэкендом nftables |
Почему мигрировать?
- Совместимость с RHEL 9/Rocky 9: firewalld по умолчанию использует бэкенд nftables
- Поддержка современного ядра: nftables — это будущее брандмауэра Linux
- Единое управление: Используйте команды
nftкак для брандмауэра, так и для контроля доступа - Лучшая поддержка CIDR: Интервальные наборы эффективно обрабатывают диапазоны сети
📋 Требования
- NGINX ≥ 1.22 (собран с
--with-compat) - Ядро Linux с поддержкой nftables
- Библиотека libnftables и заголовки разработки
- Привилегии:
CAP_NET_ADMINдля операций с nftables
📜 Лицензия
Это программное обеспечение является собственностью. Все права защищены.
Доступно исключительно через GetPageSpeed Premium Repository.
👤 Автор
Данила Верши́нин GetPageSpeed LLC
🆘 Поддержка
- Ловушка для меда v2.0 Использование nftset-access для автоматического бана ботов
- Поддержка: Доступна для премиум подписчиков
- Контакт: GetPageSpeed Support
Модуль доступа NGINX NFTSet
Премиум модуль NGINX от GetPageSpeed LLC
www.getpagespeed.com