2010-11-12 249 views
5

如何允许PHP脚本使用root权限执行bash脚本?允许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权限执行。有任何想法吗?

最好的问候, 神保

+4

为什么你需要脚本以root权限运行?您可以通过Apache正在运行的用户更改其访问的资源是否可读(并且必要时可写)? – meagar 2010-11-12 19:11:36

+0

不,我想执行'git pull'和一些'a2dissite' /'a2ensite'。 – Jimbo 2010-11-12 19:13:49

回答

6

任何基于PHP的解决方案,在链的某个时刻给root用户权限是危险的:与访问PHP用户的攻击者可以获取root用户,那就是从安全角度来看,这是不能接受的。

我自己从来没有实现过这个,但我会建议我建议的内容here:使用root权限的脚本/ cron作业频繁地扫描PHP脚本中某个位置的某个位置,以完成工作 - for例如,具有特定名称的文件或作业数据库中的条目。

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

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

只要您严格限制PHP可以为根脚本编写什么类型的作业,这是一个水密解决方案,因为它不会让root用户进入PHP的业务。

+0

我目前正在运行此解决方案。我想知道是否有像脚本/ crontab那样安全的解决方案,但是更快,更高效并且允许直接响应。就像打多米诺骨牌一样。 – Jimbo 2010-11-12 19:20:50

+0

@Jimbo - 你的意思是运行php + apache比shell命令更快吗?或者你的手段更方便? – ajreal 2010-11-12 19:24:52

+0

不,我的意思是没有等到cron工作开始的时候。 – Jimbo 2010-11-12 19:33:50

1

您可能不需要以root身份运行PHP或Apache。如果你能控制你的服务器,你可以使用一个叫做suPHP的Apache模块,并且指定你想运行Apache的用户为配置中的php脚本。您可以逐个站点地完成此操作,因此您只需要在特定域上运行suPHP脚本即可。我缺乏专业知识来就如何安装它提供建议,但我有我们的专用服务器公司为我做这件事,以允许github post-receive hook在我的开发服务器上调用脚本来触发对开发服务器的git pull时间有人推到github回购。由于Apache需要作为本地回购站的所有者运行,因此我无法以其他任何方式使其工作。

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

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); 
} 

这编译包装应拥有其根,组“WWW”,应该有“S位”。
chwon root.www wrapper; chmod 4440 wrapper,所以

  • 被执行时,他的有效UID将根
  • 执行它只能组万维网(Web服务器的组)
  • ,当主叫用户的UID是不是一个基于web服务器将退出
+0

作品一种享受!多么棒的思维,谢谢。 – georgiecasey 2013-09-14 22:27:57

2

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

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

迈克

0

使用一个守护进程以root身份运行(也许用C编写的),这将启动shell脚本为您服务。要在PHP脚本内触发shell脚本执行,只需使用IPC(消息队列)。

看一看这里得到一个想法是什么我谈论:http://php.net/manual/en/function.msg-send.php#114831

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; 

在安全性方面它远远比运行Apache作为根更好。但让PHP靠近根目录总是很棘手。

我建造这个项目实现了2种方式之一根的bash shell:

1)您允许Apache在sudo的蟒蛇的权利。

OR

2)您传递根证书对象每次你需要以root设置shell的时候。

挑你的毒药。 :)阅读文档。