我有一个bash和Perl脚本的集合
这在终端上运作良好。现在我的客户端请求此过程的Web界面。
例如某个页面上的“Create New Package”按钮将逐个调用上述步骤并将输出作为脚本回声返回给用户,而不是在整个脚本执行时。
是否可以将bash脚本的瞬时输出发送到通过程序执行函数调用它的网页或php脚本(系统,exec,passthru ......或任何其他适合此流程的东西)?
为什么这么做是优雅的?
在做这样的事情时我应该采取哪些安全预防措施(如果可能的话)?
修改 经过一些搜索后,我找到了解决方案的一部分,但仍无法正常工作:
$cmd = 'cat ./password.txt|sudo -S ./setup.sh ';
$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe that the child will read from
);
flush();
$process = proc_open($cmd, $descriptorspec, $pipes, './', array());
echo "<pre>";
if (is_resource($process)) {
while ($s = fgets($pipes[1])) {
print "Message:".$s;
flush();
}
while ($s = fgets($pipes[2])) {
print "Error:".$s;
flush();
}
}
echo "</pre>";
输出(网页)
Error:WARNING: Improper use of the sudo command could lead to data loss
Error:or the deletion of important system files. Please double-check your
Error:typing when using sudo. Type "man sudo" for more information.
Error:
Error:To proceed, enter your password, or type Ctrl-C to abort.
Error:
Error:Password:
Error:Sorry, try again.
Error:Password:
Error:Sorry, try again.
Error:Password:
Error:Sorry, try again.
Error:sudo: 3 incorrect password attempts**
我现在要做的第一个问题是传递sudo passoword
请帮忙!答案 0 :(得分:4)
我会使用一种主/从设计。奴隶将是你的perl / bash脚本,只是做一份工作(打包,编译,导出代码等),并提供一个日志条目。
主人将是你的php进程。所以原理如下:主设备和从设备共享一个通信通道,并从该通道异步通信。
您可以想象一个像以下的数据库:
create table tasks ( id INT primary key, status INT, argument VARCHAR(100));
你的php页面应该切换用户选择,过滤输入:
switch ($_GET['action']) {
case 'export':
$argument = sanitize($_GET['arg']);
add_task('export', $argument);
break;
case '...':
// ...
}
和add_task函数可以是:
function add_task($action, $arg)
{
return $db->add('tasks', array($action, NEW_TASK, $arg);
}
奴隶可以通过cron job运行,并查询数据库,为任务的进展提供支持。
专业人士:
缺点是:
请注意,您可以实现类似xml-rpc的触发器来运行从属服务器,而不是使用消息传递系统。
答案 1 :(得分:1)
最简单的方法是将shell_exec用于您的目的。它通过shell执行命令并将完整输出作为字符串返回,因此您可以在您的网站上显示它。
如果这不适合您的目的,因为在等待命令完成时您可能需要一些响应,请查看php中的其他program execution functions available(提示:手册页上有一些好的注释) )。
请记住,在以这种方式唤起命令行脚本时,生成的输出将具有您的网络服务器的文件所有者,组和权限(p.e. wwwrun或其他)。如果部署的某些部分需要单独的所有者,组和/或文件权限,则必须在脚本中或在调用shell_exec(chmod
,chown
和{{}之后手动设置它们。 3}}可以在php中处理这个问题。
关于安全性: 很多基于Web的应用程序将这种功能放在一个单独的安装目录中,请安装后请你删除这个目录。我甚至记得他们中的一些人对管理员大喊大叫,除非被删除。这是一种简单的方法,可以防止在错误的时间由错误的手调用此脚本。如果您的应用程序在安装后可能需要它,那么您必须将其放入只有授权用户才能访问的区域(例如管理区域或类似的东西)。
答案 2 :(得分:1)
您可以使用Comet web application model进行结果页面的实时更新。
对于sudo问题,作为一种快速而肮脏的解决方案,我会使用受限制的命令集,Web服务器可以在没有密码的情况下执行。示例(添加/etc/sudoers
):
apache ALL=(ALL) NOPASSWD: /sbin/service myproject *
允许apache运行/sbin/service myproject stop
,/sbin/service myproject start
等等。
看看Jenkins,它很好地完成了网络部分,你只需要在构建中添加你的脚本。
如Aif所建议的那样,更好的解决方案是将逻辑分开。一个守护进程等待任务,Web应用程序可视化结果。
答案 3 :(得分:0)
在通过PHP执行系统命令时始终使用escapeshellarg和escapeshellcmd以确保安全性。还建议让用户在chroot目录中尽可能地限制。
答案 4 :(得分:0)
您似乎已经解决了使用proc_open
将stdout和stdin输出到您的网页的问题。现在问题似乎是通过sudo执行脚本。
从安全角度来看,让PHP应用程序以root身份运行脚本(通过sudo)让我感到畏缩。在password.txt中使用root密码是一个非常大的安全漏洞。
我会做的(如果可能的话)是进行必要的更改,以便setup.sh可以由运行Apache的unix用户运行。 (我假设您正在使用Apache运行PHP。)如果setup.sh将由Web服务器执行,它应该能够在不使用sudo的情况下运行它。
如果您确实需要以不同的用户身份执行脚本,可以查看suPHP,它旨在以非标准用户身份运行PHP脚本。
答案 5 :(得分:0)
使用/ etc / sudoers的NOPASSWD选项为特定用户提供自动sudo权限,然后运行带有前缀sudo -u THE_SUDO_USER
的命令,以使该命令作为该用户执行。这可以防止给予整个apache用户sudo权限的安全漏洞,但也允许在apache中对脚本执行sudo。