![扩展现有的位置配置而不是覆盖它](https://linux22.com/image/766547/%E6%89%A9%E5%B1%95%E7%8E%B0%E6%9C%89%E7%9A%84%E4%BD%8D%E7%BD%AE%E9%85%8D%E7%BD%AE%E8%80%8C%E4%B8%8D%E6%98%AF%E8%A6%86%E7%9B%96%E5%AE%83.png)
我拥有的
我已将 Nginx 配置为处理所有虚拟主机的 .php 文件,并且一切运行正常。
location ~ \.php {
include snippets/fastcgi-php.conf;
keepalive_timeout 0;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
}
以上内容位于snippets/common.conf
并包含在每个虚拟主机配置中。 前面提到的内容fastcgi-php.conf
位于其旁边。
我需要的
对于给定的虚拟主机,我需要拒绝除之外的所有文件的访问/example.php
。
我尝试过
-
location ~ ^/example { allow all; } location ~ ^/ { allow 123.123.123.123; deny all; }
限制本身工作正常,但现在 PHP 文件作为源文本返回,而不是被处理。这意味着上面的内容以某种方式覆盖了之前的
location ~ \.php
,尽管我甚至没有.php
在这里包含扩展。 创造
common-php.conf
include snippets/fastcgi-php.conf; keepalive_timeout 0; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/run/php/php7.4-fpm.sock;
重复使用
common.conf
:location ~ \.php { include snippets/common-php.conf; }
在我的实际虚拟主机配置中:
location ~ ^/example { allow all; include snippets/common-php.conf; } location ~ ^/ { allow 123.123.123.123; deny all; include snippets/common-php.conf; }
上述问题在于:
- 它使设置变得非常复杂
/example.php
配置两次似乎多余- 它没有完全工作,因为我
/plugins/Feedback/angularjs/feedback-popup/feedback-popup.directive.html?cb=abcd1234
出于某种原因在 eg 上得到了 403。我使用的 CMS 很复杂,由于前两个原因,我没有进一步调查。
我想配置对/example.php
文件的访问,但不覆盖它所附加的现有 PHP 处理程序。这可能吗?还是包含是我唯一的选择?
如果您能想到更好的配置来完成这项任务,请告诉我。谢谢!
答案1
也就是说,一个非常常见的错误是这样做
location / {
... some settings
}
location /admin {
... additional settings
}
并期望该/admin/...
请求将使用组合设置。但事实并非如此,根据请求最终被处理的位置,只会应用一个设置集。然而,正如我已经说每个请求都可以遍历多个位置块,并且可以使用变量操作来实现一些技巧。当请求经过不同的位置时,某个变量可能会被多次更改,并且其实际值可以在最终位置用作某些指令参数。本问题解决方案不会使用这种技术,但在其他一些情况下是可能的。
很多东西(例如条件标头)都可以使用(非常强大的)nginx 功能来实现。 /规则map
的替代方案可以通过结合以下方式实现:allow
deny
map
和geo
块来评估一个变量,作为一个标志来指示请求是否应该被阻止(可以找到一些更通用的例子这里):
map $uri $restricted {
/example.php 0;
default 1;
}
geo $deny {
123.123.123.123 0;
default $restricted;
}
现在要决定是否应该阻止请求,您可以使用以下if
阻止:
if ($deny) { return 403; }
它可以放置在级别server
或 PHP 处理程序位置。但是,将其放置在级别server
会更理想,因为它将在更早的位置执行,NGX_HTTP_SERVER_REWRITE_PHASE
而不是在NGX_HTTP_REWRITE_PHASE
。
如果由于某种原因您想要添加基本身份验证而不是 IP 过滤,则可以使用以下技巧来实现:
map $uri $restricted {
/example.php off;
default "Protected area";
}
geo $realm {
123.123.123.123 off;
default $restricted;
}
location ~ \.php$ {
auth_basic $realm;
auth_basic_user_file /path/to/.htpasswd;
...
}