0

所以我有 5 台云机器正在运行,我的第 1 台被设置为 apache 服务器。我的目标是让用户点击网页上的提交按钮,它将在我的第一台机器上运行 parallel-ssh 并在其他云机器上启动脚本。我正在运行网页,正在运行脚本,这是我尝试从 index.php 启动并行 ssh

所以“master.txt”在第一台云机器上,它保存着关于其他云机器的信息。StrictHostKeyChecking 用于忽略安全检查。perl 命令将在所有云机器上启动。我知道这个问题相当令人困惑,但我对 php 和 perl 都是新手,我真的需要这个项目的答案。抱歉,这是一个大命令,但我不得不将它们分成几行,因为它不会在这里显示。

4

2 回答 2

1

如果您通过 libssh2 或 phpseclib 连接到每台服务器并在每台机器上运行这样的命令,也许您会更轻松一些?

于 2013-07-18T16:12:21.467 回答
0

这是一个很大的命令。我是否可以建议这样做,以便更好地理解它。在下面的代码中,我经常使用 escapeshellarg 来确保我们所有的 shell 参数都被正确地转义并且不会受到攻击。这也取决于您的变量是否受信任,但除非每个参数变量实际上由多个参数或其他不那么常见的东西组成,否则不应受到伤害。

<?php
$result = shell_exec(
    'parallel-ssh -h master.txt "-O StrictHostKeyChecking=no" ' . // SSH command
    '-t 5 ' . // 5 second timeout on each host
    '-l divx ' . // User
    '-i ' . // Inline mode used for troubleshooting.. Take this out once it works.
    '-P ' . // Print the output. This will only return it so it is stored in $result
    escapeshellarg(
        'perl /mnt/nas-storage/EncoderSetup/commTools/con.pl ' . // Executes a perl file
        escapeshellarg($input) . ' ' . // $input arg to perl command
        escapeshellarg($output) . ' ' . // $output arg to perl command
        escapeshellarg($intraperiod) . ' ' . // $intraperiod arg to perl command
        escapeshellarg($res) . ' ' . // $res arg to perl command
        escapeshellarg($qp) . ' ' . // $qp arg to perl command
        escapeshellarg($framerate) . ' ' . // $framerate arg to perl command
        escapeshellarg($startframe) . ' ' . // $startframe arg to perl command
        escapeshellarg($numgop) . ' ' . // $numgop arg to perl command
        escapeshellarg($enc) . ' ' . // $enc arg to perl command
        escapeshellarg($cfg) . ' ' . // $cfg arg to perl command
        escapeshellarg($sao) . ' ' . // $sao arg to perl command
        escapeshellarg($wafrosync) . ' ' . // $wafrosync arg to perl command
        escapeshellarg($amp) . ' ' . // $amp arg to perl command
        escapeshellarg($tmvp) . ' ' . // $tmvp arg to perl command
        escapeshellarg($transkp) . ' ' . // $transkp arg to perl command
        escapeshellarg($fasttranskp) . ' ' . // $fasttranskp arg to perl command
        escapeshellarg($goploc) // $goploc arg to perl command
    )
);
print $result;

这应该对你有用,但有一些事情需要考虑。首先,执行它并打印出 $result 以查看实际输出是什么。如果你得到类似的东西

[FAILURE] server.hostname Exited with error code 255

那么 pssh 可能会要求每个主机输入密码。我注意到您正在使用要求输入密码的 -A 选项。您不能在 php 中使用 shell_exec 执行此操作,因为这样脚本将挂起并永远等待密码。相反,您需要设置 SSH 密钥,以便您的第一台云服务器无需密码即可通过 ssh 连接到其他云服务器。设置基于 SSH 公钥的身份验证实际上非常简单。但是,如果您以前从未这样做过,则不会。我相信有很多关于如何设置的帖子。程序基本上是:

  1. 生成公钥和私钥(无密码)。

    • 在您的第一个云服务器上输入此命令:ssh-keygen
    • 当它问你时不要输入密码
  2. 将 id_rsa.pub 文件复制到每个辅助云服务器上的 ~/.ssh/authorized_keys 文件

  3. 确保 .ssh 文件夹在每个云服务器上具有 700 个权限

  4. 确保 .ssh/authorized_keys 文件在每个云服务器上具有 600 个权限。

如果一切按计划进行,您应该能够从主云服务器安全地在每个云服务器上执行命令,而无需密码。现在,您可以运行您的命令,它应该可以工作......或者至少给您输出为什么它没有,这样您就可以继续进行故障排除。

另一个问题是运行 shell_exec 的用户。如果您在主云服务器上运行 Web 服务器,那么您必须确保当前用户(通常是 apache)在 .ssh 文件夹中拥有 id_rsa 文件,无论您的 apache 主目录在哪里(通常是 /var/www/ )。因此,您可以将 id_rsa 文件放在 /var/www/.ssh/ 文件夹中,并确保它归 apache 所有。另外,确保它是 chmod 600 来保护它。

还有其他安全问题,例如保护您的 id_rsa 文件。不要在您的服务器上运行任何不受信任的脚本,也不要将任何虚拟主机与为自己的网站上传自己的文件的用户一起使用。安全问题开始发挥作用,因为任何作为 apache 运行的脚本都可以轻松访问并破坏您的 id_rsa 文件......哎呀。任何有权访问此文件的人都可以轻松访问您的每个云服务器……因此不应掉以轻心。

于 2013-07-18T05:19:50.043 回答