ipset-access: Блокировка IP с нулевой задержкой с использованием ipset ядра Linux (v2)
Требуется план 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-ipset-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-ipset-access
Включите модуль, добавив следующее в начало файла /etc/nginx/nginx.conf:
load_module modules/ngx_http_ipset_access.so;
Этот документ описывает nginx-module-ipset-access v2.0.9, выпущенный 20 декабря 2025 года.
Корпоративный уровень контроля доступа на основе IP для NGINX с использованием Linux ipset. Блокируйте угрозы, ограничивайте злоумышленников, проверяйте ботов и защищайте свою инфраструктуру.
⚠️ Коммерческое ПО Это закрытый премиум модуль, доступный исключительно через GetPageSpeed Repository.
✨ Особенности
Основные функции
| Функция | Описание |
|---|---|
| Белый/черный списки | Разрешить или запретить на основе членства в ipset |
| Несколько ipset | Проверка по нескольким ipset в одной директиве |
| Живые обновления | Изменение ipset без перезагрузки NGINX |
| Пользовательские коды состояния | Возврат любого HTTP статуса при блокировке |
Функции производительности
| Функция | Описание |
|---|---|
| Сессии на поток | Локальные для потока сессии libipset устраняют конкуренцию за блокировки |
| Кэш LRU | Кэш в общей памяти с настраиваемым временем жизни |
| Коэффициенты попадания в кэш | Обычно более 95% коэффициент попадания снижает вызовы ядра |
Функции безопасности
| Функция | Описание |
|---|---|
| Ограничение скорости | Ограничение запросов на IP с настраиваемыми окнами |
| Авто-блокировка | Автоматическая блокировка нарушителей ограничений скорости |
| JS Challenge | Задача на доказательство работы останавливает автоматизированные боты |
| Ловушки для меда | Авто-блокировка IP, попадающих на ловушки URL |
| Таймаут входа | Авто-истечение записей черного списка |
Операционные функции
| Функция | Описание |
|---|---|
| Режим пробного запуска | Тестирование конфигурации без блокировки |
| Fail-open/close | Управление поведением при ошибках ipset |
| Метрики Prometheus | Нативная конечная точка /metrics для Grafana |
| JSON статистика | Подробный API статистики |
| Переменные NGINX | $ipset_result и $ipset_matched_set |
🚀 Быстрый старт
1. Создайте ipsets
## Создать черный список
sudo ipset create bad_guys hash:ip timeout 86400
## Создать список блокировок по ограничению скорости
sudo ipset create ratelimited hash:ip timeout 1800
## Создать список ловушек для меда
sudo ipset create honeypot hash:ip timeout 86400
2. Настройте NGINX
load_module modules/ngx_http_ipset_access_module.so;
http {
server {
listen 80;
# Блокировка известных плохих IP
ipset_blacklist bad_guys;
# Ограничение скорости: 100 запросов в минуту
ipset_ratelimit rate=100 window=60s autoban=ratelimited;
# Ваш контент
location / {
root /var/www/html;
}
# Ловушка для меда - по умолчанию возвращает 404
location /wp-admin.php {
ipset_autoadd honeypot timeout=86400;
}
# Конечная точка метрик
location /metrics {
ipset_metrics;
allow 127.0.0.1;
deny all;
}
}
}
3. Протестируйте и перезагрузите
sudo nginx -t && sudo nginx -s reload
📦 Установка
Этот модуль доступен исключительно через GetPageSpeed Premium Repository.
Шаг 1: Подпишитесь на репозиторий GetPageSpeed
Посетите Подписка на репозиторий GetPageSpeed для получения доступа.
Шаг 2: Установите репозиторий
## RHEL/CentOS/Rocky/Alma Linux 8+
sudo dnf install https://extras.getpagespeed.com/release-latest.rpm
Шаг 3: Установите модуль
sudo dnf install nginx-module-ipset-access
Шаг 4: Включите модуль
Добавьте в /etc/nginx/nginx.conf перед любыми блоками http {}:
load_module modules/ngx_http_ipset_access_module.so;
Шаг 5: Перезагрузите NGINX
sudo nginx -t && sudo systemctl reload nginx
📖 Справочник по конфигурации
Контроль доступа
ipset_blacklist set1 [set2 ...]
Контекст: http, server
По умолчанию: —
Блокирует запросы, если IP клиента присутствует в любом из перечисленных ipset. Несколько ipset проверяются по порядку, пока не будет найдено совпадение.
## Один набор
ipset_blacklist bad_guys;
## Несколько наборов (логика ИЛИ - заблокировано, если в ЛЮБОМ наборе)
ipset_blacklist spammers hackers tor_exits;
## Отключить
ipset_blacklist off;
ipset_whitelist set1 [set2 ...]
Контекст: http, server
По умолчанию: —
Разрешает запросы только если IP клиента присутствует хотя бы в одном из перечисленных ipset. Все остальные IP отклоняются.
## Разрешить только доверенные IP
ipset_whitelist trusted_partners office_ips;
Важно: IP в белом списке обходят все ограничения модуля, включая:
- Ограничение скорости (ipset_ratelimit)
- Задачи JavaScript (ipset_challenge)
Это полезно для IP администраторов, которые не должны подлежать ограничениям по скорости или задачам:
## IP администраторов обходят ограничения по скорости и задачи
ipset_whitelist admin_ips;
ipset_ratelimit rate=100 window=1m autoban=ratelimited ban_time=1800;
ipset_challenge on;
ipset_status code
Контекст: http, server
По умолчанию: 403
HTTP код состояния, возвращаемый при блокировке запроса.
ipset_status 403; # Запрещено (по умолчанию)
ipset_status 444; # Закрыть соединение без ответа (особый случай NGINX)
ipset_status 429; # Слишком много запросов
ipset_status 503; # Сервис недоступен
Кэширование и производительность
ipset_cache_ttl time
Контекст: http, server
По умолчанию: 60s
Как долго кэшировать результаты поиска ipset. Кэшированные результаты избегают повторных вызовов ядра для одного и того же IP.
ipset_cache_ttl 30s; # 30 секунд
ipset_cache_ttl 5m; # 5 минут
ipset_cache_ttl 1h; # 1 час
Примечание по отладке: Если вы удалите IP из ipset, но модуль все еще сообщает о том, что он "совпадает", это из-за кэширования. Кэшированный результат истечет после установленного TTL. Для немедленного эффекта во время тестирования вы можете временно установить ipset_cache_ttl 0;, чтобы отключить кэширование (не рекомендуется для производства из-за влияния на производительность).
Влияние на производительность:
- Более высокий TTL = Лучшая производительность, но медленнее отражает изменения ipset
- Более низкий TTL = Более отзывчивый к изменениям ipset, но больше вызовов ядра
- Рекомендуется: 30s до 5m для большинства случаев использования
ipset_fail_open on|off
Контекст: http, server
По умолчанию: off
Управляет поведением, когда поиск ipset завершается неудачей (например, набор не существует).
ipset_fail_open off; # Запретить при ошибке (безопасно, по умолчанию)
ipset_fail_open on; # Разрешить при ошибке (доступно, но рискованно)
ipset_dryrun on|off
Контекст: http, server
По умолчанию: off
При включении регистрирует, что было бы заблокировано, но на самом деле не блокирует. Идеально для тестирования новых правил в производстве.
ipset_dryrun on; # Логировать, но не блокировать
Проверьте логи на наличие сообщений, таких как:
ipset: DRYRUN would block 1.2.3.4 (matched: bad_guys)
Важно: При использовании переменных $ipset_result и $ipset_matched_set в режиме пробного запуска эти значения отражают состояние на момент запроса, а не текущее состояние ipset. Если вы позже проверите ipset вручную и не найдете IP, возможные причины включают:
- Истечение времени ожидания: IP был добавлен с таймаутом (например,
timeout=86400) и с тех пор истек - Задержка кэша: Модуль кэширует результаты поиска (по умолчанию 60s). Запись, удаленная из ipset, может все еще отображаться как "совпадающая", пока кэш не истечет
- Ручное удаление: Кто-то или что-то (fail2ban, скрипты) удалило запись
Это ожидаемое поведение — пробный запуск показывает вам именно то, что увидит производство в момент запроса.
Ограничение скорости
ipset_ratelimit parameters
Контекст: http, server
По умолчанию: —
Ограничивает запросы на IP в пределах временного окна. Может автоматически добавлять нарушителей в ipset.
Параметры:
| Параметр | Обязательный | Описание |
|---|---|---|
rate=N |
Да | Максимальное количество запросов за окно |
window=TIME |
Нет | Временное окно (по умолчанию: 60s) |
autoban=SET |
Нет | ipset для добавления нарушителей |
ban_time=N |
Нет | Секунды до авто-истечения (по умолчанию: 3600) |
Примеры:
## Базовый: 100 запросов в минуту
ipset_ratelimit rate=100;
## С пользовательским окном: 1000 запросов в час
ipset_ratelimit rate=1000 window=1h;
## С авто-блокировкой: Добавить нарушителей в ipset на 30 минут
ipset_ratelimit rate=60 window=1m autoban=ratelimited ban_time=1800;
## Строгая защита API
ipset_ratelimit rate=10 window=1s autoban=api_abusers ban_time=3600;
Как это работает:
1. Каждому IP присваивается счетчик запросов и время начала окна
2. Счетчик увеличивается с каждым запросом
3. Когда окно истекает, счетчик сбрасывается
4. Если счетчик превышает rate, возвращается 429 Too Many Requests
5. Если установлен autoban, IP добавляется в указанный ipset
Примечание: Состояние ограничения скорости хранится в общей памяти и сохраняется при перезапуске рабочих процессов.
Задача JavaScript
ipset_challenge on|off
Контекст: http, server
По умолчанию: off
Включает режим задачи JavaScript. Браузеры должны решить задачу на доказательство работы, чтобы получить доступ к сайту. Эффективно против автоматизированных ботов и сканеров.
ipset_challenge on;
Как это работает:
1. Первый запрос получает страницу задачи (HTTP 503)
2. Браузер выполняет JavaScript, который решает задачу хеширования
3. Решение сохраняется в cookie (_ipset_verified)
4. Последующие запросы с действительной cookie проходят
5. Cookie истекает через 24 часа
ipset_challenge_difficulty level
Контекст: http, server
По умолчанию: 2
Управляет сложностью задачи (1-8). Более высокая = больше времени на решение.
| Уровень | Приблизительное время решения |
|---|---|
| 1 | ~100ms |
| 2 | ~500ms (по умолчанию) |
| 3 | ~1 секунда |
| 4 | ~2 секунды |
| 5 | ~5 секунд |
| 6+ | ~10+ секунд |
ipset_challenge on;
ipset_challenge_difficulty 3; # ~1 секунда времени решения
Особенности страницы задачи: - Современный, отзывчивый дизайн - Анимированный индикатор загрузки - Обратная связь о прогрессе - Авто-перенаправление при успехе - Без внешних зависимостей
Авто-добавление ловушки для меда
ipset_autoadd setname [timeout=seconds] [status=code]
Контекст: server, location
По умолчанию: —
Автоматически добавляет IP клиента в указанный ipset, когда доступ к локации осуществляется и возвращается HTTP код состояния. Идеально для ловушек для меда.
Параметры:
| Параметр | Обязательный | Описание |
|---|---|---|
| setname | Да | Имя целевого ipset |
timeout=N |
Нет | Таймаут записи в секундах |
status=N |
Нет | HTTP код состояния для возврата (по умолчанию: 404) |
Примеры:
## Базовый: Добавить в набор ловушки для меда и вернуть 404 (по умолчанию)
location /config.php {
ipset_autoadd honeypot;
}
## С таймаутом: Авто-истечение через 24 часа
location /wp-admin.php {
ipset_autoadd scanners timeout=86400;
}
## Вернуть 403 Запрещено вместо 404
location /admin.php {
ipset_autoadd honeypot timeout=86400 status=403;
}
## Вернуть 429 Слишком много запросов
location /api/hack {
ipset_autoadd abusers timeout=3600 status=429;
}
Общие пути ловушек для меда:
## Ловушки WordPress - вернуть 404, чтобы выглядеть как отсутствующий файл
location ~ ^/(wp-admin\.php|wp-login\.php|xmlrpc\.php)$ {
ipset_autoadd honeypot timeout=86400;
}
## Ловушки конфигурационных файлов - вернуть 403, чтобы симулировать запрещенный доступ
location ~ ^/(\\.env|config\\.php|phpinfo\\.php)$ {
ipset_autoadd honeypot timeout=86400 status=403;
}
## Ловушки для оболочки/эксплойтов - серьезные, блокировать на 1 неделю
location ~ ^/(shell|cmd|eval|exec)\\.php$ {
ipset_autoadd malicious timeout=604800 status=403;
}
Примечание: Когда IP автоматически добавляется, модуль немедленно возвращает указанный HTTP код состояния (по умолчанию 404), предотвращая дальнейшую обработку запроса. Также отключается keep-alive соединения, чтобы предотвратить дальнейшие запросы по тому же соединению.
Наблюдаемость
ipset_stats
Контекст: location
По умолчанию: —
Включает конечную точку статистики JSON.
location = /_stats {
ipset_stats;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
Смотрите JSON Stats API для формата ответа.
ipset_metrics
Контекст: location
По умолчанию: —
Включает конечную точку метрик Prometheus.
location = /metrics {
ipset_metrics;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
Смотрите Prometheus Metrics для доступных метрик.
📝 Переменные NGINX
Модуль предоставляет две переменные для использования в логировании, заголовках или условиях.
$ipset_result
Решение о доступе, принятое для этого запроса.
| Значение | Описание |
|---|---|
allow |
Запрос разрешен |
deny |
Запрос заблокирован |
dryrun |
Было бы заблокировано (режим пробного запуска) |
ratelimited |
Превышен лимит скорости |
challenged |
Страница задачи обслужена |
$ipset_matched_set
Имя ipset, которое совпало (если есть). Пусто, если совпадений нет.
Примечание: Эта переменная отражает состояние совпадения в момент запроса, а не текущее состояние ipset. Если вы позже проверите ipset вручную и не найдете IP: - Запись могла истечь (ipset поддерживает таймауты для каждой записи) - Кэш модуля (по умолчанию 60s) может показывать недавно удаленную запись как все еще совпадающую - Что-то могло удалить запись после обработки запроса
Примеры использования
Пользовательский журнал доступа:
log_format security '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'ipset_result="$ipset_result" '
'matched_set="$ipset_matched_set"';
access_log /var/log/nginx/security.log security;
Добавить заголовки для отладки:
add_header X-IPSet-Result $ipset_result always;
add_header X-IPSet-Matched $ipset_matched_set always;
Условное логирование:
## Логировать только заблокированные запросы
map $ipset_result $loggable {
"deny" 1;
default 0;
}
access_log /var/log/nginx/blocked.log combined if=$loggable;
📊 Метрики Prometheus
Конечная точка /metrics возвращает метрики в формате экспозиции Prometheus.
Доступные метрики
## HELP nginx_ipset_requests_total Всего обработанных запросов
## TYPE nginx_ipset_requests_total counter
nginx_ipset_requests_total{result="checked"} 1234567
nginx_ipset_requests_total{result="allowed"} 1234000
nginx_ipset_requests_total{result="blocked"} 500
nginx_ipset_requests_total{result="error"} 67
## HELP nginx_ipset_cache_total Операции кэша
## TYPE nginx_ipset_cache_total counter
nginx_ipset_cache_total{result="hit"} 1200000
nginx_ipset_cache_total{result="miss"} 34567
## HELP nginx_ipset_cache_entries Текущие записи кэша
## TYPE nginx_ipset_cache_entries gauge
nginx_ipset_cache_entries 5432
## HELP nginx_ipset_autoadd_total Операции авто-добавления
## TYPE nginx_ipset_autoadd_total counter
nginx_ipset_autoadd_total{result="success"} 42
nginx_ipset_autoadd_total{result="failed"} 3
## HELP nginx_ipset_ratelimit_total События ограничения скорости
## TYPE nginx_ipset_ratelimit_total counter
nginx_ipset_ratelimit_total{action="triggered"} 156
nginx_ipset_ratelimit_total{action="autobanned"} 23
## HELP nginx_ipset_challenge_total События задачи
## TYPE nginx_ipset_challenge_total counter
nginx_ipset_challenge_total{result="issued"} 1000
nginx_ipset_challenge_total{result="passed"} 950
nginx_ipset_challenge_total{result="failed"} 50
## HELP nginx_ipset_uptime_seconds Время работы модуля
## TYPE nginx_ipset_uptime_seconds gauge
nginx_ipset_uptime_seconds 86400
Запросы для панели Grafana
Скорость запросов по результату:
rate(nginx_ipset_requests_total[5m])
Коэффициент блокировок:
rate(nginx_ipset_requests_total{result="blocked"}[5m])
Коэффициент попадания в кэш:
rate(nginx_ipset_cache_total{result="hit"}[5m]) /
(rate(nginx_ipset_cache_total{result="hit"}[5m]) + rate(nginx_ipset_cache_total{result="miss"}[5m]))
Триггеры ограничения скорости в минуту:
rate(nginx_ipset_ratelimit_total{action="triggered"}[1m]) * 60
📈 JSON Stats API
Конечная точка /_stats возвращает подробную статистику в формате JSON.
Формат ответа
{
"version": "2.0.7",
"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 |
Ошибки поиска ipset |
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 + Авто-блокировка │
│ │ ограничения │ │
│ └───────┬───────┘ │
│ │ ОК │
│ ▼ │
│ ┌───────────────┐ │
│ │ Проверка │──── Нет cookie? ────▶ Обслужить страницу задачи │
│ │ задачи │ │
│ └───────┬───────┘ │
│ │ Пройдено │
│ ▼ │
│ ┌───────────────┐ ┌─────────────┐ │
│ │ Проверка кэша│────▶│ ПОПАДАНИЕ │────▶ Использовать кэшированный результат │
│ └───────┬───────┘ └─────────────┘ │
│ │ ПРОМАХ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Запрос ipset │──── Потоковая локальная сессия libipset │
│ │ (ядро) │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Сохранить в кэш│ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Решение │──── Совпадение с черным списком? ────▶ Заблокировать (403/444) │
│ │ │──── Промах в белом списке? ────▶ Заблокировать (403/444) │
│ └───────┬───────┘ │
│ │ Разрешить │
│ ▼ │
│ ┌───────────────┐ │
│ │ Проверка │──── Совпадение с локацией? ────▶ Добавить в ipset │
│ │ ловушки │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ Продолжить к │
│ Обработчику контента │
│ │
├─────────────────────────────────────────────────────────────────────┤
│ ОБЩАЯ ПАМЯТЬ │
│ ┌────────────────┬─────────────────┬─────────────────────────────┐ │
│ │ Статистика │ Кэш LRU │ Ведра ограничения скорости │ │
│ │ (счетчики) │ (IP → Результат) │ (IP → Счетчик запросов) │ │
│ └────────────────┴─────────────────┴─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Макет памяти
| Компонент | Местоположение | Назначение |
|---|---|---|
| Сессия libipset | Локальная для потока | Сессия на каждый рабочий процесс для избежания блокировок |
| Кэш поиска | Общая память | Кэш LRU сопоставлений IP→результат |
| Ведра ограничения скорости | Общая память | Счетчики запросов на IP |
| Статистика | Общая память | Атомарные счетчики для метрик |
📚 Примеры
Пример 1: Базовый черный список
## Создать ipset
sudo ipset create blacklist hash:ip
sudo ipset add blacklist 1.2.3.4
server {
listen 80;
ipset_blacklist blacklist;
location / {
root /var/www/html;
}
}
Пример 2: API с ограничением скорости
server {
listen 80;
# Строгое ограничение скорости для API
ipset_ratelimit rate=100 window=1m autoban=api_banned ban_time=3600;
# Разрешить только известным партнерам
ipset_whitelist api_partners;
ipset_status 401;
location /api/ {
proxy_pass http://backend;
}
}
Пример 3: Полный стек безопасности
server {
listen 80 default_server;
# Уровень 1: Известные угрозы
ipset_blacklist malware_ips tor_exits datacenter_ranges;
ipset_status 444;
ipset_cache_ttl 5m;
# Уровень 2: Ограничение скорости
ipset_ratelimit rate=60 window=1m autoban=ratelimited ban_time=1800;
# Уровень 3: Задача для ботов
ipset_challenge on;
ipset_challenge_difficulty 2;
# Реальный контент
location / {
root /var/www/html;
}
# Ловушки для меда - вернуть 404 (по умолчанию), чтобы выглядеть как отсутствующие файлы
location ~ ^/(wp-admin|phpmyadmin|admin)\.php$ {
ipset_autoadd honeypot timeout=86400;
}
# Мониторинг
location = /metrics {
ipset_metrics;
allow 10.0.0.0/8;
deny all;
}
}
Пример 4: Тестирование в режиме пробного запуска
server {
listen 80;
# Тестировать новые правила без блокировки
ipset_blacklist new_threat_list;
ipset_dryrun on;
location / {
root /var/www/html;
}
}
Проверьте логи:
tail -f /var/log/nginx/error.log | grep "DRYRUN"
🔧 Устранение неполадок
Модуль не загружается
nginx: [emerg] dlopen() failed
Решение: Убедитесь, что NGINX был собран с --with-compat, и модуль был собран против той же версии NGINX.
ipset не найден
ipset: INVALID_SETNAME
Решение: Создайте ipset перед запуском NGINX:
sudo ipset create myset hash:ip
Доступ запрещен
ipset: kernel error
Решение: Рабочий процесс NGINX нуждается в праве CAP_NET_ADMIN:
sudo setcap cap_net_admin+ep /usr/sbin/nginx
Отказы SELinux (RHEL/CentOS/AlmaLinux)
SELinux предотвращает доступ /usr/sbin/nginx к getattr на netlink_netfilter_socket
Решение: Установите включенный модуль политики SELinux:
cd selinux/
sudo ./install.sh
Или вручную:
## Проверить
semodule -l | grep nginx_ipset
Политика позволяет httpd_t (SELinux домен NGINX) использовать сокеты netlink_netfilter, необходимые для libipset.
Высокое использование памяти
Решение: Уменьшите TTL кэша или ограничьте размер кэша в конфигурации общей памяти.
Ограничение скорости не работает
Решение: Убедитесь, что ipset для авто-блокировки существует и поддерживает таймаут:
sudo ipset create ratelimited hash:ip timeout 3600
Лог показывает "matched=setname", но IP не в ipset
Это ожидаемое поведение. Модуль сообщает то, что он увидел в момент запроса. Если вы позже проверите ipset вручную и не найдете IP:
-
Истечение времени ожидания: IP был добавлен с таймаутом и с тех пор истек
# Проверьте, поддерживает ли набор таймауты ipset list setname | head -5 # Ищите "timeout" в заголовке -
Кэш модуля: Модуль кэширует результаты поиска (по умолчанию 60s). Недавно удаленный IP может все еще отображаться как "совпадающий"
# Временно отключите кэш для отладки (не для производства!) ipset_cache_ttl 0; -
Запись была удалена: fail2ban, скрипты или ручные команды могли удалить ее
-
Проблема с конфигурацией ловушки: Если вы используете ловушки для меда с
ipset_autoadd, законные боты могли активировать ловушки. Проверьте, чтобы ваши ловушки не пересекались с законными путями ботов (такими как карты сайта, robots.txt). Используйтеrobots.txt, чтобы исключить пути ловушек из обхода.
autoadd не удается с "result=4"
Это означает, что вы используете timeout=N в ipset_autoadd, но ipset был создан без поддержки таймаутов.
Решение: Воссоздайте ipset с поддержкой таймаутов:
## Используя ipset напрямую
sudo ipset destroy honeypot4
sudo ipset create honeypot4 hash:ip family inet timeout 86400
## Используя firewall-cmd (RHEL/CentOS/Amazon Linux)
sudo firewall-cmd --permanent --delete-ipset=honeypot4
sudo firewall-cmd --permanent --new-ipset=honeypot4 --type=hash:ip \
--option=family=inet --option=timeout=86400
sudo firewall-cmd --reload
📋 Требования
- NGINX ≥ 1.22 (собран с
--with-compat) - Ядро Linux с поддержкой ipset (модуль nf_tables или xt_set)
- Библиотека libipset и заголовки разработки
- Привилегии:
CAP_NET_ADMINдля операций с ipset
📜 Лицензия
Это программное обеспечение является собственностью. Все права защищены.
Доступно исключительно через GetPageSpeed Premium Repository.
👤 Автор
Данила Верши́нин GetPageSpeed LLC
🆘 Поддержка
- Honeypot v2.0 Использование ipset-access для авто-блокировки ботов
- Поддержка: Доступна для премиум подписчиков
- Контакт: Поддержка GetPageSpeed
Модуль доступа NGINX IPSet
Премиум модуль NGINX от GetPageSpeed LLC
www.getpagespeed.com