passthru在Nginx+PHP-FPM下默认不可用,根本原因是PHP的disable_functions配置主动禁用该函数,而非Nginx或PHP-FPM配置错误;其调用会静默失败或导致500错误,因PHP-FPM子进程加载php.ini后立即生效该安全限制。

passthru 在 Nginx + PHP-FPM 环境下默认不可用,不是配置错,是被 disable_functions 主动禁用了——这是生产环境的强制安全策略,不是 bug。
为什么 passthru 调用直接返回空或报 500
根本原因不是 Nginx 或 PHP-FPM 配置问题,而是 PHP 运行时已通过 disable_functions 指令明确拦截了该函数。Nginx 本身不参与函数级权限控制,但 PHP-FPM 子进程加载 php.ini 后会立即生效该限制。
- 现象:脚本中写
passthru('whoami');,页面空白、无输出、无错误(display_errors = Off时更隐蔽) - 验证方式:在脚本开头加
var_dump(function_exists('passthru'));,结果为false - 查禁用列表:执行
php -i | grep disable_functions,大概率看到passthru出现在逗号分隔的字符串里 - 注意:即使你在
php.ini里没手动写这一项,某些发行版(如 CentOS + remi 源)、Docker 镜像(如php:7.3-fpm)或安全加固脚本会默认注入该限制
能否临时启用 passthru?风险在哪
技术上可以删掉 disable_functions 里的 passthru,但必须同步评估后果:
- 它和
exec、shell_exec、system属同一类高危函数,允许任意命令执行,一旦 Web 入口存在未过滤的参数(比如文件名、用户名、URL 参数),极易被用于远程代码执行(RCE) - PHP-FPM 是多请求复用进程,只要一个请求触发了恶意命令,整个 worker 进程就可能被劫持
- Nginx 日志里看不到命令执行痕迹,攻击行为极难审计
- 若你用的是共享主机、SaaS 平台或合规要求严格的环境(如等保三级),启用它直接违反基线要求
替代方案:不碰 passthru 怎么达成同样效果
绝大多数真实场景其实不需要原始 shell 命令穿透——换思路比开后门更可靠:
立即学习“PHP免费学习笔记(深入)”;
- 想读系统信息(如内存、负载)?用
sys_getloadavg()、memory_get_usage()、disk_free_space()等内置函数,安全且跨平台 - 想调外部二进制(如
ffmpeg、convert)?改用proc_open()+ 显式白名单路径 +chroot或容器隔离,再配合超时与输出截断 - 想执行固定脚本(如备份任务)?把逻辑封装成独立 CLI PHP 脚本,用
systemd或cron定时跑,Web 层只发信号(如写标志文件、发 Redis 消息) - 调试阶段真要临时看命令输出?在开发机用 CLI 模式运行:
php -r "passthru('ls -l');",避免污染线上环境
真正棘手的从来不是“怎么让 passthru 工作”,而是“谁授权它工作、在什么上下文里工作、出事了怎么追溯”。生产环境里,函数是否可用,本质是信任边界的体现——别让它越界。



















