Launch interactive SSH bash session from PHP

2020-08-25 06:00发布

问题:

I'm using PHP to write shortcuts for common server admin tasks (I'm using deployer.org but this shouldn't be important). I want to add a task for starting an interactive bash prompt after SSHing into a server. For example, you would run "./dep ssh" (where "dep" is a PHP script) and this would have the same effect as running e.g. "ssh user@server" from the terminal. Is there a way to do this in PHP? For context, I have about 5 servers that I frequently want to SSH into, or read logs, or copy files etc. so I want shortcuts for this.

The closest I've been able to get is something like this:

$ph = popen("bash","w");
  while(($line = fgets(STDIN)) !== false){
      fputs($ph,$line);
 }
 pclose($ph);

This lets you send commands to and from bash but you don't see the normal bash prompt or get tab completion. I need something like this but with all the normal bash features working.

回答1:

If you are simply looking to do SSH in web-browser this is what you are may be looking for one of the following products:

  • Google's Secure Shell extension for Chrome and Chromium
  • Anyterm
  • Ajaxterm
  • Gate One
  • webmux
  • WebShell
  • EC2Box
  • KeyBox
  • KeyBox-OpenShift
  • Mist.io

Here is a link that you might like taking a look at.



回答2:

#!/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;
    }
}

Unfortunately, it's getting late so I can't finish it =D. The major problem here is reading the input (fgets only happens after the user enters a newline, so it can't detect "\t"). I try to fake it with read, but it's really buggy.

fgetc won't work either, that requires the user entry to be completed.

My next step would be to look into how tty's work, and to try to hack it that way. But, of course, you'd still have to do a lot of work to try and make the output of compgen relevant. This would involve figuring out which arguments and options to send to compgen (i.e., is the user typing a command or a filename).



回答3:

Take a look at this ssh2 module in PHP, documentation is here.

This is how you can connect and execute your commands:

<?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");

}

?>


标签: php bash shell