我最近部署了我的第一个 nginx 设置,一切都运行良好,除了位置解析让我抓狂。我有一个简单的 php fastcgi 设置,如下所示:
location ~ \.php {
if (!-e $request_filename) {
return 404;
}
include /etc/nginx/fastcgi.conf;
keepalive_timeout 0;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
}
现在我想用这样的基本身份验证来保护一些位置:
location /madmin {
auth_basic "Restricted";
auth_basic_user_file /var/www/localhost/admincp/.htpasswd;
}
按照此设置,nginx 在访问 /madmin 时会要求输入密码,但在 /madmin/foo.php 时不会要求输入密码。如果我将身份验证位置更改为“location ~ ^/madmin”之类的位置,则 nginx 会提供 php 文件供下载...
难道不能在 nginx 中配置多个位置吗?如果不行,这里的解决方法是什么?
感谢您的帮助。
答案1
请参见http://nginx.org/en/docs/http/request_processing.html有关 nginx 如何处理请求(包括位置)的描述。wiki 文档也有一些很好的例子。不幸的是,您很可能需要当前未记录的功能。
如前所述,NginX 中只有一个位置获胜;但是,您可能不知道 nginx 支持位置内的位置。因此,您的位置策略实际上可能类似于此示例服务器(0.8.31+ 中的 fastcgi.conf):
upstream my-backend {
localhost:9000;
}
server {
listen 80;
server_name my-awesome-php.site;
root /path/to/root;
# The protected location
location /protected {
auth_basic "Give me codes.";
auth_basic_user_file /path/to/.htpasswd;
location ~ \.php$ {
include fastcgi.conf;
fastcgi_pass my-backend;
}
}
# Normal files (blank location is OK, just means serve from root)
location / {
}
# PHP for normal stuff
location ~ \.php$ {
include fastcgi.conf;
fastcgi_pass my-backend;
}
}
答案2
这样做的原因是 nginx 会选择最具体的位置块。通过正则表达式匹配的位置将优于纯字符串匹配。
因此,当您对 /madmin 有请求时,它会与您的身份验证位置匹配,但以 .php 结尾的任何内容都会首先转到该位置。
位置 ~^ /madmin 不进行解析就提供 php 代码的原因是,如果以下正则表达式匹配,~^ 就会停止搜索。
您可以在此处查看位置文档:http://wiki.nginx.org/NginxHttpCoreModule#location
答案3
这似乎解决了问题,但是它看起来真的很糟糕,有很多位置指令,我认为现在即使是静态文件也是由 php-fastcgi 提供的,但我猜它可以通过重写的 if 指令来解决。
location ~ ^/madmin {
auth_basic "Restricted Access";
auth_basic_user_file /var/www/localhost/admincp/.htpasswd;
include /etc/nginx/fastcgi.conf;
fastcgi_pass 127.0.0.1:9000;
}