4

我有一组 bash 和 Perl 脚本

  1. 开发在 linux box 上部署所需的目录结构
  2. (可选)从 svn 导出代码
  3. 从此源构建一个包

这在终端上运行良好。现在我的客户请求此过程的 Web 界面。

例如,某些页面上的“创建新包”按钮将一一调用上述步骤并将输出作为脚本回显返回给用户,而不是在整个脚本执行时返回。

是否可以将 bash 脚本的瞬时输出发送到网页或 php 脚本,该网页或 php 脚本已通过程序执行功能(系统、执行、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 密码

请帮忙 !

4

6 回答 6

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 作业运行,并查询数据库,提供任务的进展。

专业人士是:

  • 独立系统,轻松进化。
  • 如果客户端断开连接,则工作永远不会丢失
  • 更容易保护

缺点是:

  • 一开始有点复杂。
  • 反应性较低,因为从属运行的轮询时间(例如,如果它们每 5 分钟运行一次)
  • 输出比命令的直接输出少

请注意,您可以实现类似 xml-rpc 的触发器来运行从属服务器,而不是使用消息传递系统。

于 2012-06-14T12:27:44.030 回答
1

最简单的方法是使用shell_exec来达到您的目的。它通过 shell 执行命令并将完整的输出作为字符串返回,因此您可以将其显示在您的网站上。

如果这不符合您的目的,因为也许您在等待命令完成时需要一些响应,请查看php 中可用的其他程序执行功能(提示:手册页上有一些很好的评论)。

请记住,以这种方式调用命令行脚本时,生成的输出将具有您的网络服务器的文件所有者、组和权限(pe wwwrun 或其他)。如果您的部分部署需要单独的所有者、组和/或文件权限,您必须在脚本中或在调用shell_execchmod之后手动设置它们(chown并且chgrp可以在 php 中处理)。

关于安全性:很多基于网络的应用程序都将这种功能放在一个单独的安装目录中,安装后请您删除该目录。我什至记得他们中的一些人非常顽固地对管理员大喊大叫,除非它被删除。这是防止此脚本在错误的时间被错误的人调用的简单方法。如果您的应用程序在安装后可能需要它,那么您必须将其放入只有授权用户才能访问的区域(pe 管理区域或类似的东西)。

于 2012-06-11T09:09:44.953 回答
1

您可以使用Comet Web 应用程序模型对结果页面进行实时更新。

对于 sudo 问题,作为一种快速而肮脏的解决方案,我将使用 Web 服务器无需密码即可执行的受限命令集。示例(添加/etc/sudoers):

apache ALL=(ALL) NOPASSWD: /sbin/service myproject *

这将允许 apache 运行/sbin/service myproject stop/sbin/service myproject start依此类推。

看看Jenkins,它很好地完成了 web 部分,您只需在构建中添加脚本。

正如Aif所建议的,更好的解决方案是分离逻辑。一个等待任务的守护进程和一个可视化结果的 Web 应用程序。

于 2012-06-15T00:47:33.780 回答
0

通过 PHP 执行系统命令时始终使用escapeshellargescapeshellcmd以确保安全。还建议尽可能限制用户在 chroot'd 目录中。

于 2012-06-16T03:35:21.027 回答
0

您似乎已经解决了使用proc_open. 现在问题似乎是通过 sudo 执行脚本。

从安全的角度来看,让 PHP 应用程序以 root 身份运行脚本(通过 sudo)让我感到畏缩。在password.txt 中有root 密码是一个相当大的安全漏洞。

我要做的(如果可能的话)是进行任何必要的更改,以便运行 Apache 的 unix 用户可以运行 setup.sh。(我假设您使用 Apache 运行 PHP。)如果 setup.sh 将由网络服务器执行,它应该能够运行它而无需借助 sudo。

如果您确实需要以其他用户身份执行脚本,您可以查看suPHP,它旨在以非标准用户身份运行 PHP 脚本。

于 2012-06-19T17:09:56.403 回答
0

使用 /etc/sudoers 的 NOPASSWD 选项为特定用户提供自动 sudo 权限,然后运行带有前缀的命令以sudo -u THE_SUDO_USER使命令以该用户身份执行。这可以防止授予整个 apache 用户 sudo 权限的安全漏洞,但也允许从 apache 内部对脚本执行 sudo。

于 2013-12-17T05:34:25.293 回答