必须在cli和web(fpm/apache)各自对应的php.ini中严格配置disable_functions(全小写、零空格、含pcntl_*等全量函数),重启服务后,通过php -r实测exec/system及phpinfo()核对生效,并同步设置open_basedir与opcache.restrict_api防绕过。

在 CentOS 7 上搭建 PHP 7.4.33 环境后,禁用危险函数不是“加一行就完事”,而是必须确认生效路径、语法无误、多环境验证的闭环操作。PHP 7.4.33 是 PHP 7 系列最终版,虽已停止维护,但仍在不少生产环境运行,其 pcntl_*、proc_open 等函数若未严格限制,极易被用于远程命令执行或 Webshell 提权。
确认实际生效的 php.ini 文件位置
CLI 和 Web(FPM/Apache)加载不同配置,改错文件等于没改:
- Web 环境:新建
info.php,内容为<?php phpinfo(); ?>,访问后搜索 “Loaded Configuration File” - CLI 环境:执行
php --ini,看 “Loaded Configuration File” 行(不是 “Configuration File Path”) - FPM 常见路径是
/etc/php/7.4/fpm/php.ini,Apache 下则是/etc/php/7.4/apache2/php.ini
正确配置 disable_functions 并重启服务
语法错误会导致整行被忽略,且不报错:
- 值必须全小写、逗号后**零空格**、无换行、无末尾逗号
- 推荐完整列表(含绕过常用函数):
exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_alarm,pcntl_getpriority,pcntl_setpriority,eval,assert,dl,ini_alter,openlog,syslog,chmod,chown,chgrp,symlink,link,file_put_contents - 改完后必须重启对应服务:
sudo systemctl restart php7.4-fpm(Nginx+PHP-FPM)或sudo systemctl restart httpd(Apache)
补充关键安全限制:open_basedir + opcache.restrict_api
仅禁函数不够,攻击者仍可能写入文件再通过 include 执行:
- 在同个 php.ini 中设置:
open_basedir = /var/www/html:/tmp(确保包含上传和缓存所需目录) - 启用 OPcache 并限制 API:
opcache.enable = 1
opcache.restrict_api = "/dev/null"(PHP 7.4+ 支持,防路径泄露与 JIT 利用) - Nginx + PHP-FPM 下务必检查:
security.limit_extensions = .php(防止.php5、.phtml绕过解析)
实测验证是否真正生效
不能只看 phpinfo(),要走真实调用链:
- CLI 测试:
php -r "var_dump(exec('id'));"应输出NULL并带警告 - Web 测试:建
test.php,内容<?php echo system('whoami'); ?>,访问应空白或报 500 错误 - 检查是否遗漏:
php -r "echo ini_get('disable_functions');"输出应与配置完全一致 - 重点测试业务流:上传文件、后台导出、日志写入、Composer 自动加载,避免因
file_put_contents或symlink被禁导致功能静默中断
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











