Nginx:使用标头绕过速率限制

Nginx:使用标头绕过速率限制

这个答案完美地解决了绕过 IP 地址速率限制的问题。

如果我需要使用秘密标头来绕过速率限制,我该如何实现?

参考:

http {
    geo $whitelist {
       default 0;
       # CIDR in the list below are not limited
       1.2.3.0/24 1;
       9.10.11.12/32 1;
       127.0.0.1/32 1;
    }
    map $whitelist $limit {
        0     $binary_remote_addr;
        1     "";
    }
    limit_conn_zone      $limit    zone=connlimit:10m;

    limit_conn           connlimit 5;
    limit_conn_log_level warn;   # logging level when threshold exceeded
    limit_conn_status    503;    # the error code to return

答案1

这些问题的通常原因是,大多数这些指令不能在语句的上下文中使用if,因此,如何能够有条件地指定不同的限制?

答案是使用中间变量——就像在链接答案中一样,使用变量设置限制,随后,这些变量的值将根据mapif语句而有所不同。

http {
    map $http_x_secret_header $limit {
        default      $binary_remote_addr;
        secretvalue  "";
    }
    limit_conn_zone      $limit    zone=connlimit:10m;

参考:

答案2

FWIIW,我也看过另一个“奇怪”的答案对于您链接的问题——它是在 2011 年写的,在 2017 年早些时候只有 3 个赞成票,而您引用的 2014 年左右的最新答案有 23 个赞成票。也许有点令人惊讶的是,较早被忽略的答案实际上也没有任何问题!

以下是我对完整 MVP 配置的看法,经过全面测试:

server {
    listen 7461;
    error_page 429 = @slowdown;
    if ($http_x_secret_header != secret_value) {
        return 429;
    }
    location @slowdown {
        #limit_...
        return 200 "$uri: slowed down\n";
    }
    location / {
        return 200 "$uri: very fast\n";
    }
}

下面的测试向您展示一切正常,包括200 OK返回了正确的代码:

%curl -H "X-Secret-Header: secret_value" localhost:7461/important/path/
/important/path/: very fast

%curl -H "X-Secret-Header: wrong_value" localhost:7461/important/path/
/important/path/: slowed down

%curl -v localhost:7461/important/path/ | & fgrep -e HTTP/ -e /important
> GET /important/path/ HTTP/1.1
< HTTP/1.1 200 OK
/important/path/: slowed down
%

所以,是的,error_page重定向确实也有效!


让我解释一下这个奇怪答案的原因error_page——在 nginx 中,你可以同时执行这两项操作外部的重定向(对客户端可见),以及内部的重定向(内部完成,无需向客户端发出任何中间回复)。

这种内在与外在的差异是一种很强大概念,没有它许多凉爽的技巧这是不可能的,因为配置语言足够简单,可以限制if语句中可用的指令数量,并且不允许嵌套if语句。

因此,使用内部重定向,$uri可以在内部进行更改,导致您的请求在多个独立位置之间来回跳转(将每个位置视为locationDFA(确定性有限自动机)中的一个状态),直到达到所需的结果(有关这种情况的极端示例,请查看http://mdoc.su/,如图所示nginx.conf 2016)。


总结,在上面的例子中:

  • 我们重新将429 error_page用作到internal的重定向internal location,然后以与internal location处理非内部位置完全相同的方式处理它,只是添加了一些额外的变量或指令;

  • 我们还使用=参数来error_page指令指示 nginx 实际上不要将429代码发送回客户端,而是让进一步的处理决定最终的状态代码应该是什么。

相关内容