You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:35:44