PHP 服务器加固实战:关闭版本暴露、禁用危险函数

一、先搞清楚:改的是哪一个 php.ini

一台机器上通常有两个 PHP 配置:CLI(命令行,供 wp-cli、定时任务使用)和 FPM(Web 请求由 php-fpm 处理)。网站对外的安全加固应当改 FPM 那份:

# 以 PHP 8.5 为例
/etc/php/8.5/fpm/php.ini      # Web 服务,要加固这一份
/etc/php/8.5/cli/php.ini      # 命令行,建议保持默认,否则可能破坏 wp-cli 等运维工具

改之前先确认部署方式:

php -v
ps aux | grep -E "php-fpm|php-cgi"
grep -rEn "fastcgi_pass|php-cgi" /etc/nginx

二、关闭版本暴露:expose_php = Off

默认 expose_php = On 会让响应头带上 X-Powered-By: PHP/8.5.4,等于主动告诉攻击者你的具体版本,方便其对照已知 CVE(如 CVE-2024-4577 这类 PHP-CGI 参数注入)做针对性利用。关掉它属于低成本的“信息收敛”。

sed -i -E 's/^expose_php = On/expose_php = Off/' /etc/php/8.5/fpm/php.ini

验证(重启后看不到该响应头即生效):

curl -sI https://你的域名/ | grep -i x-powered-by   # 应无输出

三、禁用危险函数:disable_functions

大多数 webshell 与 RCE 利用链最终都要调用系统命令函数。把它们禁用,即使业务代码存在注入/反序列化等漏洞,攻击者能造成的危害也会被大幅压缩——这是典型的纵深防御。

sed -i -E 's/^;?disable_functions =.*/disable_functions = exec,passthru,shell_exec,system,proc_open,popen/' /etc/php/8.5/fpm/php.ini
  • exec / system / shell_exec / passthru:直接执行外部命令;
  • proc_open / popen:打开进程管道,常被武器化;
  • 列表可按业务裁剪,若某插件报错,再按需从列表中移除对应函数,不要一删了之。

四、改完必须重启 php-fpm

修改 php.ini 后只有重启(不是 reload)才会生效:

systemctl restart php8.5-fpm
# 或 service php8.5-fpm restart

重启后务必回归验证:

php -i | grep -iE "expose_php|disable_functions"   # 注意这看的是 CLI;FPM 需用 curl 头验证

五、其它加固项(回顾与基线)

  • 不用 php-cgi 直出:用 php-fpm + 反向代理,避免 CVE-2024-4577 类 CGI 参数注入的攻击面;
  • allow_url_include = Off:杜绝远程文件包含,这是 RCE 类漏洞的关键开关;
  • 保持 PHP 在受支持版本:旧版本停止安全支持后,唯一修复方式就是升级;
  • 入口层 WAF + 运行时监控:拦截可疑请求与异常进程/外连;
  • uploads 目录禁止执行 PHP:在 Nginx 中对 wp-content/uploads 的 *.php 直接 return 403。

六、一键加固脚本(可复用)

#!/usr/bin/env bash
set -e
VER=8.5
FPM=/etc/php/${VER}/fpm/php.ini
grep -q "^expose_php" "$FPM" && 
  sed -i -E 's/^expose_php = On/expose_php = Off/' "$FPM" || 
  echo "expose_php = Off" >> "$FPM"
sed -i -E 's/^;?disable_functions =.*/disable_functions = exec,passthru,shell_exec,system,proc_open,popen/' "$FPM"
systemctl restart php${VER}-fpm
echo "已加固并重启 php-fpm"

七、上线前验证清单

  1. curl -sI 站点 无 X-Powered-By 头;
  2. php -i(FPM 视角)中 disable_functions 已含禁用函数;
  3. 网站前台与后台功能正常,无插件因禁用函数报错;
  4. PHP 处于受支持版本,php-cgi 未对外暴露。

把“关闭版本暴露 + 禁用危险函数”作为每台 PHP 服务器的基线动作,配合版本升级与 WAF,就能把 PHP2Shell 一类风险的落地难度显著提高。