testcookie: Módulo de mitigación de robots testcookie de NGINX
Instalación
Puedes instalar este módulo en cualquier distribución basada en RHEL, incluyendo, pero no limitado a:
- RedHat Enterprise Linux 7, 8, 9 y 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 y 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
Habilita el módulo añadiendo lo siguiente en la parte superior de /etc/nginx/nginx.conf:
load_module modules/ngx_http_testcookie_access_module.so;
Este documento describe nginx-module-testcookie v1.28 lanzado el 19 de julio de 2022.
testcookie-nginx-module es un módulo simple de mitigación de robots que utiliza un desafío/respuesta basado en cookies.
Las cookies de desafío se pueden establecer utilizando diferentes métodos:
- "Set-Cookie" + redirección HTTP 302/307 Location
- "Set-Cookie" + redirección HTML meta refresh
- Plantilla personalizada, se puede usar JavaScript aquí.
Para prevenir el análisis automático, el valor de la cookie de desafío se puede cifrar con AES-128 en modo CBC utilizando una clave y un iv personalizados/aleatorios, y luego descifrado en el lado del cliente con JavaScript.
Directivas
testcookie
sintaxis: testcookie (on|off|var);
predeterminado: off
contexto: http, server, location, if
on - Habilitar módulo
off - Deshabilitar módulo
var - No interceptar solicitudes, solo establecer variables del módulo.
testcookie_name
sintaxis: testcookie_name <string>
predeterminado: TCK
contexto: http, server, location
Establece el nombre de la cookie.
testcookie_domain
sintaxis: testcookie_domain <string>
predeterminado: none, establecido por el navegador
contexto: http, server, location
Establece el dominio de la cookie.
testcookie_expires
sintaxis: testcookie_expires <string>
predeterminado: 31 Dec 2037 23:55:55 GMT
contexto: http, server, location
Establece el valor de expiración de la cookie.
testcookie_path
sintaxis: testcookie_path <string>
predeterminado: /
contexto: http, server, location
Establece la ruta de la cookie, útil si planeas usar diferentes claves para ubicaciones.
testcookie_samesite
sintaxis: testcookie_samesite <string>
predeterminado: None
contexto: http, server, location
Establece el atributo de la cookie, te permite declarar si tu cookie debe estar restringida a un contexto de primer partido o de mismo sitio. El valor predeterminado es None (Las cookies se enviarán en todos los contextos, es decir, se permite el envío entre orígenes). Acepta valores: Lax, Strict, None.
testcookie_secret
sintaxis: testcookie_secret <string>
predeterminado: directiva de configuración requerida
contexto: http, server, location
Cadena secreta, utilizada en el cálculo de la cookie de desafío, debe tener 32 bytes o más, es mejor que sea larga pero estática para prevenir el restablecimiento de cookies para usuarios legítimos en cada reinicio del servidor. Si se establece en "random" - se generará un nuevo secreto en cada reinicio del servidor, no recomendado (todas las cookies con la clave anterior serán inválidas).
testcookie_session
sintaxis: testcookie_session <variable>
predeterminado: directiva de configuración requerida
contexto: http, server, location
Establece la entrada de la función de generación de desafíos, * $remote_addr - la dirección IP del cliente se utilizará como un identificador único de usuario * $remote_addr$http_user_agent - IP del cliente + User-Agent
testcookie_arg
sintaxis: testcookie_arg <string>
predeterminado: none
contexto: http, server, location
Establece el nombre del parámetro GET, utilizado para el cálculo de intentos de establecimiento de cookies,
Si no se establece - el servidor intentará establecer la cookie infinitamente.
testcookie_max_attempts
sintaxis: testcookie_max_attempts <integer>
predeterminado: 5
contexto: http, server, location
Establece el número máximo de redirecciones antes de que el usuario sea enviado a la URL de respaldo, de acuerdo con RFC1945 no puede ser más de 5.
Si se establece en 0 - el servidor intentará establecer la cookie infinitamente (en realidad, el navegador mostrará la página de error).
testcookie_p3p
sintaxis: testcookie_p3p <string>
predeterminado: none
contexto: http, server, location
Establece la política P3P.
testcookie_fallback
sintaxis: testcookie_fallback <script>
predeterminado: none
contexto: http, server, location
Establece la URL de respaldo, a la que el usuario será redirigido después de que se exceda el número máximo de intentos, especificado por la directiva testcookie_max_attempts. Se pueden usar variables de scripting de Nginx aquí. Si no se establece - el cliente recibirá un 403 después de alcanzar el máximo de intentos.
testcookie_whitelist
sintaxis: testcookie_whitelist <network list>
predeterminado: none
contexto: http, server
Establece las redes para las cuales no se utilizará la prueba, agrega aquí redes de motores de búsqueda. Actualmente solo IPv4 CIDR.
testcookie_pass
sintaxis: testcookie_pass $variable;
predeterminado: none
contexto: http, server
Establece el nombre de la variable para probar si se debe omitir la verificación de la cookie. Si el valor de la variable se establece en 1 durante la solicitud - no se realizará la verificación de la cookie. Se puede usar para listas blancas más complejas.
testcookie_redirect_via_refresh
sintaxis: testcookie_redirect_via_refresh (on|off);
predeterminado: off
contexto: http, server, location
Establece la cookie y redirige utilizando una meta refresh HTTP, requerido si se utiliza testcookie_refresh_template.
testcookie_refresh_template
sintaxis: testcookie_refresh_template <string>
predeterminado: none
contexto: http, server, location
Utiliza HTML personalizado en lugar de una simple meta refresh HTTP, necesitas establecer la cookie manualmente desde la plantilla. Disponibles todas las variables de nginx y
$testcookie_nexturl - URL a la que el cliente debe ser redirigido, si se excede *testcookie_max_attempts* aquí estará el valor de *testcookie_fallback*
$testcookie_got - valor de la cookie recibido del cliente, vacío si no hay cookie o no coincide con el formato
$testcookie_set - valor correcto de la cookie que esperamos del cliente
$testcookie_ok - el usuario pasó la prueba (1 - pasado, 0 - no pasado) Nota: cambiado de "yes"/"no" en v1.10
Además, si testcookie_refresh_encrypt_cookie está habilitado, hay tres variables más:
$testcookie_enc_key - clave de cifrado (32 dígitos hexadecimales)
$testcookie_enc_iv - iv de cifrado (32 dígitos hexadecimales)
$testcookie_enc_sec - valor de cookie cifrado (32 dígitos hexadecimales)
testcookie_refresh_status
sintaxis: testcookie_refresh_status <code>
predeterminado: 200
contexto: http, server, location
Utiliza un código de estado HTTP personalizado al servir HTML.
testcookie_deny_keepalive
sintaxis: testcookie_deny_keepalive (on|off);
predeterminado: off
contexto: http, server, location
Cierra la conexión justo después de establecer la cookie, no hay razón para mantener conexiones con bots.
testcookie_get_only
sintaxis: testcookie_get_only (on|off);
predeterminado: off
contexto: http, server, location
Procesa solo solicitudes GET, las solicitudes POST serán omitidas.
testcookie_https_location
sintaxis: testcookie_https_location (on|off);
predeterminado: off
contexto: http, server, location
Redirige al cliente al protocolo https después de establecer la cookie, también afecta a $testcookie_nexturl, útil con la descarga SSL de terceros.
testcookie_refresh_encrypt_cookie
sintaxis: testcookie_refresh_encrypt_cookie (on|off);
predeterminado: off
contexto: http, server, location
Cifra la variable de la cookie, utilizada con testcookie_refresh_template para forzar el descifrado del lado del cliente con AES-128 CBC.
testcookie_refresh_encrypt_cookie_key
sintaxis: testcookie_refresh_encrypt_cookie_key <32 hex digits|random>
predeterminado: directiva requerida si se habilita el cifrado
contexto: http, server, location
Establece la clave de cifrado.
Valores posibles:
random - nueva clave generada en cada reinicio de nginx
32 hex digits - clave estática, útil si planeas ofuscarla profundamente en JavaScript del lado del cliente.
testcookie_refresh_encrypt_iv
sintaxis: testcookie_refresh_encrypt_iv <32 hex digits|random|random2>
predeterminado: random
contexto: http, server, location
Establece el iv de cifrado.
Valores posibles: random - nuevo iv generado para cada solicitud del cliente random2 - nuevo iv generado para cada reinicio de nginx 32 hex digits - iv estático, útil si planeas ofuscarlo profundamente en JavaScript del lado del cliente.
testcookie_internal
sintaxis: testcookie_internal (on|off);
predeterminado: off
contexto: http, server, location
Habilita la verificación de testcookie para redirecciones internas (deshabilitado por defecto por razones de optimización), útil para este tipo de configuraciones:
rewrite ^/(.*)$ /index.php?$1 last;
testcookie_httponly_flag
sintaxis: testcookie_httponly_flag (on|off);
predeterminado: off
contexto: http, server, location
Habilita la bandera HttpOnly para la cookie.
testcookie_secure_flag
sintaxis: testcookie_secure_flag (on|off|$variable);
predeterminado: on
contexto: http, server, location
Habilita la bandera Secure para la cookie. Cualquier valor de variable excepto "on" se interpreta como False.
testcookie_port_in_redirect
sintaxis: testcookie_port_in_redirect (on|off);
predeterminado: off
contexto: http, server, location
Expone el puerto en la redirección.
Ejemplo de configuración
http {
#configuración predeterminada, módulo deshabilitado
testcookie off;
#estableciendo el nombre de la cookie
testcookie_name BPC;
#estableciendo el secreto
testcookie_secret keepmesecret;
#estableciendo la clave de sesión
testcookie_session $remote_addr;
#estableciendo el nombre del argumento
testcookie_arg ckattempt;
#estableciendo el número máximo de intentos de establecimiento de cookies
testcookie_max_attempts 3;
#estableciendo la política p3p
testcookie_p3p 'CP="CUR ADM OUR NOR STA NID", policyref="/w3c/p3p.xml"';
#estableciendo la URL de respaldo
testcookie_fallback http://google.com/cookies.html?backurl=http://$host$request_uri;
#configurando la lista blanca
testcookie_whitelist {
8.8.8.8/32;
}
#estableciendo redirección a través de código html
testcookie_redirect_via_refresh on;
#habilitando cifrado
testcookie_refresh_encrypt_cookie on;
#estableciendo la clave de cifrado
testcookie_refresh_encrypt_cookie_key deadbeefdeadbeefdeadbeefdeadbeef;
#estableciendo el iv de cifrado
testcookie_refresh_encrypt_cookie_iv deadbeefdeadbeefdeadbeefdeadbeef;
#estableciendo la plantilla de respuesta
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 / {
#habilitar módulo para ubicación específica
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;
}
}
}
Consulta más casos en el directorio "docs" del proyecto.
Suite de pruebas
Este módulo viene con una suite de pruebas impulsada por Perl. Gracias al módulo Test::Nginx en el mundo de Perl.
Fuentes
Disponibles en github en kyprizel/testcookie-nginx-module.
GitHub
Puedes encontrar consejos adicionales de configuración y documentación para este módulo en el repositorio de GitHub para nginx-module-testcookie.