必须分层拦截:Nginx 层用 fastcgi_hide_header X-Powered-By(置于 location ~ .php$ 块内)、PHP 层设 expose_php = Off 并重启 php-fpm、同时修改 fastcgi.conf 中 SERVER_SOFTWARE 为精简值,并验证错误页与 phpinfo() 等潜在泄露点。

要让 Nginx 通过 fastcgi_hide_header 隐藏后端动态框架(如 PHP、Laravel、ThinkPHP 等)返回的敏感响应头(例如 X-Powered-By: PHP/8.2.12),关键不是只加一行配置,而是分层拦截:Nginx 层隐藏传输头 + FastCGI 层切断变量注入 + PHP 层关闭自身暴露。否则容易出现「curl -I 看不到,但打开错误页又露馅」的情况。
明确目标:哪些头需要隐藏?
常见需隐藏的响应头包括:
-
X-Powered-By(PHP 默认输出,含 PHP 版本) -
Server(Nginx 自身版本,靠server_tokens off控制) -
X-AspNet-Version(IIS 场景,不适用于 phpEnv) -
Server-Side或自定义框架头(如某些 Laravel 调试页带的X-Runtime或X-PHP-FPM)
在 Nginx 中用 fastcgi_hide_header 拦截 X-Powered-By
该指令仅对 FastCGI 协议上游(即 PHP-FPM)返回的响应头生效,必须放在 location ~ \.php$ 块或 fastcgi_params 引入前的位置。示例配置:
location ~ \.php$ {
include fastcgi.conf;
fastcgi_hide_header X-Powered-By;
fastcgi_pass 127.0.0.1:9000; # 或 unix:/path/to/php-fpm.sock
}⚠️ 注意:fastcgi_hide_header 不支持正则或通配符,只能逐个写;若同时用代理(如反向代理到 Node.js),应改用 proxy_hide_header。
同步关闭 PHP 自身的版本暴露
Nginx 的 fastcgi_hide_header 只能过滤响应头,但 X-Powered-By 是 PHP 内核直接写的,关掉它才治本:
- 编辑
php.ini,找到并修改:expose_php = Off - 改完后务必重启 php-fpm(在 phpEnv 界面点「重启 PHP」,或执行
php-fpm -s reload) - 验证方式:访问一个 PHP 页面,执行
curl -I http://localhost/info.php | grep -i "x-powered-by",应无输出
别漏掉 FastCGI 传递的 SERVER_SOFTWARE 变量
即使响应头隐藏了,PHP 脚本仍可通过 $_SERVER['SERVER_SOFTWARE'] 读到 nginx/1.24.0 —— 这是因为 phpEnv 的 fastcgi.conf 默认有这一行:
fastcgi_param SERVER_SOFTWARE "nginx/$nginx_version";
必须手动改为:
-
fastcgi_param SERVER_SOFTWARE "nginx";(推荐,简洁真实) - 或
fastcgi_param SERVER_SOFTWARE "Apache";(仅混淆用,不影响功能)
路径通常为:phpenv/nginx/conf/fastcgi.conf(具体以你的安装目录为准)。修改后运行 nginx -t && nginx -s reload 生效。
额外检查点:错误页与 phpinfo()
即使上述全做了,仍可能在以下位置泄露版本:
- 500 错误页底部文字(Nginx 默认错误页含版本)→ 需配合
error_page 500 /50x.html+ 自定义静态页 -
phpinfo()页面底部「Apache Environment」或「HTTP Headers」区域 → 生产环境务必删除或限制访问 - 某些框架调试模式(如 Laravel APP_DEBUG=true)会主动打印服务器信息 → 确保生产环境关闭调试

















