相同的正则表达式在 Apache 和 Nginx 中表现不同

Same regex behaving differently in Apache and Nginx

我正在尝试将 5G Blacklist 从 Apache(.htaccess) 转换为 Nginx(.conf)。 .htaccess 中有一行导致问题:

<IfModule mod_alias.c>  
    RedirectMatch 403 (\,|\)\+|/\,/|\{0\}|\(/\(|\.\.\.|\+\+\+|\||\\"\\")  
</IfModule>

我已将其转换为 .conf 如下:

http 块中包含的代码

map $request_uri $bad_uri {  
    default 0;  
    "~*(\,|\)\+|/\,/|\{0\}|\(/\(|\.\.\.|\+\+\+|\||\\"\\")" 1;  
}  

服务器块中包含的代码

if ($bad_uri) {  
    return 403;  
}  

据我所知,Apache 和 Nginx 都使用 perl regex,因此在从前者转换为后者时不需要进行任何更改。但是,以下 URI 在 Nginx 上给出 403,但在 Apache 上运行良好:

www.example.com/some,url,with,commas
www.example.com/?q=some,url,with,commas

终于找到问题了。

在 Apache 中 RedirectMatch 只匹配没有查询字符串的 url 而 nginx 中的 $request_uri 映射到url 带有查询字符串。

所以 Nginx 的正确代码是:

map $uri $bad_uri {  
default 0;  
"~*(\,|\)\+|/\,/|\{0\}|\(/\(|\.\.\.|\+\+\+|\||\\"\\")" 1;  
}