从PHP启动交互式SSH bash会话

9
我正在使用PHP编写常见服务器管理任务的快捷方式(我使用deployer.org,但这不重要)。我想添加一个任务,在SSH到服务器后启动交互式bash提示符。例如,您将运行“./dep ssh”(其中“dep”是一个PHP脚本),这将具有与从终端运行“ssh user@server”相同的效果。在PHP中是否有一种方法可以实现这一点?为了背景,我有大约5个经常想要SSH到的服务器,或者阅读日志,或者复制文件等,因此我需要快捷方式。
我能够接近的最接近的方法是像这样:
$ph = popen("bash","w");
  while(($line = fgets(STDIN)) !== false){
      fputs($ph,$line);
 }
 pclose($ph);

这可以让你向bash发送和接收命令,但你看不到正常的bash提示或获得制表符自动完成。我需要类似于此的东西,但要使所有正常的bash功能都能工作。


我正在努力解决这个问题 :). 希望我能尽快完成它。 - robert
为什么不把你的快捷方式写成在 .bashrc 中的别名呢? - Raphael Müller
我在编写所有任务的脚本时始终保持一致,以便所有开发人员都可以轻松地执行它们。我希望能够运行"./dep ssh stage"、"./dep release stage"、"./del logs stage"来交互式地通过SSH连接到暂存服务器、发布和查看日志(例如,'release'任务是一组非交互式的SSH任务)。 - fstr
3个回答

1
如果您只是想在Web浏览器中进行SSH,那么以下产品可能会符合您的需求:
  • Google Chrome和Chromium的Secure Shell扩展
  • Anyterm
  • Ajaxterm
  • Gate One
  • webmux
  • WebShell
  • EC2Box
  • KeyBox
  • KeyBox-OpenShift
  • Mist.io
这里有一个链接,您可能会感兴趣。

也许我没有表达清楚,但这是一个我从命令行运行的PHP脚本。 - fstr
1
@fstr 这意味着你需要自己开发它,ssh2拥有你需要开发类似于命令行上使用的SSH实用程序的bash tty所需的所有功能,请查看此链接并开始开发:http://phpseclib.sourceforge.net/ssh/intro.html。 - anand

0
#!/usr/bin/php
# This doesn't work, but it might lead you in the right direction.
<?
$ph = popen("bash","w");

function getCharacter() {
    $cmd = '
        read -n 1 char;
        if [ "$char"==" " ]; then
            echo space
        elif [ "$char"=="\n" ]; then
            echo newline
        else 
            echo "$char"
        fi
    ';
    return trim(shell_exec($cmd));
}

$command = "";

while (false !== ($char = getCharacter())) {
    if ($char === "space") {
        $command .= ' ';
    } elseif ($char === "newline") {
        fputs($ph, $command);
        $command = "";
    } elseif ($char === "\t") {
        # Do something fancy with the `compgen` bash utility.
        echo shell_exec("compgen -d $command");
    } else {
        $command .= $char;
    }
}

很不幸,时间已经很晚了,所以我无法完成它 =D。这里的主要问题是读取输入(fgets 只会在用户输入换行符后才发生,因此它无法检测 "\t")。我试图用 read 来模拟它,但是它真的很有 bug。

fgetc 也不起作用,因为它需要用户输入完成。

我的下一步将是研究 tty 的工作原理,并尝试通过这种方式来进行黑客攻击。但是,当然,您仍然需要做很多工作来尝试使 compgen 的输出相关。这将涉及确定要发送到 compgen 的参数和选项(即,用户是输入命令还是文件名)。


-1

看看 PHP 中的 this ssh2 模块,文档在这里

以下是连接并执行命令的方法:

<?php

/* Notify the user if the server terminates the connection */
function my_ssh_disconnect($reason, $message, $language) {
  printf("Server disconnected with reason code [%d] and message: %s\n",
         $reason, $message);
}

public function my_exec_cmd($connection, $cmd) {
    if (!($stream = ssh2_exec($connection, $cmd))) {
        throw new Exception('SSH command failed');
    }
    stream_set_blocking($stream, true);
    $data = "";
    while ($buf = fread($stream, 4096)) {
        $data .= $buf;
    }
    fclose($stream);
    return $data;
} 

$methods = array(
  'kex' => 'diffie-hellman-group1-sha1',
  'client_to_server' => array(
    'crypt' => '3des-cbc',
    'comp' => 'none'),
  'server_to_client' => array(
    'crypt' => 'aes256-cbc,aes192-cbc,aes128-cbc',
    'comp' => 'none'));

$callbacks = array('disconnect' => 'my_ssh_disconnect');

$connection = ssh2_connect('shell.example.com', 22, $methods, $callbacks);
if (!$connection){
 die('Connection failed');
}else{

   my_exec_cmd($connection, "ls -la");

}

?>

1
这会给我一个交互式的bash提示符吗?我不想发送单个命令,我想启动一个交互式的bash会话。 - fstr
这是一个编程库而不是产品,因此它不能完全满足您的需求,您需要进行开发;也许您可以将其作为进程运行,保持连接打开,并从HTML页面发送命令请求并在服务器上使用ssh2运行它们,然后获取响应并在屏幕上显示它们,等待下一个输入,这就是交互式的方式。 - anand
1
你会看到正常的bash提示符吗?Tab键自动补全会工作吗?如果从我发布的示例中无法工作,我不确定为什么特定的SSH库会允许它。 - fstr
不,它不支持制表符自动完成。如果您需要它,也有方法可以实现。我可能误解了您的问题,因为我认为您正在寻找从监控站点远程执行SSH到主机的方式,但这在您发布的示例中不起作用。 - anand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接