给出以下配置(简化为相关部分):
/etc/nginx/nginx.conf:
http {
# ... general configuration stuff here ...
map $http_user_agent $isbot_ua {
default 0;
~*(GoogleBot|bingbot|YandexBot|mj12bot|PetalBot|SemrushBot|AhrefsBot|DotBot|oBot) 1;
}
map $isbot_ua $limit_bot {
0 "";
1 $binary_remote_addr;
}
limit_req_zone $limit_bot zone=bots:10m rate=2r/m;
limit_req_log_level warn;
limit_req_status 429;
include sites.d/vhost_*.conf;
}
/etc/nginx/sites.d/vhost_example.org.conf:
server {
# ... general vhost config here ...
location / {
index index.php index.html index.htm;
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ ^(.+?\.php)(/.*)?$ {
try_files /does-not-exist-099885c5caef6f8ea25d0ca26594465a.htm @php;
}
location @php {
try_files $1 =404;
include /etc/nginx/fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)\$;
fastcgi_param SCRIPT_FILENAME $document_root$1;
fastcgi_param PATH_INFO $2;
fastcgi_param HTTPS on;
fastcgi_pass unix:/var/lib/php/11-example.org-php-fpm.socket;
fastcgi_index index.php;
}
}
在/etc/nginx/fastcgi_params中:
limit_req zone=bots burst=5 nodelay;
# ... more fastcgi_param here ...
问题如下:
每个与机器人 UA 匹配的请求(无论是通过映射到的虚拟 URL/index.php
还是直接指向的本机 URL index.php
)都将导致响应代码 404 而不是预期代码 200 - 除非当它突然以预期代码 429 响应时我超出速率限制。
如果我将地图更改为:
map $request_uri $is_req_limited {
default 0;
# ~*(GoogleBot|bingbot|YandexBot|mj12bot|PetalBot|SemrushBot|AhrefsBot|DotBot|oBot) 1;
}
在这种情况下,所有请求都会得到 200 的答复。如果我没有匹配任何机器人,情况也是如此。
问题是:它在我们的部署前测试中运行正常,该测试具有更简单的 vhost 配置(我们limit_req
在部署期间从全局配置移至 fastcgi 部分,因为我们只想匹配页面生成,缓存页面和静态资源都可以)。这完全毁掉了我们网站的 SEO 排名。
测试所用命令:
# Causes the problem:
for i in $(seq 1 30) do; curl -Is -A GoogleBot https://example.org/ | head -n1; done
# Does not cause the problem:
for i in $(seq 1 30) do; curl -Is -A ThisIsNotABot https://example.org/ | head -n1; done
这是错误还是配置错误?如果是错误,是否可以解决?
边注:几乎不可能阻止这种有点奇怪的配置,因为它是由主机管理软件(Froxlor)生成的,但我认为它可能会导致问题。我们也无法在此处添加或修改任何配置:
location ~ ^(.+?\.php)(/.*)?$ {
try_files /does-not-exist-099885c5caef6f8ea25d0ca26594465a.htm @php;
}
location @php {
try_files $1 =404;
#...
我不知道是否limit_req
将其放置在里面会更好location ~ ^(.+?\.php)(/.*)?$
,但另一方面,location @php
应该同样好。
答案1
哎呀,如果我理解正确的话,这个问题很难回答,尤其是因为配置是由 Froxlor 生成的。不过,我可以尝试引导您找到正确的方向,这样您就可以与 Froxlor 开发人员联系。
因此,这取决于我对 Nginx 的了解。据我从您的问题中了解到,这看起来不像是一个错误。但更像是一个配置/顺序问题。以下是我这么认为的原因:
当请求进入时/
,Nginx 首先检查位置块以查看将请求路由到哪里。在您的配置中,@php
由于您的try_file
指令,此请求被路由到该位置。因此,limit_req
fastcgi_params 文件中应用的指令仅影响由 FastCGI 处理的请求。但正如您所描述的,机器人正在攻击/
由 Nginx 直接处理的请求。
我的意见是,如果将limit_req
指令移动到位置/
配置块,如下所示:
location / {
index index.php index.html index.htm;
try_files $uri $uri/ /index.php$is_args$args;
limit_req zone=bots burst=5 nodelay;
}
您应该注意到,所有传入请求(无论是由 Nginx 还是 FastCGI 机器人处理)都受到速率限制。而且您不应该再收到突然出现的奇怪的 404 错误。
点击此处查看更多相关信息:Nginx 中的速率限制