如何在Nginx中拦截.php文件请求 现有配置不生效如何解决
问题原因排查
- 配置优先级冲突
你当前server块中先执行了include /etc/nginx/default.d/*.conf;语句,绝大多数Linux发行版的Nginx默认会在该目录下存放php-fpm处理配置,其中包含优先级更高的.php后缀匹配规则,会先于你写的internal拦截规则生效,导致你的拦截逻辑完全不执行。 - 路径拦截规则错误
你配置了location ^~ /my { deny all; return 404; },直接拦截了所有/my开头的请求,你需要允许的/my/mypage路径本身就会被这条规则拦截,无法正常访问。 - php处理逻辑缺失
你写的.php匹配规则中只有internal指令,没有配置fastcgi_pass转发到php-fpm的逻辑,就算内部重定向的无后缀请求也无法正常解析php文件。 - 正则匹配顺序错误
Nginx的正则location匹配按书写顺序生效,你把普通.php拦截规则写在了main.php精确匹配之后,逻辑冗余且容易出现匹配错位。
修复方案
- 先删除
/etc/nginx/default.d/目录下默认的php处理配置文件,或者将你自己的规则写在include /etc/nginx/default.d/*.conf;语句之前,确保你的规则优先匹配。 - 删掉错误的
location ^~ /my { deny all; return 404; }规则。 - 替换你的server块为以下配置:
server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/public_html; index main.php; error_page 403 404 /error/error.php; # 拦截所有直接访问.php后缀的外部请求,仅允许内部重定向访问 location ~ \.php$ { internal; # 配置你的php-fpm监听地址,一般为9000端口或者unix套接字,按需修改 fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # 拦截其他不需要的后缀请求 location ~ (\.html|.aspx|.asp|myadmin) { return 404; } # 无后缀路径处理逻辑 location / { # 仅允许指定的两个无后缀路径访问,其余路径直接返回404 if ($request_uri !~ ^/(main|my/mypage)$) { return 404; } # 对应php文件存在时执行内部重写 if (-e $request_filename.php) { rewrite ^/(.*)$ /$1.php last; } } location ~ (^|/)\. { return 403; } location = /errorpage_404.html { root /usr/share/nginx/public_html; internal; } }
- 配置修改完成后执行
nginx -t测试配置语法是否正确,确认无错误后执行systemctl reload nginx重载配置生效。
内容的提问来源于stack exchange,提问作者Yongjun Kim
相关产品推荐
相关产品推荐

