在PHP中通过SSH与多个服务器交互

时间:2011-01-18 23:22:14

标签: php deployment ssh passthru

我目前正在用PHP编写部署框架。该框架连接到服务器并通过SSH执行命令。我一直在寻找相当长的一段时间,试图在PHP中找到一种更好的方法。这是要求。该技术应该能够:

  1. 以编程方式输入SSH密码。我知道当你想要无密码的SSH登录时,使用SSH密钥是可行的,但请记住,这是一个部署框架。它可能一次部署到25台服务器。要求用户设置SSH密钥以使用框架,谁想要输入密码25次似乎是不对的?我在这里使用Capistrano作为模型 - 它会询问您的密码一次,然后使用它来建立SSH连接而无需重新提示用户。我并不是建议将密码存储在部署脚本中,只是(静默地)输入一次并使用,直到部署任务完成。

  2. 将输出发送到PHP脚本。我希望能够独立拦截每个SSH会话的终端输出,修改它,然后将其发送回终端供用户查看。这样,我可以将服务器的名称添加到每行输出中,以显示正在发生的事情。

  3. 提供对终端的写入(以及读取)访问。除了SSH密码之外,用户(或脚本)能够在终端中输入其他信息非常重要。

  4. 支持SSH v2。

  5. 目前,我的框架将部署脚本中的命令“编译”成一个巨大的字符串,并使用SSH命令执行它们。每个最终部署命令都如下所示:

    ssh -t -t -p 12345 user@server.com 'command1; command2;'

    这些SSH命令中的每一个都是通过PHP的内置passthru函数执行的:

    <?php passthru("ssh -t -t -p 12345 user@server.com 'command1; command2;'"); ?>

    我尝试过使用proc_open和几乎所有PHP的其他命令执行功能都无济于事 - 它们都没有提供我上面列出的所有功能。另外,我尝试了几种纯PHP的SSH实现,也无济于事。这些库要么不提供对终端的写访问权限,要么不支持SSH v2。

    对此的任何帮助将不胜感激 - 提前感谢!

3 个答案:

答案 0 :(得分:2)

您认为以下是对终端进行写访问的示例吗?:

ssh -t -t -p 12345 user@server.com 'command1; command2;'

如果是,那么您可以使用phpseclib's pure PHP SSH implementation执行此操作。例如

$ssh = new Net_SSH2(...);
$ssh->login(..., ...);
$ssh->exec('command1; command2;');

如果没有那么(1)我会说你最好不要使用phpseclib而不是你当前的实现;(2)如果你想要phpseclib作者所谓的“交互式”支持可能你可以尝试联系作者吗?也许愿意向他支付一些钱来激励他开发这个功能。看看支持论坛,作者似乎反应灵敏。

答案 1 :(得分:1)

我不确定php是否是正确的工具。为什么不使用更接近shell环境的东西,比如bash脚本?

我可以想象您想要使用PHP的唯一原因是,您可以通过单击页面上的某个链接来启动该过程,从而在系统所应具有的安全性方面打出一个大洞。但是,如果你真的必须,那么用更易于使用shell的语言编写脚本仍然更容易,只需使用php作为调用脚本的网关。

答案 2 :(得分:0)

您可以在PHP中使用PECL扩展进行SSH连接。 http://php.net/manual/en/book.ssh2.php

$connection = ssh2_connect('server.com', 22);
ssh2_auth_password($connection, 'username', 'password');
$stream1 = ssh2_exec($connection, $command1);
$stream2 = ssh2_exec($connection, $command2);

如果您需要更高级的东西,还可以使用ssh2_shell()创建一个ssh交互式shell。