Aller au contenu

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.

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.

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.