![通过 php 调用时不允许 setresuid 操作](https://linux22.com/image/974465/%E9%80%9A%E8%BF%87%20php%20%E8%B0%83%E7%94%A8%E6%97%B6%E4%B8%8D%E5%85%81%E8%AE%B8%20setresuid%20%E6%93%8D%E4%BD%9C.png)
我遇到了以下问题:我的 Apache 和 PHP 脚本以用户 www-data 身份运行。
我想调用一个只能以 root 身份执行的脚本,因此我向 /etc/sudoers.d 添加了一个新文件,以允许 www-data 用户执行此命令:
echo390:/var/www/html# cat /etc/sudoers.d/iptables
www-data ALL= NOPASSWD: /sbin/iptables
我的PHP脚本如下:
<?php
$command = '"/usr/bin/sudo" "/sbin/iptables" -L -v -n | grep "220.177.198.43"';
echo 'Benutzer: '.exec('whoami').'<br/>';
echo 'Command: '.$command.'<br/>';
$result = array();
exec($command,$result);
print_r($result);
?>
如果我通过以下方式从命令行调用脚本:sudo -u www-data /usr/bin/php test.php 一切都会按预期运行,但是当我通过 Apache 调用脚本时,我在 apache2/error.log 中收到以下错误:
sudo: PERM_ROOT: setresuid(0, -1, -1): Operation not permitted
我已经将 Ubuntu 从 12.02 升级到 14.04。同样的脚本在 Ubuntu 12.02 中运行没有任何问题。有人能帮我吗?错误在哪里?
www-data 的群组:
echo390:~$ groups www-data
显示
www-data : www-data
作为信息:
我使用Apache-mpm-itk 模块
这样每个 Apache 虚拟主机都在单独的用户 ID 下运行。那么如何允许特定 Apache 用户以 root 权限执行特定 shell 脚本(在 php 等中)?
提前致谢并致以亲切的问候 Ravermeister
答案1
修复apache2.4
并将mpm-itk
其放置在/etc/apache2/conf-enabled/security.conf
<IfModule mpm_itk_module>
LimitUIDRange 0 6000
LimitGIDRange 0 6000
</IfModule>
然后重新启动apache
。
这不是必需的,apache2.2
但是一旦我升级到apache2.4
正在使用的 PHP 脚本,shell_exec
它就会sudo
停止工作。
答案2
我发现建议禁用 mpm-itk 相当奇怪,因为实际使用它可能有原因。
我们将 mpm-itk(版本 2.4.7-02)与 apache 2.4 结合使用,效果非常好。这里唯一需要考虑的是新的配置指令
LimitUIDRange
和
LimitGIDRange
这些指令定义 mpm-itk 可以使用哪些 UID 和 GID(通过 setuid/setguid)。由于您显然希望它能够成为 root,因此您的下限范围必须是 ID 0。以下配置将在此处起作用:
<IfModule mpm_itk_module>
LimitUIDRange 0 6000
LimitGIDRange 0 6000
</IfModule>
请注意,上边界应该包括您想要通过 AssignUserID 在配置中使用的所有用户 UID/GID 组合。
请注意,您可以为每个虚拟主机配置此功能。还请注意,您需要 Linux 内核 3.5.0 或更高版本才能实现此功能。
答案3
您的 sudoers 配置是正确的,事实上当您执行:
sudo -u www-data /usr/bin/php test.php
它按预期工作。
在正常运行中,您的阿帕奇运行为根并使用mpm-itk模块。这就是问题所在。
根据mpm-itk 文档:
由于 mpm-itk 必须能够设置用户标识(),它以 root 身份运行(尽管在可能的情况下受到 POSIX 功能和 seccomp v2 的限制),直到请求被解析并且 vhost 确定。
和:
mpm-itk 基于传统的 prefork MPM,这意味着它是非线程化的;... 您还会比 prefork 承受额外的性能损失,因为每个请求都有一个额外的 fork。
这意味着mpm-itk叉阿帕奇处理并使用 setuid() 以便为每个虚拟主机分配所需的用户。
根据setuid 手册:
setuid() 函数检查调用者的有效用户 ID,如果是超级用户,则所有与进程相关的用户 ID 都设置为 uid。发生这种情况后,程序将无法重新获得 root 权限。
这已经可以解释,但不相信,我下载了源代码mpm-itk我注意到它发生了变化能力允许并限制uid范围从1到UINT_MAX。
如果线程从其允许集中删除一项能力,则它永远无法重新获得该能力
我的结论是,通过使用mpm-itk你的 php 脚本无法获得 root 权限。
如果有机会,你可以检查是否正在运行阿帕奇作为www-数据并禁用mpm-itk模块你的测试.php作品。