我正在尝试使用 limit_conn 和 limit_req 保护在 Nginx 上运行的 Drupal 免受简单 DDoS 攻击。但我遇到了一些与limit_conn
指令继承有关的奇怪行为,我无法解释。
我已将 nginx(1.8.0)配置降低到最低限度,这显示了问题:
limit_conn_zone $binary_remote_addr zone=perip:10m;
server {
server_name test.dev;
root /var/nginx/drupal; ## <-- Your only path reference.
#Allow not more than 10 simultaneous connections from one address.
limit_conn perip 10;
location / {
#limit_conn perip 1;
# This is cool because no php is touched for static content
try_files $uri @rewrite;
}
location @rewrite {
# Clean URLs are handled in drupal_environment_initialize().
rewrite ^ /index.php;
}
location ~ \.php$ {
#Allow not more than 1 simultaneous *connection_to_PHP* from one address.
limit_conn perip 1;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi.conf;
fastcgi_intercept_errors on;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
}
如您所见,我想将所有请求的同时连接数限制为 10 个,将 php 后端的同时连接数限制为 4 个。(在这个例子中我把 4 个连接修改为 1 个,这样会更容易触发)
Nginx 文档位于http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn指出:
limit_conn
当且仅当当前级别没有指令时,这些指令才会从上一级别继承。
但是在我的测试中发生了一些奇怪的事情,看起来 nginx 忽略了块limit_conn
内的指令location ~ \.php$
:
- 当我使用 5 个同时连接测试此配置时
ab -n 100 -c 5 http://test.dev/
,没有发生阻塞。一旦我将
限制提高到 11,-c 11
nginx 就会开始阻止请求。 - 如果我将全局连接限制从 10 修改为 5,则 nginx 将限制超过 6 个连接(
-c 6
) - 看起来location ~ \.php$
块中的指令被忽略了。 - 如果我删除
conn_limit
服务器级别的指令,块中的指令location ~ \.php$
就会突然开始工作! - 更令人困惑的是:如果我将
conn_limit
指令添加到location /
阻止中,它会正确地覆盖全局指令!
也许问题出在指令或多个重定向上?如果有人能解释为什么指令没有像预期的那样被覆盖,try_files
我将非常感激。conn_limit
答案1
感谢@AlexeyTen,我希望能够回答这个问题。
重要的是两点:
limit_conn
每个请求仅处理一次该指令!limit_conn
当且仅当当前级别没有指令时,这些指令才会从上一级别继承。
TL;DR:如果有limit_conn
指令,nginx 会在执行链中查看子块,如果没有limit_conn
,则处理父块。此后,所有其他limit_conn
指令都将被忽略。
我尝试用我的例子来解释它:
在我发布的例子中,当“http://test.dev/“请求到达时,起初 nginx 不在级别limit_conn
上处理server
,而是等待查看匹配的位置location /
。但是在这个级别上没有limit_conn
指令,所以 nginx 处理该级别的指令server
。之后,所有limit_conn
指令都将被忽略,因为它已经被处理了。这解释了我的测试 1-3。
在测试 4 中,nginxlimit_conn
在 location 中找到了一条指令location /
并对其进行了处理,但同样,在 location 上location @rewrite
没有limit_conn
找到,因此处理了 处的指令location /
。同样,我们忽略了该location ~ \.php$
块。