testcookie: Módulo de mitigação de robôs testcookie do NGINX
Instalação
Você pode instalar este módulo em qualquer distribuição baseada em RHEL, incluindo, mas não se limitando a:
- RedHat Enterprise Linux 7, 8, 9 e 10
- CentOS 7, 8, 9
- AlmaLinux 8, 9
- Rocky Linux 8, 9
- Amazon Linux 2 e 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
Ative o módulo adicionando o seguinte no topo de /etc/nginx/nginx.conf:
load_module modules/ngx_http_testcookie_access_module.so;
Este documento descreve o nginx-module-testcookie v1.28 lançado em 19 de julho de 2022.
testcookie-nginx-module é um módulo simples de mitigação de robôs que utiliza um desafio/resposta baseado em cookies.
Os cookies de desafio podem ser definidos usando diferentes métodos:
- "Set-Cookie" + redirecionamento HTTP Location 302/307
- "Set-Cookie" + redirecionamento HTML meta refresh
- Template personalizado, JavaScript pode ser usado aqui.
Para evitar a análise automática, o valor do cookie de desafio pode ser criptografado com AES-128 em modo CBC usando uma chave e iv personalizados/aleatórios, e depois descriptografado no lado do cliente com JavaScript.
Diretivas
testcookie
sintaxe: testcookie (on|off|var);
padrão: off
contexto: http, server, location, if
on - Habilitar módulo
off - Desabilitar módulo
var - Não interceptar solicitações, apenas definir variáveis do módulo.
testcookie_name
sintaxe: testcookie_name <string>
padrão: TCK
contexto: http, server, location
Define o nome do cookie.
testcookie_domain
sintaxe: testcookie_domain <string>
padrão: none, definido pelo navegador
contexto: http, server, location
Define o domínio do cookie.
testcookie_expires
sintaxe: testcookie_expires <string>
padrão: 31 Dec 2037 23:55:55 GMT
contexto: http, server, location
Define o valor de expiração do cookie.
testcookie_path
sintaxe: testcookie_path <string>
padrão: /
contexto: http, server, location
Define o caminho do cookie, útil se você planeja usar chaves diferentes para localizações.
testcookie_samesite
sintaxe: testcookie_samesite <string>
padrão: None
contexto: http, server, location
Define o atributo do cookie, permite declarar se seu cookie deve ser restrito a um contexto de primeiro partido ou mesmo site. O padrão é None (Cookies serão enviados em todos os contextos, ou seja, o envio cross-origin é permitido.) Aceita valores: Lax, Strict, None.
testcookie_secret
sintaxe: testcookie_secret <string>
padrão: diretiva de configuração obrigatória
contexto: http, server, location
String secreta, usada no cálculo do cookie de desafio, deve ter 32 bytes ou mais, é melhor que seja longa, mas estática para evitar a redefinição do cookie para usuários legítimos a cada reinício do servidor. Se definido como "random" - uma nova chave secreta será gerada a cada reinício do servidor, não recomendado (todos os cookies com a chave anterior serão inválidos).
testcookie_session
sintaxe: testcookie_session <variable>
padrão: diretiva de configuração obrigatória
contexto: http, server, location
Define a entrada da função de geração de desafio, * $remote_addr - endereço IP do cliente será usado como um identificador único do usuário * $remote_addr$http_user_agent - IP do cliente + User-Agent
testcookie_arg
sintaxe: testcookie_arg <string>
padrão: none
contexto: http, server, location
Define o nome do parâmetro GET, usado para o cálculo de tentativas de definição de cookie,
Se não definido - o servidor tentará definir o cookie infinitamente.
testcookie_max_attempts
sintaxe: testcookie_max_attempts <integer>
padrão: 5
contexto: http, server, location
Define o número máximo de redirecionamentos antes que o usuário seja enviado para a URL de fallback, de acordo com o RFC1945 não pode ser mais que 5.
Se definido como 0 - o servidor tentará definir o cookie infinitamente (na verdade, o navegador mostrará a página de erro).
testcookie_p3p
sintaxe: testcookie_p3p <string>
padrão: none
contexto: http, server, location
Define a política P3P.
testcookie_fallback
sintaxe: testcookie_fallback <script>
padrão: none
contexto: http, server, location
Define a URL de fallback, para a qual o usuário será redirecionado após o número máximo de tentativas, especificado pela diretiva testcookie_max_attempts ser excedido. Variáveis de script do Nginx podem ser usadas aqui. Se não definido - o cliente receberá 403 após o número máximo de tentativas.
testcookie_whitelist
sintaxe: testcookie_whitelist <network list>
padrão: none
contexto: http, server
Define as redes para as quais o teste não será utilizado, adicione redes de mecanismos de busca aqui. Atualmente apenas CIDR IPv4.
testcookie_pass
sintaxe: testcookie_pass $variable;
padrão: none
contexto: http, server
Define o nome da variável para testar se a verificação do cookie deve ser ignorada. Se o valor da variável for definido como 1 durante a solicitação - a verificação do cookie não será realizada. Pode ser usado para uma lista de permissões mais complexa.
testcookie_redirect_via_refresh
sintaxe: testcookie_redirect_via_refresh (on|off);
padrão: off
contexto: http, server, location
Define cookie e redireciona usando meta refresh HTTP, necessário se testcookie_refresh_template for usado.
testcookie_refresh_template
sintaxe: testcookie_refresh_template <string>
padrão: none
contexto: http, server, location
Use HTML personalizado em vez de um simples meta refresh HTTP, você precisa definir o cookie manualmente a partir do template. Todas as variáveis do nginx estão disponíveis e
$testcookie_nexturl - URL para a qual o cliente deve ser redirecionado, se max_attempts for excedido, o valor de *testcookie_fallback* estará aqui
$testcookie_got - valor do cookie recebido do cliente, vazio se não houver cookie ou se não corresponder ao formato
$testcookie_set - valor correto do cookie que estamos esperando do cliente
$testcookie_ok - usuário passou no teste (1 - passou, 0 - não passou) Nota: alterado de "yes"/"no" na v1.10
Além disso, se testcookie_refresh_encrypt_cookie estiver habilitado, há mais três variáveis:
$testcookie_enc_key - chave de criptografia (32 dígitos hexadecimais)
$testcookie_enc_iv - iv de criptografia (32 dígitos hexadecimais)
$testcookie_enc_sec - valor do cookie criptografado (32 dígitos hexadecimais)
testcookie_refresh_status
sintaxe: testcookie_refresh_status <code>
padrão: 200
contexto: http, server, location
Use um código de status HTTP personalizado ao servir HTML.
testcookie_deny_keepalive
sintaxe: testcookie_deny_keepalive (on|off);
padrão: off
contexto: http, server, location
Feche a conexão logo após definir o cookie, não há razão para manter conexões com robôs.
testcookie_get_only
sintaxe: testcookie_get_only (on|off);
padrão: off
contexto: http, server, location
Processar apenas solicitações GET, solicitações POST serão ignoradas.
testcookie_https_location
sintaxe: testcookie_https_location (on|off);
padrão: off
contexto: http, server, location
Redirecionar o cliente para o protocolo https após definir o cookie, também afeta $testcookie_nexturl, útil com offload SSL de terceiros.
testcookie_refresh_encrypt_cookie
sintaxe: testcookie_refresh_encrypt_cookie (on|off);
padrão: off
contexto: http, server, location
Criptografar a variável do cookie, usada com testcookie_refresh_template para forçar a descriptografia do lado do cliente com AES-128 CBC.
testcookie_refresh_encrypt_cookie_key
sintaxe: testcookie_refresh_encrypt_cookie_key <32 hex digits|random>
padrão: diretiva obrigatória se a criptografia estiver habilitada
contexto: http, server, location
Define a chave de criptografia.
Valores possíveis:
random - nova chave gerada a cada reinício do nginx
32 hex digits - chave estática, útil se você planeja ofuscar profundamente no JavaScript do lado do cliente.
testcookie_refresh_encrypt_iv
sintaxe: testcookie_refresh_encrypt_iv <32 hex digits|random|random2>
padrão: random
contexto: http, server, location
Define o iv de criptografia.
Valores possíveis: random - novo iv gerado para cada solicitação do cliente random2 - novo iv gerado para cada reinício do nginx 32 hex digits - iv estático, útil se você planeja ofuscar profundamente no JavaScript do lado do cliente
testcookie_internal
sintaxe: testcookie_internal (on|off);
padrão: off
contexto: http, server, location
Habilitar verificação de testcookie para redirecionamentos internos (desativado por padrão para fins de otimização!), útil para este tipo de configuração:
rewrite ^/(.*)$ /index.php?$1 last;
testcookie_httponly_flag
sintaxe: testcookie_httponly_flag (on|off);
padrão: off
contexto: http, server, location
Habilitar a flag HttpOnly para o cookie.
testcookie_secure_flag
sintaxe: testcookie_secure_flag (on|off|$variable);
padrão: on
contexto: http, server, location
Habilitar a flag Secure para o cookie. Qualquer valor de variável, exceto "on", é interpretado como Falso.
testcookie_port_in_redirect
sintaxe: testcookie_port_in_redirect (on|off);
padrão: off
contexto: http, server, location
Expor a porta no redirecionamento.
Exemplo de configuração
http {
#configuração padrão, módulo desabilitado
testcookie off;
#definindo o nome do cookie
testcookie_name BPC;
#definindo o segredo
testcookie_secret keepmesecret;
#definindo a chave da sessão
testcookie_session $remote_addr;
#definindo o nome do argumento
testcookie_arg ckattempt;
#definindo o número máximo de tentativas de definição de cookie
testcookie_max_attempts 3;
#definindo a política p3p
testcookie_p3p 'CP="CUR ADM OUR NOR STA NID", policyref="/w3c/p3p.xml"';
#definindo a URL de fallback
testcookie_fallback http://google.com/cookies.html?backurl=http://$host$request_uri;
#configurando a lista de permissões
testcookie_whitelist {
8.8.8.8/32;
}
#definindo redirecionamento via código html
testcookie_redirect_via_refresh on;
#habilitar criptografia
testcookie_refresh_encrypt_cookie on;
#definindo a chave de criptografia
testcookie_refresh_encrypt_cookie_key deadbeefdeadbeefdeadbeefdeadbeef;
#definindo o iv de criptografia
testcookie_refresh_encrypt_cookie_iv deadbeefdeadbeefdeadbeefdeadbeef;
#definindo o template de resposta
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 localização 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;
}
}
}
Veja mais casos no diretório "docs" do projeto.
Conjunto de testes
Este módulo vem com um conjunto de testes baseado em Perl. Graças ao módulo Test::Nginx no mundo Perl.
Fontes
Disponível no github em kyprizel/testcookie-nginx-module.
GitHub
Você pode encontrar dicas adicionais de configuração e documentação para este módulo no repositório do GitHub para nginx-module-testcookie.