testcookie: Module de mitigation des robots testcookie pour NGINX
Installation
Vous pouvez installer ce module dans n'importe quelle 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-testcookie
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-testcookie
Activez le module en ajoutant ce qui suit en haut de /etc/nginx/nginx.conf :
load_module modules/ngx_http_testcookie_access_module.so;
Ce document décrit nginx-module-testcookie v1.28 publié le 19 juillet 2022.
testcookie-nginx-module est un module simple de mitigation des robots utilisant un défi/réponse basé sur des cookies.
Les cookies de défi peuvent être définis en utilisant différentes méthodes :
- "Set-Cookie" + redirection HTTP Location 302/307
- "Set-Cookie" + redirection HTML meta refresh
- Modèle personnalisé, JavaScript peut être utilisé ici.
Pour empêcher l'analyse automatique, la valeur du cookie de défi peut être chiffrée avec AES-128 en mode CBC en utilisant une clé et un iv personnalisés/au hasard, puis déchiffrée côté client avec JavaScript.
Directives
testcookie
syntax: testcookie (on|off|var);
default: off
context: http, server, location, if
on - Activer le module
off - Désactiver le module
var - Ne pas intercepter les requêtes, seulement définir des variables de module.
testcookie_name
syntax: testcookie_name <string>
default: TCK
context: http, server, location
Définit le nom du cookie.
testcookie_domain
syntax: testcookie_domain <string>
default: none, set by browser
context: http, server, location
Définit le domaine du cookie.
testcookie_expires
syntax: testcookie_expires <string>
default: 31 Dec 2037 23:55:55 GMT
context: http, server, location
Définit la valeur d'expiration du cookie.
testcookie_path
syntax: testcookie_path <string>
default: /
context: http, server, location
Définit le chemin du cookie, utile si vous prévoyez d'utiliser différentes clés pour les emplacements.
testcookie_samesite
syntax: testcookie_samesite <string>
default: None
context: http, server, location
Définit l'attribut du cookie, vous permet de déclarer si votre cookie doit être restreint à un contexte de première partie ou de même site. La valeur par défaut est None (Les cookies seront envoyés dans tous les contextes, c'est-à-dire que l'envoi inter-domaine est autorisé.) Accepte les valeurs : Lax, Strict, None.
testcookie_secret
syntax: testcookie_secret <string>
default: required configuration directive
context: http, server, location
Chaîne secrète, utilisée dans le calcul du cookie de défi, doit avoir 32 octets ou plus, il est préférable qu'elle soit longue mais statique pour éviter la réinitialisation du cookie pour les utilisateurs légitimes à chaque redémarrage du serveur. Si défini sur "random" - un nouveau secret sera généré à chaque redémarrage du serveur, non recommandé (tous les cookies avec la clé précédente seront invalides),
testcookie_session
syntax: testcookie_session <variable>
default: required configuration directive
context: http, server, location
Définit l'entrée de la fonction de génération de défi, * $remote_addr - l'adresse IP des clients sera utilisée comme identifiant unique de l'utilisateur * $remote_addr$http_user_agent - IP des clients + User-Agent
testcookie_arg
syntax: testcookie_arg <string>
default: none
context: http, server, location
Définit le nom du paramètre GET, utilisé pour le calcul des tentatives de définition de cookie,
Si non défini - le serveur essaiera de définir le cookie indéfiniment.
testcookie_max_attempts
syntax: testcookie_max_attempts <integer>
default: 5
context: http, server, location
Définit le nombre maximum de redirections avant que l'utilisateur ne soit envoyé à l'URL de secours, selon RFC1945 ne peut pas être plus de 5.
Si défini sur 0 - le serveur essaiera de définir le cookie indéfiniment (en réalité, le navigateur affichera la page d'erreur).
testcookie_p3p
syntax: testcookie_p3p <string>
default: none
context: http, server, location
Définit la politique P3P.
testcookie_fallback
syntax: testcookie_fallback <script>
default: none
context: http, server, location
Définit l'URL de secours, l'utilisateur sera redirigé vers celle-ci après que le nombre maximum de tentatives, spécifié par la directive testcookie_max_attempts, soit dépassé. Les variables de script Nginx peuvent être utilisées ici. Si non définie - le client recevra un 403 après avoir atteint le nombre maximum de tentatives.
testcookie_whitelist
syntax: testcookie_whitelist <network list>
default: none
context: http, server
Définit les réseaux pour lesquels le test ne sera pas utilisé, ajoutez ici les réseaux des moteurs de recherche. Actuellement IPv4 CIDR uniquement.
testcookie_pass
syntax: testcookie_pass $variable;
default: none
context: http, server
Définit le nom de la variable pour tester si la vérification du cookie doit être contournée. Si la valeur de la variable est définie sur 1 pendant la requête - la vérification du cookie ne sera pas effectuée. Peut être utilisé pour un filtrage plus complexe.
testcookie_redirect_via_refresh
syntax: testcookie_redirect_via_refresh (on|off);
default: off
context: http, server, location
Définir le cookie et rediriger en utilisant le rafraîchissement HTTP meta, requis si testcookie_refresh_template est utilisé.
testcookie_refresh_template
syntax: testcookie_refresh_template <string>
default: none
context: http, server, location
Utilisez du HTML personnalisé au lieu d'un simple rafraîchissement HTTP meta, vous devez définir le cookie manuellement à partir du modèle. Toutes les variables nginx sont disponibles et
$testcookie_nexturl - URL vers laquelle le client doit être redirigé, si max_attempts dépassé, la valeur de *testcookie_fallback* sera ici
$testcookie_got - valeur du cookie reçue du client, vide si aucun cookie ou s'il ne correspond pas au format
$testcookie_set - valeur correcte du cookie que nous attendons du client
$testcookie_ok - utilisateur a réussi le test (1 - réussi, 0 - non réussi) Remarque : changé de "yes"/"no" dans v1.10
De plus, si testcookie_refresh_encrypt_cookie est activé, il y a trois autres variables :
$testcookie_enc_key - clé de chiffrement (32 chiffres hexadécimaux)
$testcookie_enc_iv - iv de chiffrement (32 chiffres hexadécimaux)
$testcookie_enc_sec - valeur du cookie chiffrée (32 chiffres hexadécimaux)
testcookie_refresh_status
syntax: testcookie_refresh_status <code>
default: 200
context: http, server, location
Utilisez un code d'état HTTP personnalisé lors du service HTML.
testcookie_deny_keepalive
syntax: testcookie_deny_keepalive (on|off);
default: off
context: http, server, location
Fermez la connexion juste après avoir défini le cookie, aucune raison de maintenir des connexions avec des robots.
testcookie_get_only
syntax: testcookie_get_only (on|off);
default: off
context: http, server, location
Traitez uniquement les requêtes GET, les requêtes POST seront contournées.
testcookie_https_location
syntax: testcookie_https_location (on|off);
default: off
context: http, server, location
Redirigez le client vers le protocole https après avoir défini le cookie, affecte également $testcookie_nexturl, utile avec le déchargement SSL tiers.
testcookie_refresh_encrypt_cookie
syntax: testcookie_refresh_encrypt_cookie (on|off);
default: off
context: http, server, location
Chiffrez la variable cookie, utilisée avec testcookie_refresh_template pour forcer le déchiffrement côté client avec AES-128 CBC.
testcookie_refresh_encrypt_cookie_key
syntax: testcookie_refresh_encrypt_cookie_key <32 hex digits|random>
default: required directive if encryption enabled
context: http, server, location
Définit la clé de chiffrement.
Valeurs possibles :
random - nouvelle clé générée à chaque redémarrage de nginx
32 hex digits - clé statique, utile si vous prévoyez de l'obfusquer profondément dans le JavaScript côté client.
testcookie_refresh_encrypt_iv
syntax: testcookie_refresh_encrypt_iv <32 hex digits|random|random2>
default: random
context: http, server, location
Définit l'iv de chiffrement.
Valeurs possibles : random - nouvel iv généré pour chaque requête client random2 - nouvel iv généré pour chaque redémarrage de nginx 32 hex digits - iv statique, utile si vous prévoyez de l'obfusquer profondément dans le JavaScript côté client
testcookie_internal
syntax: testcookie_internal (on|off);
default: off
context: http, server, location
Activez la vérification testcookie pour les redirections internes (désactivée par défaut pour des raisons d'optimisation !), utile pour ce type de configurations :
rewrite ^/(.*)$ /index.php?$1 last;
testcookie_httponly_flag
syntax: testcookie_httponly_flag (on|off);
default: off
context: http, server, location
Activez le drapeau HttpOnly pour le cookie.
testcookie_secure_flag
syntax: testcookie_secure_flag (on|off|$variable);
default: on
context: http, server, location
Activez le drapeau Secure pour le cookie. Toute valeur de variable sauf "on" est interprétée comme False.
testcookie_port_in_redirect
syntax: testcookie_port_in_redirect (on|off);
default: off
context: http, server, location
Exposez le port dans la redirection.
Exemple de configuration
http {
#configuration par défaut, module désactivé
testcookie off;
#définir le nom du cookie
testcookie_name BPC;
#définir le secret
testcookie_secret keepmesecret;
#définir la clé de session
testcookie_session $remote_addr;
#définir le nom de l'argument
testcookie_arg ckattempt;
#définir le nombre maximum de tentatives de définition de cookie
testcookie_max_attempts 3;
#définir la politique p3p
testcookie_p3p 'CP="CUR ADM OUR NOR STA NID", policyref="/w3c/p3p.xml"';
#définir l'URL de secours
testcookie_fallback http://google.com/cookies.html?backurl=http://$host$request_uri;
#configurer la liste blanche
testcookie_whitelist {
8.8.8.8/32;
}
#définir la redirection via le code html
testcookie_redirect_via_refresh on;
#activer le chiffrement
testcookie_refresh_encrypt_cookie on;
#définir la clé de chiffrement
testcookie_refresh_encrypt_cookie_key deadbeefdeadbeefdeadbeefdeadbeef;
#définir l'iv de chiffrement
testcookie_refresh_encrypt_cookie_iv deadbeefdeadbeefdeadbeefdeadbeef;
#définir le modèle de réponse
testcookie_refresh_template '<html><body>setting cookie...<script type=\"text/javascript\" src=\"/aes.min.js\" ></script><script>function toNumbers(d){var e=[];d.replace(/(..)/g,function(d){e.push(parseInt(d,16))});return e}function toHex(){for(var d=[],d=1==arguments.length&&arguments[0].constructor==Array?arguments[0]:arguments,e="",f=0;f<d.length;f++)e+=(16>d[f]?"0":"")+d[f].toString(16);return e.toLowerCase()}var a=toNumbers("$testcookie_enc_key"),b=toNumbers("$testcookie_enc_iv"),c=toNumbers("$testcookie_enc_set");document.cookie="BPC="+toHex(slowAES.decrypt(c,2,a,b))+"; expires=Thu, 31-Dec-37 23:55:55 GMT; path=/";location.href="$testcookie_nexturl";</script></body></html>';
server {
listen 80;
server_name test.com;
location = /aes.min.js {
gzip on;
gzip_min_length 1000;
gzip_types text/plain;
root /var/www/public_html;
}
location = /w3c/p3p.xml {
root /var/www/public_html;
}
location / {
#activer le module pour un emplacement spécifique
testcookie on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://127.0.0.1:80;
}
}
}
Voir plus de cas dans le répertoire "docs" du projet.
Suite de tests
Ce module est livré avec une suite de tests pilotée par Perl. Grâce au module Test::Nginx dans le monde Perl.
Sources
Disponible sur github à kyprizel/testcookie-nginx-module.
GitHub
Vous pouvez trouver des conseils de configuration supplémentaires et de la documentation pour ce module dans le dépôt GitHub pour nginx-module-testcookie.