应严格限制php-fpm监听方式:优先使用unix套接字;若用tcp则必须设listen.allowed_clients=127.0.0.1,禁用0.0.0.0或*绑定;配合防火墙封禁9000端口;nginx中fastcgi_pass应指向本地套接字并精简传递参数;关闭fpm-status页面;最后实测验证外部无法访问。

FastCGI 本身不是对外服务接口,而是 Nginx 与 PHP-FPM 等后端处理器之间的内部通信通道。所谓“防止未授权访问内部接口”,本质是切断外部对 FastCGI 监听端点的直连能力,确保只有 Nginx 本机可发起调用。
严格限制 PHP-FPM 监听方式
PHP-FPM 是最常见的 FastCGI 实现,它的监听配置直接决定攻击面大小:
- 优先使用 Unix 套接字(如 /run/php/php-fpm.sock),不走网络协议,天然隔离外部访问
- 若必须用 TCP(如 127.0.0.1:9000),务必在 pool 配置中显式设置 listen.allowed_clients = 127.0.0.1
- 绝对禁止出现 listen = 0.0.0.0:9000 或 listen = *:9000 —— 这等于把 PHP 解释器挂在公网上
系统防火墙兜底封禁端口
即使 PHP-FPM 绑定在 127.0.0.1,也需防火墙做最后一道防线,防配置误改或服务异常重启导致暴露:
- iptables 用户执行:iptables -A INPUT -p tcp --dport 9000 -j DROP
- firewalld 用户执行:firewall-cmd --permanent --add-port=9000/tcp --zone=drop && firewall-cmd --reload
- 若只用 Unix 套接字,则无需开任何端口,但仍建议 INPUT 链默认拒绝,避免其他服务误开高危端口
Nginx 中安全调用 FastCGI 资源
Nginx 的 fastcgi_pass 必须指向本地资源,并精简传递参数,避免泄露敏感上下文:
- 推荐写法:fastcgi_pass unix:/run/php/php-fpm.sock;(比 TCP 更安全)
- 只传递必要变量,例如:fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
- 禁用非必要环境变量转发,如 REMOTE_ADDR、HTTP_USER_AGENT 等,防止信息泄露或被恶意利用
- 关闭 PHP-FPM 状态页(如 /fpm-status),除非真有监控需求,否则加 location ~ ^/fpm-status$ { deny all; }
验证是否真正隔离成功
加固不是配完就结束,必须实测确认外部无法触达:
- 从另一台机器执行:curl -v http://your-server:9000,应无响应或连接被拒
- 检查 PHP-FPM 日志,确认没有来自非 127.0.0.1 的连接尝试
- 用 ss -tlnp | grep :9000 查看监听状态,确认仅绑定在 127.0.0.1 或未监听 TCP











