跳转至

testcookie: NGINX testcookie 机器人缓解模块

安装

您可以在任何基于 RHEL 的发行版中安装此模块,包括但不限于:

  • RedHat Enterprise Linux 7、8、9 和 10
  • CentOS 7、8、9
  • AlmaLinux 8、9
  • Rocky Linux 8、9
  • Amazon Linux 2 和 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

通过在 /etc/nginx/nginx.conf 顶部添加以下内容来启用模块:

load_module modules/ngx_http_testcookie_access_module.so;

本文档描述了 nginx-module-testcookie v1.28,于 2022 年 7 月 19 日发布。


testcookie-nginx-module 是一个简单的机器人缓解模块,使用基于 Cookie 的挑战/响应。

可以使用不同的方法设置挑战 Cookie:

  • "Set-Cookie" + 302/307 HTTP 位置重定向
  • "Set-Cookie" + HTML meta 刷新重定向
  • 自定义模板,这里可以使用 JavaScript。

为了防止自动解析,挑战 Cookie 值可以使用自定义/随机密钥和 IV 通过 AES-128 CBC 模式加密,然后在客户端使用 JavaScript 解密。

指令

testcookie

语法: testcookie (on|off|var);

默认值: off

上下文: http, server, location, if

on - 启用模块

off - 禁用模块

var - 不拦截请求,仅设置模块变量。

testcookie_name

语法: testcookie_name <string>

默认值: TCK

上下文: http, server, location

设置 Cookie 名称。

testcookie_domain

语法: testcookie_domain <string>

默认值: none, set by browser

上下文: http, server, location

设置 Cookie 域。

testcookie_expires

语法: testcookie_expires <string>

默认值: 31 Dec 2037 23:55:55 GMT

上下文: http, server, location

设置 Cookie 过期值。

testcookie_path

语法: testcookie_path <string>

默认值: /

上下文: http, server, location

设置 Cookie 路径,如果您计划为不同位置使用不同的密钥,这很有用。

testcookie_samesite

语法: testcookie_samesite <string>

默认值: None

上下文: http, server, location

设置 Cookie 属性,允许您声明 Cookie 是否应限制在第一方或同站上下文中。 默认值为 None(Cookie 将在所有上下文中发送,即允许跨源发送)。 接受的值:Lax, Strict, None。

testcookie_secret

语法: testcookie_secret <string>

默认值: required configuration directive

上下文: http, server, location

秘密字符串,用于挑战 Cookie 计算,应该是 32 字节或更多, 最好是长但静态,以防止每次服务器重启时合法用户的 Cookie 重置。 如果设置为 "random" - 每次服务器重启时将生成新密钥,不推荐(所有使用先前密钥的 Cookie 将无效)。

testcookie_session

语法: testcookie_session <variable>

默认值: required configuration directive

上下文: http, server, location

设置挑战生成函数输入, * $remote_addr - 客户端 IP 地址将用作用户唯一标识符 * $remote_addr$http_user_agent - 客户端 IP + User-Agent

testcookie_arg

语法: testcookie_arg <string>

默认值: none

上下文: http, server, location

设置 GET 参数名称,用于 Cookie 设置尝试的计算,

如果未设置 - 服务器将尝试无限次设置 Cookie。

testcookie_max_attempts

语法: testcookie_max_attempts <integer>

默认值: 5

上下文: http, server, location

设置在用户被发送到后备 URL 之前的最大重定向次数,根据 RFC1945 不能超过 5。

如果设置为 0 - 服务器将尝试无限次设置 Cookie(实际上,浏览器将显示错误页面)。

testcookie_p3p

语法: testcookie_p3p <string>

默认值: none

上下文: http, server, location

设置 P3P 策略。

testcookie_fallback

语法: testcookie_fallback <script>

默认值: none

上下文: http, server, location

设置后备 URL,用户将在超过指令 testcookie_max_attempts 指定的最大尝试次数后被重定向到此 URL。 可以在这里使用 Nginx 脚本变量。如果未设置 - 客户端将在达到最大尝试次数后收到 403。

testcookie_whitelist

语法: testcookie_whitelist <network list>

默认值: none

上下文: http, server

设置不使用测试的网络,在这里添加搜索引擎网络。目前仅支持 IPv4 CIDR。

testcookie_pass

语法: testcookie_pass $variable;

默认值: none

上下文: http, server

设置变量名称以测试是否应绕过 Cookie 检查。 如果请求期间变量值设置为 1 - 将不执行 Cookie 检查。 可用于更复杂的白名单。

testcookie_redirect_via_refresh

语法: testcookie_redirect_via_refresh (on|off);

默认值: off

上下文: http, server, location

使用 HTTP meta 刷新设置 Cookie 和重定向,如果使用了 testcookie_refresh_template,则需要。

testcookie_refresh_template

语法: testcookie_refresh_template <string>

默认值: none

上下文: http, server, location

使用自定义 HTML 而不是简单的 HTTP meta 刷新,您需要从模板手动设置 Cookie。 可用的所有 Nginx 变量和

$testcookie_nexturl - 客户端应重定向到的 URL,如果超过 *testcookie_max_attempts*,此处将显示 *testcookie_fallback* 的值
$testcookie_got - 从客户端接收到的 Cookie 值,如果没有 Cookie 或不匹配格式则为空
$testcookie_set - 我们期望从客户端收到的正确 Cookie 值
$testcookie_ok - 用户通过测试(1 - 通过,0 - 未通过)注意:在 v1.10 中从 "yes"/"no" 更改

此外,如果启用 testcookie_refresh_encrypt_cookie,则还有三个变量:

$testcookie_enc_key - 加密密钥(32 个十六进制数字)
$testcookie_enc_iv - 加密 IV(32 个十六进制数字)
$testcookie_enc_sec - 加密的 Cookie 值(32 个十六进制数字)

testcookie_refresh_status

语法: testcookie_refresh_status <code>

默认值: 200

上下文: http, server, location

在提供 HTML 时使用自定义 HTTP 状态码。

testcookie_deny_keepalive

语法: testcookie_deny_keepalive (on|off);

默认值: off

上下文: http, server, location

在设置 Cookie 后立即关闭连接,没有理由与机器人保持连接。

testcookie_get_only

语法: testcookie_get_only (on|off);

默认值: off

上下文: http, server, location

仅处理 GET 请求,POST 请求将被绕过。

testcookie_https_location

语法: testcookie_https_location (on|off);

默认值: off

上下文: http, server, location

在设置 Cookie 后将客户端重定向到 HTTPS 协议,也会影响 $testcookie_nexturl,在与第三方 SSL 卸载时很有用。

语法: testcookie_refresh_encrypt_cookie (on|off);

默认值: off

上下文: http, server, location

加密 Cookie 变量,与 testcookie_refresh_template 一起使用,以强制客户端使用 AES-128 CBC 解密。

语法: testcookie_refresh_encrypt_cookie_key <32 hex digits|random>

默认值: required directive if encryption enabled

上下文: http, server, location

设置加密密钥。

可能的值:

random - 每次 Nginx 重启时生成新密钥
32 hex digits - 静态密钥,如果您计划在客户端 JavaScript 中深度混淆它,这很有用。

testcookie_refresh_encrypt_iv

语法: testcookie_refresh_encrypt_iv <32 hex digits|random|random2>

默认值: random

上下文: http, server, location

设置加密 IV。

可能的值: random - 为每个客户端请求生成新 IV random2 - 为每次 Nginx 重启生成新 IV 32 hex digits - 静态 IV,如果您计划在客户端 JavaScript 中深度混淆它,这很有用。

testcookie_internal

语法: testcookie_internal (on|off);

默认值: off

上下文: http, server, location

启用内部重定向的 testcookie 检查(默认情况下出于优化目的禁用!),适用于此类配置:

rewrite ^/(.*)$ /index.php?$1 last;

testcookie_httponly_flag

语法: testcookie_httponly_flag (on|off);

默认值: off

上下文: http, server, location

为 Cookie 启用 HttpOnly 标志。

testcookie_secure_flag

语法: testcookie_secure_flag (on|off|$variable);

默认值: on

上下文: http, server, location

为 Cookie 启用 Secure 标志。 任何变量值,除了 "on",都被解释为 False。

testcookie_port_in_redirect

语法: testcookie_port_in_redirect (on|off);

默认值: off

上下文: http, server, location

在重定向中暴露端口。

示例配置

http {
    #默认配置,模块禁用
    testcookie off;

    #设置 Cookie 名称
    testcookie_name BPC;

    #设置秘密
    testcookie_secret keepmesecret;

    #设置会话密钥
    testcookie_session $remote_addr;

    #设置参数名称
    testcookie_arg ckattempt;

    #设置最大 Cookie 设置尝试次数
    testcookie_max_attempts 3;

    #设置 p3p 策略
    testcookie_p3p 'CP="CUR ADM OUR NOR STA NID", policyref="/w3c/p3p.xml"';

    #设置后备 URL
    testcookie_fallback http://google.com/cookies.html?backurl=http://$host$request_uri;

    #配置白名单
    testcookie_whitelist {
        8.8.8.8/32;
    }

    #通过 HTML 代码设置重定向
    testcookie_redirect_via_refresh on;

    #启用加密
    testcookie_refresh_encrypt_cookie on;

    #设置加密密钥
    testcookie_refresh_encrypt_cookie_key deadbeefdeadbeefdeadbeefdeadbeef;

    #设置加密 IV
    testcookie_refresh_encrypt_cookie_iv deadbeefdeadbeefdeadbeefdeadbeef;

    #设置响应模板
    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 / {
            #为特定位置启用模块
            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;
        }
    }
}

在项目的 "docs" 目录中查看更多案例。

测试套件

此模块附带一个 Perl 驱动的测试套件。感谢 Perl 世界中的 Test::Nginx 模块。

源代码

可在 GitHub 上找到 kyprizel/testcookie-nginx-module

GitHub

您可以在 nginx-module-testcookie 的 GitHub 仓库 中找到此模块的其他配置提示和文档。