ipset-access: Blocage IP à latence zéro utilisant les ipsets du noyau Linux (v2)
Nécessite le plan Pro (ou supérieur) de l'abonnement GetPageSpeed NGINX Extras.
Installation
Vous pouvez installer ce module dans toute distribution basée sur RHEL, y compris, mais sans s'y limiter :
- RedHat Enterprise Linux 7, 8, 9 et 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 et 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
Activez le module en ajoutant ce qui suit en haut de /etc/nginx/nginx.conf :
load_module modules/ngx_http_ipset_access.so;
Ce document décrit nginx-module-ipset-access v2.0.9 publié le 20 décembre 2025.
Contrôle d'accès basé sur l'IP de niveau entreprise pour NGINX utilisant ipset de Linux. Bloquez les menaces, limitez le taux des abus, défiez les bots et protégez votre infrastructure.
⚠️ Logiciel Commercial
Il s'agit d'un module premium à code source fermé disponible exclusivement via le Dépôt GetPageSpeed.
✨ Fonctionnalités
Fonctionnalités principales
| Fonctionnalité | Description |
|---|---|
| Liste blanche/Liste noire | Autoriser ou refuser en fonction de l'appartenance à l'ipset |
| Multiples ipsets | Vérifiez plusieurs ipsets dans une seule directive |
| Mises à jour en direct | Modifiez les ipsets sans recharger NGINX |
| Codes d'état personnalisés | Retournez n'importe quel statut HTTP lors du blocage |
Fonctionnalités de performance
| Fonctionnalité | Description |
|---|---|
| Sessions par fil | Les sessions libipset locales au fil éliminent la contention de verrouillage |
| Cache LRU | Cache en mémoire partagée avec TTL configurable |
| Taux de réussite du cache | Un taux de réussite typiquement supérieur à 95 % réduit les appels au noyau |
Fonctionnalités de sécurité
| Fonctionnalité | Description |
|---|---|
| Limitation de taux | Limitez les requêtes par IP avec des fenêtres configurables |
| Auto-interdiction | Mettez automatiquement sur liste noire les violateurs de la limite de taux |
| Défi JS | Le défi de preuve de travail arrête les bots automatisés |
| Pièges honeypot | Mettez automatiquement sur liste noire les IPs touchant les URL pièges |
| Délai d'entrée | Expiration automatique des entrées de liste noire |
Fonctionnalités opérationnelles
| Fonctionnalité | Description |
|---|---|
| Mode dry-run | Testez la configuration sans bloquer |
| Fail-open/close | Contrôlez le comportement en cas d'erreurs d'ipset |
| Métriques Prometheus | Point de terminaison /metrics natif pour Grafana |
| Statistiques JSON | API de statistiques détaillées |
| Variables NGINX | $ipset_result et $ipset_matched_set |
🚀 Démarrage rapide
1. Créer des ipsets
## Créer une liste noire
sudo ipset create bad_guys hash:ip timeout 86400
## Créer une liste d'interdiction de limitation de taux
sudo ipset create ratelimited hash:ip timeout 1800
## Créer une liste de pièges honeypot
sudo ipset create honeypot hash:ip timeout 86400
2. Configurer NGINX
load_module modules/ngx_http_ipset_access_module.so;
http {
server {
listen 80;
# Bloquer les IPs connues comme mauvaises
ipset_blacklist bad_guys;
# Limitation de taux : 100 requêtes par minute
ipset_ratelimit rate=100 window=60s autoban=ratelimited;
# Votre contenu
location / {
root /var/www/html;
}
# Piège honeypot - retourne 404 par défaut
location /wp-admin.php {
ipset_autoadd honeypot timeout=86400;
}
# Point de terminaison des métriques
location /metrics {
ipset_metrics;
allow 127.0.0.1;
deny all;
}
}
}
3. Tester et recharger
sudo nginx -t && sudo nginx -s reload
📦 Installation
Ce module est disponible exclusivement via le Dépôt Premium GetPageSpeed.
Étape 1 : S'abonner au Dépôt GetPageSpeed
Visitez Abonnement au Dépôt GetPageSpeed pour obtenir l'accès.
Étape 2 : Installer le Dépôt
## RHEL/CentOS/Rocky/Alma Linux 8+
sudo dnf install https://extras.getpagespeed.com/release-latest.rpm
Étape 3 : Installer le Module
sudo dnf install nginx-module-ipset-access
Étape 4 : Activer le Module
Ajoutez à /etc/nginx/nginx.conf avant tout bloc http {} :
load_module modules/ngx_http_ipset_access_module.so;
Étape 5 : Recharger NGINX
sudo nginx -t && sudo systemctl reload nginx
📖 Référence de configuration
Contrôle d'accès
ipset_blacklist set1 [set2 ...]
Contexte : http, server
Par défaut : —
Bloque les requêtes si l'IP client apparaît dans n'importe lequel des ipsets listés. Plusieurs ipsets sont vérifiés dans l'ordre jusqu'à ce qu'une correspondance soit trouvée.
## Ensemble unique
ipset_blacklist bad_guys;
## Ensembles multiples (logique OU - bloqué si dans UN SEUL ensemble)
ipset_blacklist spammers hackers tor_exits;
## Désactiver
ipset_blacklist off;
ipset_whitelist set1 [set2 ...]
Contexte : http, server
Par défaut : —
Autorise les requêtes uniquement si l'IP client apparaît dans au moins un des ipsets listés. Toutes les autres IPs sont rejetées.
## Autoriser uniquement les IPs de confiance
ipset_whitelist trusted_partners office_ips;
Important : Les IPs sur liste blanche contournent toutes les restrictions du module, y compris :
- Limitation de taux (ipset_ratelimit)
- Défis JavaScript (ipset_challenge)
Ceci est utile pour les IPs administratives qui ne devraient pas être soumises à des limites de taux ou à des défis :
## Les IPs administratives contournent la limitation de taux et les défis
ipset_whitelist admin_ips;
ipset_ratelimit rate=100 window=1m autoban=ratelimited ban_time=1800;
ipset_challenge on;
ipset_status code
Contexte : http, server
Par défaut : 403
Code d'état HTTP retourné lorsqu'une requête est bloquée.
ipset_status 403; # Interdit (par défaut)
ipset_status 444; # Fermer la connexion sans réponse (spécial NGINX)
ipset_status 429; # Trop de requêtes
ipset_status 503; # Service indisponible
Mise en cache & Performance
ipset_cache_ttl time
Contexte : http, server
Par défaut : 60s
Combien de temps mettre en cache les résultats de recherche d'ipset. Les résultats mis en cache évitent les appels répétés au noyau pour la même IP.
ipset_cache_ttl 30s; # 30 secondes
ipset_cache_ttl 5m; # 5 minutes
ipset_cache_ttl 1h; # 1 heure
Note de débogage : Si vous retirez une IP d'un ipset mais que le module continue de la signaler comme "correspondante", cela est dû à la mise en cache. Le résultat mis en cache expirera après le TTL configuré. Pour un effet immédiat lors des tests, vous pouvez temporairement définir ipset_cache_ttl 0; pour désactiver la mise en cache (non recommandé pour la production en raison de l'impact sur les performances).
Impact sur les performances :
- TTL plus élevé = Meilleures performances, mais plus lent à refléter les changements d'ipset
- TTL plus bas = Plus réactif aux changements d'ipset, mais plus d'appels au noyau
- Recommandé : 30s à 5m pour la plupart des cas d'utilisation
ipset_fail_open on|off
Contexte : http, server
Par défaut : off
Contrôle le comportement lorsqu'une recherche d'ipset échoue (par exemple, l'ensemble n'existe pas).
ipset_fail_open off; # Refuser en cas d'erreur (sécurisé, par défaut)
ipset_fail_open on; # Autoriser en cas d'erreur (disponible mais risqué)
ipset_dryrun on|off
Contexte : http, server
Par défaut : off
Lorsqu'il est activé, journalise ce qui serait bloqué mais ne bloque pas réellement. Parfait pour tester de nouvelles règles en production.
ipset_dryrun on; # Journaliser mais ne pas bloquer
Vérifiez les journaux pour des messages comme :
ipset: DRYRUN would block 1.2.3.4 (matched: bad_guys)
Important : Lorsque vous utilisez les variables $ipset_result et $ipset_matched_set avec le mode dryrun, ces valeurs reflètent l'état à un moment donné lorsque la requête a été traitée - pas l'état actuel de l'ipset. Si vous vérifiez l'ipset manuellement plus tard et ne trouvez pas l'IP, les raisons possibles incluent :
- Expiration du délai : L'IP a été ajoutée avec un délai (par exemple,
timeout=86400) et a depuis expiré - Retard de cache : Le module met en cache les résultats de recherche (par défaut 60s). Une entrée retirée de l'ipset peut encore apparaître comme "correspondante" jusqu'à ce que le cache expire
- Retrait manuel : Quelqu'un ou quelque chose (fail2ban, scripts) a retiré l'entrée
C'est un comportement attendu - le dryrun vous montre exactement ce que la production verrait au moment de la requête.
Limitation de taux
ipset_ratelimit parameters
Contexte : http, server
Par défaut : —
Limite les requêtes par IP dans une fenêtre temporelle. Peut ajouter automatiquement les violateurs à un ipset.
Paramètres :
| Paramètre | Requis | Description |
|---|---|---|
rate=N |
Oui | Maximum de requêtes par fenêtre |
window=TIME |
Non | Fenêtre temporelle (par défaut : 60s) |
autoban=SET |
Non | ipset pour ajouter les violateurs |
ban_time=N |
Non | Secondes jusqu'à expiration automatique (par défaut : 3600) |
Exemples :
## Basique : 100 requêtes par minute
ipset_ratelimit rate=100;
## Avec fenêtre personnalisée : 1000 requêtes par heure
ipset_ratelimit rate=1000 window=1h;
## Avec auto-interdiction : Ajouter les violateurs à l'ipset pendant 30 minutes
ipset_ratelimit rate=60 window=1m autoban=ratelimited ban_time=1800;
## Protection API stricte
ipset_ratelimit rate=10 window=1s autoban=api_abusers ban_time=3600;
Comment ça fonctionne :
1. Chaque IP obtient un compteur de requêtes et un temps de début de fenêtre
2. Le compteur s'incrémente à chaque requête
3. Lorsque la fenêtre expire, le compteur se réinitialise
4. Si le compteur dépasse rate, retourne 429 Trop de requêtes
5. Si autoban est défini, l'IP est ajoutée à l'ipset spécifié
Remarque : L'état de limitation de taux est stocké en mémoire partagée et survit aux redémarrages des travailleurs.
Défi JavaScript
ipset_challenge on|off
Contexte : http, server
Par défaut : off
Active le mode défi JavaScript. Les navigateurs doivent résoudre une énigme de preuve de travail pour accéder au site. Efficace contre les bots automatisés et les scrapers.
ipset_challenge on;
Comment ça fonctionne :
1. La première requête reçoit une page de défi (HTTP 503)
2. Le navigateur exécute JavaScript qui résout une énigme de hachage
3. La solution est stockée dans un cookie (_ipset_verified)
4. Les requêtes suivantes avec un cookie valide passent
5. Le cookie expire après 24 heures
ipset_challenge_difficulty level
Contexte : http, server
Par défaut : 2
Contrôle la difficulté du défi (1-8). Plus élevé = temps de résolution plus long.
| Niveau | Temps de résolution approximatif |
|---|---|
| 1 | ~100ms |
| 2 | ~500ms (par défaut) |
| 3 | ~1 seconde |
| 4 | ~2 secondes |
| 5 | ~5 secondes |
| 6+ | ~10+ secondes |
ipset_challenge on;
ipset_challenge_difficulty 3; # ~1 seconde de temps de résolution
Fonctionnalités de la page de défi : - Design moderne et réactif - Indicateur de chargement animé - Retour d'information sur la progression - Redirection automatique en cas de succès - Pas de dépendances externes
Auto-ajout Honeypot
ipset_autoadd setname [timeout=seconds] [status=code]
Contexte : server, location
Par défaut : —
Ajoute automatiquement l'IP client à l'ipset spécifié lorsque la localisation est accédée et retourne un code d'état HTTP. Parfait pour les pièges honeypot.
Paramètres :
| Paramètre | Requis | Description |
|---|---|---|
| setname | Oui | Nom de l'ipset cible |
timeout=N |
Non | Délai d'entrée en secondes |
status=N |
Non | Code d'état HTTP à retourner (par défaut : 404) |
Exemples :
## Basique : Ajouter au jeu honeypot et retourner 404 (par défaut)
location /config.php {
ipset_autoadd honeypot;
}
## Avec délai : Expiration automatique après 24 heures
location /wp-admin.php {
ipset_autoadd scanners timeout=86400;
}
## Retourner 403 Interdit au lieu de 404
location /admin.php {
ipset_autoadd honeypot timeout=86400 status=403;
}
## Retourner 429 Trop de requêtes
location /api/hack {
ipset_autoadd abusers timeout=3600 status=429;
}
Chemins de piège Honeypot courants :
## Pièges WordPress - retourner 404 pour ressembler à un fichier manquant
location ~ ^/(wp-admin\.php|wp-login\.php|xmlrpc\.php)$ {
ipset_autoadd honeypot timeout=86400;
}
## Pièges de fichiers de configuration - retourner 403 pour simuler un accès interdit
location ~ ^/(\\.env|config\\.php|phpinfo\\.php)$ {
ipset_autoadd honeypot timeout=86400 status=403;
}
## Pièges de shell/exploit - sévère, bloquer pendant 1 semaine
location ~ ^/(shell|cmd|eval|exec)\\.php$ {
ipset_autoadd malicious timeout=604800 status=403;
}
Remarque : Lorsqu'une IP est auto-ajoutée, le module retourne immédiatement le code d'état HTTP spécifié (404 par défaut), empêchant tout traitement ultérieur de la requête. Le keep-alive de la connexion est également désactivé pour éviter d'autres requêtes sur la même connexion.
Observabilité
ipset_stats
Contexte : location
Par défaut : —
Active le point de terminaison de statistiques JSON.
location = /_stats {
ipset_stats;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
Voir API de statistiques JSON pour le format de réponse.
ipset_metrics
Contexte : location
Par défaut : —
Active le point de terminaison des métriques Prometheus.
location = /metrics {
ipset_metrics;
allow 127.0.0.1;
allow 10.0.0.0/8;
deny all;
}
Voir Métriques Prometheus pour les métriques disponibles.
📝 Variables NGINX
Le module expose deux variables à utiliser dans les journaux, les en-têtes ou les conditionnels.
$ipset_result
La décision d'accès prise pour cette requête.
| Valeur | Description |
|---|---|
allow |
Requête autorisée |
deny |
Requête bloquée |
dryrun |
Serait bloqué (mode dry-run) |
ratelimited |
Limite de taux dépassée |
challenged |
Page de défi servie |
$ipset_matched_set
Nom de l'ipset qui a correspondu (le cas échéant). Vide s'il n'y a pas de correspondance.
Remarque : Cette variable reflète l'état de correspondance au moment de la requête, pas l'état actuel de l'ipset. Si vous vérifiez l'ipset manuellement et ne trouvez pas l'IP : - L'entrée peut avoir expiré (les ipsets prennent en charge les délais par entrée) - Le cache du module (par défaut 60s) peut montrer une entrée récemment retirée comme encore correspondante - Quelque chose a pu retirer l'entrée après que la requête ait été traitée
Exemples d'utilisation
Journal d'accès personnalisé :
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;
Ajouter des en-têtes pour le débogage :
add_header X-IPSet-Result $ipset_result always;
add_header X-IPSet-Matched $ipset_matched_set always;
Journalisation conditionnelle :
## Ne journaliser que les requêtes bloquées
map $ipset_result $loggable {
"deny" 1;
default 0;
}
access_log /var/log/nginx/blocked.log combined if=$loggable;
📊 Métriques Prometheus
Le point de terminaison /metrics retourne des métriques au format d'exposition Prometheus.
Métriques disponibles
## HELP nginx_ipset_requests_total Total des requêtes traitées
## 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 Opérations de cache
## 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 Entrées de cache actuelles
## TYPE nginx_ipset_cache_entries gauge
nginx_ipset_cache_entries 5432
## HELP nginx_ipset_autoadd_total Opérations d'auto-ajout
## 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 Événements de limitation de taux
## 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 Événements de défi
## 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 Temps de fonctionnement du module
## TYPE nginx_ipset_uptime_seconds gauge
nginx_ipset_uptime_seconds 86400
Requêtes de tableau de bord Grafana
Taux de requêtes par résultat :
rate(nginx_ipset_requests_total[5m])
Taux de blocage :
rate(nginx_ipset_requests_total{result="blocked"}[5m])
Taux de réussite du cache :
rate(nginx_ipset_cache_total{result="hit"}[5m]) /
(rate(nginx_ipset_cache_total{result="hit"}[5m]) + rate(nginx_ipset_cache_total{result="miss"}[5m]))
Déclencheurs de limitation de taux par minute :
rate(nginx_ipset_ratelimit_total{action="triggered"}[1m]) * 60
📈 API de statistiques JSON
Le point de terminaison /_stats retourne des statistiques détaillées au format JSON.
Format de réponse
{
"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
}
}
Descriptions des champs
| Champ | Description |
|---|---|
version |
Version du module |
uptime_seconds |
Secondes depuis le chargement du module |
requests.checked |
Total des requêtes traitées |
requests.allowed |
Requêtes qui ont passé |
requests.blocked |
Requêtes qui ont été bloquées |
requests.errors |
Erreurs de recherche d'ipset |
cache.hits |
Succès de cache (évité appel au noyau) |
cache.misses |
Échecs de cache (appel au noyau requis) |
cache.entries |
Entrées mises en cache actuelles |
cache.hit_rate |
Pourcentage de taux de réussite |
autoadd.success |
Ajouts réussis de honeypot |
autoadd.failed |
Échecs d'ajout de honeypot |
ratelimit.triggered |
Violations de limitation de taux |
ratelimit.autobanned |
IPs ajoutées automatiquement à la liste d'interdiction |
challenge.issued |
Pages de défi servies |
challenge.passed |
Défis résolus avec succès |
challenge.failed |
Échecs de défi |
🏗️ Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ FLUX DE REQUÊTE │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Requête entrante │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Vérification │──── Dépassé ? ────▶ 429 + Auto-interdiction │
│ │ de taux │ │
│ └───────┬───────┘ │
│ │ OK │
│ ▼ │
│ ┌───────────────┐ │
│ │ Vérification │──── Pas de cookie ? ────▶ Servir JS Puzzle │
│ │ de défi │ │
│ └───────┬───────┘ │
│ │ Réussi │
│ ▼ │
│ ┌───────────────┐ ┌─────────────┐ │
│ │ Vérification │────▶│ HIT │────▶ Utiliser le résultat mis en cache │
│ └───────┬───────┘ └─────────────┘ │
│ │ MANQUE │
│ ▼ │
│ ┌───────────────┐ │
│ │ Requête ipset │──── Session libipset locale au fil │
│ │ (noyau) │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Stocker dans le cache│ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
│ │ Décision │──── Correspondance sur liste noire ? ────▶ Bloquer (403/444) │
│ │ │──── Correspondance sur liste blanche ? ────▶ Bloquer (403/444) │
│ └───────┬───────┘ │
│ │ Autoriser │
│ ▼ │
│ ┌───────────────┐ │
│ │ Vérification │──── Correspondance de localisation ? ────▶ Ajouter à l'ipset │
│ │ honeypot │ │
│ └───────┬───────┘ │
│ │ │
│ ▼ │
│ Continuer vers │
│ le gestionnaire de contenu │
│ │
├─────────────────────────────────────────────────────────────────────┤
│ MÉMOIRE PARTAGÉE │
│ ┌────────────────┬─────────────────┬─────────────────────────────┐ │
│ │ Statistiques │ Cache LRU │ Seaux de limitation de taux │ │
│ │ (compteurs) │ (IP → Résultat) │ (IP → Compteur de requêtes) │ │
│ └────────────────┴─────────────────┴─────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Disposition de la mémoire
| Composant | Emplacement | Objectif |
|---|---|---|
| Session libipset | Locale au fil | Session par travailleur pour éviter les verrous |
| Cache de recherche | Mémoire partagée | Cache LRU des mappages IP→résultat |
| Seaux de limitation de taux | Mémoire partagée | Compteurs de requêtes par IP |
| Statistiques | Mémoire partagée | Compteurs atomiques pour les métriques |
📚 Exemples
Exemple 1 : Liste noire basique
## Créer un 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;
}
}
Exemple 2 : API avec limitation de taux
server {
listen 80;
# Limitation stricte de taux pour l'API
ipset_ratelimit rate=100 window=1m autoban=api_banned ban_time=3600;
# Autoriser uniquement les partenaires connus
ipset_whitelist api_partners;
ipset_status 401;
location /api/ {
proxy_pass http://backend;
}
}
Exemple 3 : Pile de sécurité complète
server {
listen 80 default_server;
# Couche 1 : Menaces connues
ipset_blacklist malware_ips tor_exits datacenter_ranges;
ipset_status 444;
ipset_cache_ttl 5m;
# Couche 2 : Limitation de taux
ipset_ratelimit rate=60 window=1m autoban=ratelimited ban_time=1800;
# Couche 3 : Défi de bot
ipset_challenge on;
ipset_challenge_difficulty 2;
# Contenu réel
location / {
root /var/www/html;
}
# Pièges honeypot - retourner 404 (par défaut) pour ressembler à des fichiers manquants
location ~ ^/(wp-admin|phpmyadmin|admin)\.php$ {
ipset_autoadd honeypot timeout=86400;
}
# Surveillance
location = /metrics {
ipset_metrics;
allow 10.0.0.0/8;
deny all;
}
}
Exemple 4 : Test en mode dry-run
server {
listen 80;
# Tester de nouvelles règles sans bloquer
ipset_blacklist new_threat_list;
ipset_dryrun on;
location / {
root /var/www/html;
}
}
Vérifiez les journaux :
tail -f /var/log/nginx/error.log | grep "DRYRUN"
🔧 Dépannage
Module ne se charge pas
nginx: [emerg] dlopen() failed
Solution : Assurez-vous que NGINX a été construit avec --with-compat et que le module a été construit contre la même version de NGINX.
ipset non trouvé
ipset: INVALID_SETNAME
Solution : Créez l'ipset avant de démarrer NGINX :
sudo ipset create myset hash:ip
Permission refusée
ipset: kernel error
Solution : Le travailleur NGINX a besoin de la capacité CAP_NET_ADMIN :
sudo setcap cap_net_admin+ep /usr/sbin/nginx
Refus SELinux (RHEL/CentOS/AlmaLinux)
SELinux empêche /usr/sbin/nginx d'accéder à getattr sur le netlink_netfilter_socket
Solution : Installez le module de politique SELinux inclus :
cd selinux/
sudo ./install.sh
Ou manuellement :
## Vérifier
semodule -l | grep nginx_ipset
La politique permet à httpd_t (le domaine SELinux de NGINX) d'utiliser les sockets netlink_netfilter requis par libipset.
Utilisation élevée de la mémoire
Solution : Réduisez le TTL du cache ou limitez la taille du cache dans la configuration de la mémoire partagée.
Limitation de taux non fonctionnelle
Solution : Assurez-vous que l'ipset pour l'auto-interdiction existe et prend en charge les délais :
sudo ipset create ratelimited hash:ip timeout 3600
Le journal montre "matched=setname" mais l'IP n'est pas dans l'ipset
C'est un comportement attendu. Le module signale ce qu'il a vu au moment de la requête. Si vous vérifiez l'ipset plus tard et ne trouvez pas l'IP :
-
Expiration du délai : L'IP a été ajoutée avec un délai et a depuis expiré
# Vérifiez si l'ensemble prend en charge les délais ipset list setname | head -5 # Recherchez "timeout" dans l'en-tête -
Cache du module : Le module met en cache les recherches (par défaut 60s). Une IP récemment retirée peut encore apparaître comme "correspondante"
# Désactiver temporairement le cache pour le débogage (pas pour la production !) ipset_cache_ttl 0; -
L'entrée a été retirée : fail2ban, des scripts ou des commandes manuelles peuvent l'avoir retirée
-
Problème de configuration de piège : Si vous utilisez des pièges honeypot avec
ipset_autoadd, des bots légitimes peuvent avoir déclenché des pièges. Vérifiez que vos emplacements de piège ne se chevauchent pas avec des chemins de bots légitimes (comme les sitemaps, robots.txt). Utilisezrobots.txtpour exclure les chemins de piège du crawling.
autoadd échoue avec "result=4"
Cela signifie que vous utilisez timeout=N dans ipset_autoadd mais que l'ipset a été créé sans prise en charge des délais.
Solution : Recréez l'ipset avec prise en charge des délais :
## En utilisant ipset directement
sudo ipset destroy honeypot4
sudo ipset create honeypot4 hash:ip family inet timeout 86400
## En utilisant 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
📋 Exigences
- NGINX ≥ 1.22 (construit avec
--with-compat) - Noyau Linux avec prise en charge d'ipset (module nf_tables ou xt_set)
- Bibliothèque libipset et en-têtes de développement
- Capacités :
CAP_NET_ADMINpour les opérations d'ipset
📜 Licence
Il s'agit d'un logiciel propriétaire. Tous droits réservés.
Disponible exclusivement via le Dépôt Premium GetPageSpeed.
👤 Auteur
Danila Vershinin
GetPageSpeed LLC
🆘 Support
- Honeypot v2.0 Utilisation d'ipset-access pour l'auto-interdiction des bots
- Support : Disponible pour les abonnés premium
- Contact : Support GetPageSpeed
Module d'accès NGINX IPSet
Un module NGINX premium de GetPageSpeed LLC
www.getpagespeed.com