这个答案是完美的处理与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
这些问题的通常原因是,大多数这些指令不能在if语句的范围内使用,因此,如何能够有条件地指定不同的限制?
答案是使用中间variables – 就像在链接的答案中一样,使用variables设置限制,随后,这些variables的值将根据map或if语句而不同。
http { map $http_x_secret_header $limit { default $binary_remote_addr; secretvalue ""; } limit_conn_zone $limit zone=connlimit:10m; …
参考:
FWIIW,我还看到了其他“怪异”的答案 ,你们联系起来的问题 – 它是在2011年撰写的,今天早些时候只有3个提议,而在2014年大约在2014年。 也许有点令人惊讶的是,旧的被忽视的答案确实没有任何问题的工作!
这是我在完整的MVPconfiguration,完全testing:
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"; } }
以下是testing,以显示它的一切工作,包括正确的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_pageredirect实际上也工作!
让我解释奇怪的error_page答案的理由 – 在nginx中,你既可以做外部redirect (对客户端可见),也可以做内部redirect (内部完成,不需要对客户端进行任何中间回复)。
这种内部和外部的区别是一个非常强大的概念,没有这个概念, 很多很酷的技巧是不可能的,因为configuration语言非常简单,足以限制if语句中可用的指令数量,并且不允许嵌套if声明。
因此,对于内部redirect,可以在内部更改$uri ,导致请求在多个独立位置之间跳动(将每个location视为DFA(确定性有限自动机)中的状态),直到获得所需的结果实现(对于这个极端的例子,看一下http://mdoc.su/ ,如在nginx.conf 2016中看到的)。
总结一下 ,在上面的例子中:
我们重新调整429 error_page作为internalredirect到internal location ,然后以非内部位置处理的方式处理这样的internal location ,除了添加一些额外的variables或指令;
我们还使用error_page指令的=参数来指示nginx不实际地将429代码发送回客户端,而是让进一步处理决定最终状态代码应该是什么。