Nginx location块中配置fastcgi_pass本质是精准匹配PHP请求并安全转发至PHP-FPM:需用location ~ .php(/|$)防绕过,fastcgi_pass严格匹配PHP-FPM监听地址(如unix:/run/php/php8.2-fpm.sock),SCRIPT_FILENAME应使用$realpath_root杜绝目录穿越,并显式设置fastcgi_index、include snippets/fastcgi-php.conf等必要参数。

Nginx 在 location 块中配置 fastcgi_pass,本质是告诉它:哪些请求该转给 PHP-FPM,以及怎么连过去。关键不在“加一行”,而在匹配准确、参数完整、路径安全。
匹配规则要防误判
只写 location ~ \.php$ 看似简单,但容易被绕过(比如访问 /config.php.jpg 仍可能触发 PHP 解析)。更稳妥的做法是:
-
location ~ \.php(/|$):匹配/index.php或/api/index.php/extra这类真实路由,拒绝带多余后缀的伪装路径 - 若项目入口固定(如 Laravel 的
public/index.php),可加限定:location = /index.php - 配合
try_files $uri =404;,确保.php文件真实存在,避免空文件或路径穿越被利用
fastcgi_pass 必须与 PHP-FPM 监听方式一致
这一行不是随便填的,必须和 PHP-FPM 实际监听地址完全对应:
- Unix socket(推荐同机部署):
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
→ 检查 socket 文件是否存在、权限是否允许 Nginx worker 用户(如www-data)读写 - TCP 方式(跨主机或调试用):
fastcgi_pass 127.0.0.1:9000;
→ 确认 PHP-FPM 的listen = 127.0.0.1:9000且listen.allowed_clients = 127.0.0.1
SCRIPT_FILENAME 参数不能依赖 $document_root
这是最常出问题的地方。直接写 $document_root$fastcgi_script_name 存在目录穿越风险(如 ?file=../../etc/passwd)。应改用:
-
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
→$realpath_root是经过realpath()解析后的绝对路径,能自动消除../
→ 同时需在server或location块中定义root和alias,并确保root路径正确
其他必要参数建议显式设置(不只靠 include fastcgi_params):
-
fastcgi_param PATH_INFO $fastcgi_path_info;(支持框架路由,如/index.php/user/1) -
fastcgi_param REQUEST_METHOD $request_method; -
fastcgi_param QUERY_STRING $query_string; -
include fastcgi_params;放在最后,覆盖基础变量后再补关键项
别忘了基础配套
光有 fastcgi_pass 不够,还缺这几样:
-
fastcgi_index index.php;(指定默认入口文件) -
include snippets/fastcgi-php.conf;(Debian/Ubuntu 系统自带的标准化参数集,比裸fastcgi_params更安全) - 对上传目录(如
/uploads/)单独设location ^~ /uploads/并禁用 PHP 执行,防止 Webshell
配置完务必执行 nginx -t 测试语法,再 systemctl reload nginx 生效。如果页面下载而非执行,优先检查 fastcgi_pass 地址是否拼错、PHP-FPM 是否运行、socket 文件权限是否放开。



















