root运行PHP脚本时proc_open访问其他用户文件权限被拒问题
问题原因及解决方案
原因分析
你遇到的问题是由Linux内核的fs.protected_regular安全参数导致的。AlmaLinux 9(基于RHEL 9)默认开启了该参数(值为1),它会限制root用户对不属于自己的普通文件执行写入/截断操作——即便文件权限设置为777,这个限制依然生效,目的是防止root误操作或被恶意利用修改普通用户的文件。
你的脚本中proc_open的第三个描述符指定了/tmp/foo.bar以w模式打开,当该文件属于admin用户时,root尝试打开并截断它的行为就会被这个内核参数阻止,触发权限拒绝错误。
验证方法
执行以下命令查看该参数的当前值:
sysctl fs.protected_regular
如果输出为fs.protected_regular = 1,则说明该安全机制处于开启状态。
解决方案
方案1:让PHP自动创建文件
删除已存在的/tmp/foo.bar,root运行脚本时会自动创建属于root的文件,此时就不会触发权限限制:
rm -f /tmp/foo.bar ./test.php
方案2:替换为管道接收错误输出
修改脚本,将错误输出从文件改为管道,避免涉及其他用户的文件:
#!/usr/bin/php <?php // 将第三个描述符改为管道 $ph = proc_open('whoami', [['pipe','r'],['pipe','w'],['pipe','w']], $fds); if ($ph) { echo 'command output: ' . stream_get_contents($fds[1]); // 可以选择读取错误输出或直接关闭 fclose($fds[2]); proc_close($ph); } else { echo 'proc_open failed' . PHP_EOL; }
方案3:临时/永久关闭内核参数(不推荐)
如果必须使用现有文件,可以临时关闭该限制(重启后失效):
sysctl -w fs.protected_regular=0
若要永久生效,编辑/etc/sysctl.d/99-custom.conf(或类似配置文件),添加以下内容:
fs.protected_regular=0
然后执行命令生效:
sysctl --system
注意:该参数是系统安全机制,关闭后会降低系统安全性,仅在必要时使用。
内容的提问来源于stack exchange,提问作者miken32
相关产品推荐
相关产品推荐

