我有一个CentOS 5.7 linux服务器并使用php5.3.x。
在pfSense系统上,您可以使用php网页重新启动需要root权限的服务。
我正在尝试做类似的事情,我已经写了一些PHP代码来执行shell命令。例如,要重新启动sshd服务:
<?php
exec('/sbin/service sshd restart');
?>
我尝试通过exec函数执行该命令,但它需要root权限,但我们有一个apache用户权限。
我遇到了一些解决方案:
还有其他解决方案吗? 谢谢你的回答。
现在..这很有趣。我试过@refp post,它工作了我的本地ubuntu服务器。但是当我在我的cenOS vps服务器上尝试相同时。它不起作用。这是apache的错误日志“rm:无法删除`/ var / lock / subsys / vsftpd':权限被拒绝”
答案 0 :(得分:89)
在尝试之前阅读整篇文章,可以做出选择。
1)创建一个脚本(最好.sh
),其中包含您希望以root用户身份运行的内容。
# cat > php_shell.sh <<CONTENT
#!/bin/sh
/sbin/service sshd restart
CONTENT
2)此文件应由root拥有,并且由于它稍后将以root权限运行,因此请确保只有root用户才有权写入该文件。
# chown root php_shell.sh
# chmod u=rwx,go=xr php_shell.sh
3)要以root身份运行脚本,无论执行它的用户是什么,我们都需要一个二进制包装器。创建一个将执行我们的php_shell.sh
。
# cat > wrapper.c <<CONTENT
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int
main (int argc, char *argv[])
{
setuid (0);
/* WARNING: Only use an absolute path to the script to execute,
* a malicious user might fool the binary and execute
* arbitary commands if not.
* */
system ("/bin/sh /path/to/php_shell.sh");
return 0;
}
CONTENT
4)编译并设置适当的权限,包括suid位(说它应该以root权限运行):
# gcc wrapper.c -o php_root
# chown root php_root
# chmod u=rwx,go=xr,+s php_root
php_root
现在将以root权限运行,并执行php_shell.sh
中指定的命令。
如果您不需要选项来轻松更改将要执行的命令,我建议您直接在步骤 4 的wrapper.c
中编写命令。然后,您不需要二进制文件执行执行相关命令的外部脚本。
在wrapper.c
中,使用system ("your shell command here");
指定您要执行的命令。
答案 1 :(得分:22)
我不会让PHP执行任何sudo命令。对我而言,这听起来像是在寻找麻烦。相反,我会创建两个独立的系统。
PHP(Web层)中的第一个系统将处理用户请求。当发出需要sudo命令的请求时,我会将此请求放在某个队列中。这可能是某种类型的数据库或中间件,如ZeroMQ。
第二个系统(业务层)将从此队列读取或接收消息,并且能够执行sudo命令,但不在您的Web服务器进程范围内。
我知道这有点模糊,可以通过各种技术以不同的方式解决,但我认为这是最好和最安全的方式。
答案 2 :(得分:8)
允许www-data用户运行以运行无密码的program1和program2:
sudo visudo
添加到sudoers文件的内容:
User_Alias WWW_USER = www-data
Cmnd_Alias WWW_COMMANDS = /sbin/program1, /sbin/program2
WWW_USER ALL = (ALL) NOPASSWD: WWW_COMMANDS
保存。
来自https://askubuntu.com/questions/76920/call-a-shell-script-from-php-run-as-root
答案 3 :(得分:2)
我最近发布了一个允许PHP获取真实Bash shell并与之交互的项目,它将很容易为您提供以root身份登录的shell。然后你可以只执行单独的bash命令,而不是在脚本中捆绑。这样你也可以处理回报。在此处获取:https://github.com/merlinthemagic/MTS
下载后,您只需使用以下代码:
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', true);
$return1 = $shell->exeCmd('service sshd restart');
echo $return1;
//On CentOS 7 output would be like:
//Redirecting to /bin/systemctl restart sshd.service
//On CentOS 6 and lower output would be like:
//Stopping sshd: [ OK ]
//Starting sshd: [ OK ]
答案 4 :(得分:2)
使用二进制包装器(带有suid位)的解决方案 对Filip Roséen - refp帖子进行了一些修改。
执行任何命令修改后的wrapper.c
hadoop dfadmin -safemode get
编译并设置适当的权限;
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
int main (int argc, char **argv)
{
setuid (0);
char cmd[100] = "";
int i;
char *p;
for(i=0; i < argc; i++) {
if(i != 0){
strcat(cmd, *(argv+i));
strcat(cmd, " ");
}
}
system (cmd);
return 0;
}
现在从PHP调用。执行任何命令。
gcc wrapper.c -o php_root # php_root can be any name.
chown root php_root
chmod u=rwx,go=xr,+s php_root
答案 5 :(得分:0)
setenforce 0
在终端中写入此命令将禁用SELinux。 这不是一个好习惯。