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

Qui*_*Par 3 nginx rate-limiting

这个答案非常适合绕过 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
Run Code Online (Sandbox Code Playgroud)

cns*_*nst 6

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

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

http {
    map $http_x_secret_header $limit {
        default      $binary_remote_addr;
        secretvalue  "";
    }
    limit_conn_zone      $limit    zone=connlimit:10m;
    …
Run Code Online (Sandbox Code Playgroud)

参考:


cns*_*nst 5

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

这是向您展示一切正常的测试,包括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
%
Run Code Online (Sandbox Code Playgroud)

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


让我解释一下奇怪error_page答案的基本原理- 在 nginx 中,您可以进行外部重定向(对客户端可见),也可以进行内部重定向(在内部完成,无需对客户端进行任何中间回复)。

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

因此,相反,通过内部重定向,$uri可以在内部更改,导致您的请求在多个独立位置之间来回跳动(将每个位置location视为 DFA(确定性有限自动机)中的一个状态),直到获得所需的结果(对于这方面的一个极端示例,请查看http://mdoc.su/,如nginx.conf 2016 所示)。


总结一下,在上面的例子中:

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

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

  • 主啊,因为有你这样的人,这个世界变得更美好了…… (3认同)