允许PHP使用root权限执行bash脚本

时间:2010-11-12 19:09:23

标签: php bash exec root

如何允许PHP脚本执行具有root权限的bash脚本?

假设有一个PHP脚本......

<?php
// location: /var/www/script.php
exec("bash /var/scripts/test.sh"); // "sudo bash ..." does not work
?>

和bash脚本......

#!/bin/bash
# location: /var/scripts/test.sh
sudo mkdir /test

当然,PHP和Apache不应该以root身份运行,最多只能使用root权限执行脚本。有什么想法吗?

祝你好运, 神保

6 个答案:

答案 0 :(得分:6)

任何基于PHP的解决方案都会在链的某个位置提供root权限是危险的:有权访问PHP用户的攻击者可以访问root用户,从安全的角度来看这是不可接受的。

我自己从未实现过这个,但我会建议我建议的here:让一个拥有root权限的脚本/ cron作业经常扫描一些位置,从PHP脚本中找到一个工作要做的标志完成 - 例如,具有特定名称的文件或作业数据库中的条目。

如果发现该文件存在,则根脚本执行其操作,并再次删除该文件。

如果您的PHP脚本不需要来自根脚本的直接响应,我认为这是最好的方法。 (当然,根脚本将状态消息写入文件也可以促进响应。)

只要您严格限制PHP可以为root脚本执行哪些类型的作业,这是一个防水的解决方案,因为它不会让root用户进入PHP的业务。

答案 1 :(得分:6)

如果不想等待cron,这里有一个简单的C包装器,你会从php调用。

#include <unistd.h>
#include <errno.h>
#define WEBUID 500
main( int argc, char ** argv, char ** envp ) {
    if( getuid() != WEBUID ) exit(1);
    /* some more security checks */
    if( setuid(geteuid()) ) perror( "setuid error" );
    envp = 0; /* don't want environment - security problem */
    system( "/hardcoded/path/to/script.bash", argv, envp );
}

这个编译好的包装器应该被拥有为root,group“www”并且应该具有“s-bit” chwon root.www wrapper; chmod 4440 wrapper,所以

  • 执行时,他的有效UID将是root
  • 执行它只能分组www(web-server的组)
  • 当调用者的UID不是Web服务器时将退出

答案 2 :(得分:2)

您需要查看incron(文件系统事件的cron)。让php写入文件并设置incron以在关闭写入文件时启动脚本(incron非常具体)。您的脚本可能还应该清理输入文件以防止代码注入,并使用lockfile命令以防止多个Web用户之间的任何竞争条件。

我有一个迷你网络界面,可以使用密码打开匿名FTP或其他服务1小时。 www和普通的特权一样运行www-data(php用户),但incron以root身份调用输入处理脚本。

麦克

答案 3 :(得分:1)

您可能不需要PHP或Apache以root身份运行。如果您拥有对服务器的控制权,您可以使用名为suPHP的Apache模块,并在配置中指定要运行Apache的用户和PHP脚本。您可以逐个站点地执行此操作,因此您只需要为特定域上的脚本运行suPHP。我缺乏建议如何安装它的专业知识,但我有我们的专用服务器公司为我做这个允许github post-receive挂钩调用我的开发服务器上的脚本来触发git pull到开发服务器任何有人推送到github回购。我无法以任何其他方式使用它,因为Apache需要作为本地存储库的所有者运行才能工作。

我只想到了另一个可能的解决方案,基于这里的其他评论 - 您可能能够编写一个简单的PHP脚本来接收来自github钩子的请求,并将一些任意信息写入具有777权限的目录中的文件或者到数据库。然后有一个cron作业,每分钟检查一次该文件或db以查看它是否已更改,如果是,则直接发出git pull请求,因为cron通常以root身份运行。您甚至可以查看文件的时间戳是否已更改以确定是否执行git pull。您可以将您的cron脚本su添加到拥有repos的任何用户,然后发出git pull。这不是一个真正的实时解决方案,但如果cron脚本非常简单,那么每隔一两分钟它就不会让你的系统陷入困境。希望有所帮助。

答案 4 :(得分:0)

使用以root身份运行的守护程序(可能用C语言编写),它会为您启动shell脚本。要从PHP脚本中触发shell脚本执行,只需使用IPC(消息队列)。

看看这里,了解我在说什么:http://php.net/manual/en/function.msg-send.php#114831

答案 5 :(得分:0)

我最近发布了一个项目,允许PHP获取真正的Bash shell并与之交互(如果需要,可以作为root),它解决了exec()和shell_exec()的限制。在此处获取:https://github.com/merlinthemagic/MTS

下载后,您只需使用以下代码:

$shell    = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1  = $shell->exeCmd('/my/bash/script.sh');
//the return will be a string containing the return of the command
echo $return1;

就安全性而言,它比以root身份运行apache要好得多。但让PHP靠近root,总是很棘手。

我构建的项目以两种方式之一实现了root bash shell:

1)你允许apache权限sudo python。

OR

2)每次需要具有root设置的shell时,都会将根凭据传递给对象。

选择你的毒药。 :)阅读文档。