我发现许多问题是通过在权限中打开巨大漏洞或更改文件的用户所有权来实现的。对于我目前的申请,这些都不是一个选择。我想要做的是使用shell_exec或类似的php函数在我的网页上单击按钮时在我的系统上的完全不同的文件夹中运行.sh脚本。该脚本必须从它所在的文件夹运行。我在debian上并安装了sudo以允许apache用户通过添加以下行来运行命令:
www-data ALL=(ALL) NOPASSWD:/opt/folder/run.sh start
www-data ALL=(ALL) NOPASSWD:/opt/folder/run.sh stop
www-data ALL=(ALL) NOPASSWD:/opt/folder/run.sh status
run.sh不是我允许编辑的东西,所以如果可能的话我必须在apache端管理它。我不允许更改run.sh的权限或所有权。所以你可以看到我的困境。我正在使用的php调用如下所示:
$test=shell_exec('cd /opt/folder/ && ./run.sh start&& cd -');
我使用$ test来回显命令的输出。这是奇怪的地方。命令有很好的输出。 run.sh脚本用于启动和停止其他程序列表并显示其状态。我可以运行./run.sh status
并在$ test变量中得到一个好的结果。如果我尝试./run.sh stop
它说它有用(我很确定run.sh脚本没有内置很多检查)但是系统上实际上没有发生任何事情。我可以运行ps -ef | grep
作为健全性检查,并查看应该停止的所有进程。如果我运行./run.sh start
,它将是相同的,但它将返回没有任何程序启动。
所有这一切,我只想弄清楚我做错了什么。我确信php正在运行bash脚本,但由于某些原因,它无法在脚本中实际运行任何启动或停止命令。我也可以从操作系统中以root身份完全运行run.sh.我真的在这个绳子的尽头,所以任何帮助都非常感激。如果这甚至不可能,那么是否有其他选择需要额外的程序安装。
答案 0 :(得分:0)
因此,经过几次尝试,我决定将其保存以供日后使用。我意识到虽然我允许apache用户以root身份运行脚本,但我还是没有告诉它。为了解决这个问题,我做了改变
$test=shell_exec('cd /opt/folder/ && sudo ./run.sh start&& cd -');
添加的sudo现在告诉脚本以root身份运行,而visudo中的条目允许它在不要求密码的情况下这样做。我确实将我的visodu文件更改为更精简,所以现在它只有一行。
www-data ALL=(ALL) NOPASSWD:/opt/folder/run.sh
这符合安全要求和用户约束。几乎没有打开攻击向量,因为chmod 777等会导致,并且apache用户只能访问带有它包含的硬编码参数的run.sh脚本。
答案 1 :(得分:0)
我最近发布了一个项目,允许PHP获取并与真正的Bash shell进行交互(如果需要,以root身份,但我认为你不需要它),它解决了exec()和shell_exec()的限制。在此处获取:https://github.com/merlinthemagic/MTS
下载后,您只需使用以下代码:
$shell = \MTS\Factories::getDevices()->getLocalHost()->getShell('bash', false);
$return1 = $shell->exeCmd('cd /opt/folder/');
$return2 = $shell->exeCmd('./run.sh start');
$return3 = $shell->exeCmd('cd -');
//the return will be a string containing the return of the command
echo $return1;
echo $return2;
echo $return3;
由于您不需要root,因此实际上没有任何安全问题。安装软件包时,请跳过有关设置sudo的部分。
此外,如果您的'run.sh'需要很长时间才能完成,您需要更改该命令的超时时间,如下所示:
//is one hour enough?
$timeout = 3600000;
$return2 = $shell->exeCmd('./run.sh start', null, $timeout);