it-swarm.com.de

Ausführen von SSH-Befehlen über PHP

Ich freue mich auf SSH per PHP. Was ist der beste/sicherste Weg, um dies zu erreichen? Ich weiß ich kann:

Shell_exec("SSH [email protected] mkdir /testing");

Etwas besseres Das fühlt sich so "frech" an :).

54
Justin

Ich würde phpseclib verwenden, eine reine PHP SSH-Implementierung . Ein Beispiel:

<?php
include('Net/SSH2.php');

$ssh = new Net_SSH2('www.domain.tld');
if (!$ssh->login('username', 'password')) {
    exit('Login Failed');
}

echo $ssh->exec('pwd');
echo $ssh->exec('ls -la');
?>
64
user734976

Haben Sie die SSH2-Erweiterung zur Verfügung?

Dokumente: http://www.php.net/manual/de/function.ssh2-exec.php

$connection = ssh2_connect('Shell.example.com', 22);
ssh2_auth_password($connection, 'username', 'password');

$stream = ssh2_exec($connection, '/usr/local/bin/php -i');
17
Chris Baker

Ich hatte eine schwere Zeit mit ssh2 in php, weil der Ausgabestrom manchmal funktioniert und manchmal nicht. Ich werde nur meine Lib hier einfügen, was für mich sehr gut funktioniert. Wenn es kleine Inkonsistenzen im Code gibt, liegt das daran, dass ich es in ein Framework eingesteckt habe.

<?php

class Components_Ssh {

    private $Host;

    private $user;

    private $pass;

    private $port;

    private $conn = false;

    private $error;

    private $stream;

    private $stream_timeout = 100;

    private $log;

    private $lastLog;

    public function __construct ( $Host, $user, $pass, $port, $serverLog ) {
        $this->Host = $Host;
        $this->user = $user;
        $this->pass = $pass;
        $this->port = $port;
        $this->sLog = $serverLog;

        if ( $this->connect ()->authenticate () ) {
            return true;
        }
    }

    public function isConnected () {
        return ( boolean ) $this->conn;
    }

    public function __get ( $name ) {
        return $this->$name;
    }

    public function connect () {
        $this->logAction ( "Connecting to {$this->Host}" );
        if ( $this->conn = ssh2_connect ( $this->Host, $this->port ) ) {
            return $this;
        }
        $this->logAction ( "Connection to {$this->Host} failed" );
        throw new Exception ( "Unable to connect to {$this->Host}" );
    }

    public function authenticate () {
        $this->logAction ( "Authenticating to {$this->Host}" );
        if ( ssh2_auth_password ( $this->conn, $this->user, $this->pass ) ) {
            return $this;
        }
        $this->logAction ( "Authentication to {$this->Host} failed" );
        throw new Exception ( "Unable to authenticate to {$this->Host}" );
    }

    public function sendFile ( $localFile, $remoteFile, $permision = 0644 ) {
        if ( ! is_file ( $localFile ) ) throw new Exception ( "Local file {$localFile} does not exist" );
        $this->logAction ( "Sending file $localFile as $remoteFile" );

        $sftp = ssh2_sftp ( $this->conn );
        $sftpStream = @fopen ( 'ssh2.sftp://' . $sftp . $remoteFile, 'w' );
        if ( ! $sftpStream ) {
            //  if 1 method failes try the other one
            if ( ! @ssh2_scp_send ( $this->conn, $localFile, $remoteFile, $permision ) ) {
                throw new Exception ( "Could not open remote file: $remoteFile" );
            }
            else {
                return true;
            }
        }

        $data_to_send = @file_get_contents ( $localFile );

        if ( @fwrite ( $sftpStream, $data_to_send ) === false ) {
            throw new Exception ( "Could not send data from file: $localFile." );
        }

        fclose ( $sftpStream );

        $this->logAction ( "Sending file $localFile as $remoteFile succeeded" );
        return true;
    }

    public function getFile ( $remoteFile, $localFile ) {
        $this->logAction ( "Receiving file $remoteFile as $localFile" );
        if ( ssh2_scp_recv ( $this->conn, $remoteFile, $localFile ) ) {
            return true;
        }
        $this->logAction ( "Receiving file $remoteFile as $localFile failed" );
        throw new Exception ( "Unable to get file to {$remoteFile}" );
    }

    public function cmd ( $cmd, $returnOutput = false ) {
        $this->logAction ( "Executing command $cmd" );
        $this->stream = ssh2_exec ( $this->conn, $cmd );

        if ( FALSE === $this->stream ) {
            $this->logAction ( "Unable to execute command $cmd" );
            throw new Exception ( "Unable to execute command '$cmd'" );
        }
        $this->logAction ( "$cmd was executed" );

        stream_set_blocking ( $this->stream, true );
        stream_set_timeout ( $this->stream, $this->stream_timeout );
        $this->lastLog = stream_get_contents ( $this->stream );

        $this->logAction ( "$cmd output: {$this->lastLog}" );
        fclose ( $this->stream );
        $this->log .= $this->lastLog . "\n";
        return ( $returnOutput ) ? $this->lastLog : $this;
    }

    public function shellCmd ( $cmds = array () ) {
        $this->logAction ( "Openning ssh2 Shell" );
        $this->shellStream = ssh2_Shell ( $this->conn );

        sleep ( 1 );
        $out = '';
        while ( $line = fgets ( $this->shellStream ) ) {
            $out .= $line;
        }

        $this->logAction ( "ssh2 Shell output: $out" );

        foreach ( $cmds as $cmd ) {
            $out = '';
            $this->logAction ( "Writing ssh2 Shell command: $cmd" );
            fwrite ( $this->shellStream, "$cmd" . PHP_EOL );
            sleep ( 1 );
            while ( $line = fgets ( $this->shellStream ) ) {
                $out .= $line;
                sleep ( 1 );
            }
            $this->logAction ( "ssh2 Shell command $cmd output: $out" );
        }

        $this->logAction ( "Closing Shell stream" );
        fclose ( $this->shellStream );
    }

    public function getLastOutput () {
        return $this->lastLog;
    }

    public function getOutput () {
        return $this->log;
    }

    public function disconnect () {
        $this->logAction ( "Disconnecting from {$this->Host}" );
        // if disconnect function is available call it..
        if ( function_exists ( 'ssh2_disconnect' ) ) {
            ssh2_disconnect ( $this->conn );
        }
        else { // if no disconnect func is available, close conn, unset var
            @fclose ( $this->conn );
            $this->conn = false;
        }
        // return null always
        return NULL;
    }

    public function fileExists ( $path ) {
        $output = $this->cmd ( "[ -f $path ] && echo 1 || echo 0", true );
        return ( bool ) trim ( $output );
    }
}
10
Romeo M.

Für Benutzer von Symfony Framework kann die phpseclib auch für die Verbindung über SSH verwendet werden. Es kann mit Composer installiert werden:

composer require phpseclib/phpseclib

Als nächstes verwenden Sie es einfach wie folgt:

use phpseclib\Net\SSH2;

// Within a controller for example:
$ssh = new SSH2('hostname or ip');
if (!$ssh->login('username', 'password')) {
    // Login failed, do something
}

$return_value = $ssh->exec('command');
3
Ziad Akiki

Verwenden Sie die Funktionen ssh2 . Alles, was Sie über einen exec () - Aufruf machen würden, kann direkt mit diesen Funktionen ausgeführt werden, wodurch Sie viele Verbindungen und Shell-Aufrufe sparen.

2
Marc B

Ich habe einen einfachen ssh-Client mit xterm geschrieben. Sie können den Quellcode auf der github-Seite nachsehen https://github.com/roke22/PHP-SSH2-Web-Client

Sie können mir helfen, mich zu verbessern, bitte senden Sie mir ein Feedback.

0
Roke

// Update 2018, funktioniert //

Methode 1:

Laden Sie phpseclib v1 herunter und verwenden Sie diesen Code:

<?php
set_include_path(__DIR__ . '/phpseclib1.0.11');
include("Net/SSH2.php");

$key ="MyPassword";
  /* ### if using PrivateKey ### 
  include("Crypt/RSA.php");
  $key = new Crypt_RSA();
  $key->loadKey(file_get_contents('private-key.ppk'));
  */

$ssh = new Net_SSH2('www.example.com', 22);   // Domain or IP
if (!$ssh->login('your_username', $key))  exit('Login Failed');

echo $ssh->exec('pwd');
?>

oder Methode2:

Neueste phpseclib v2 herunterladen (erfordert composer install zuerst):

<?php

set_include_path($path=__DIR__ . '/phpseclib-master/phpseclib');
include ($path.'/../vendor/autoload.php');

$loader = new \Composer\Autoload\ClassLoader();

use phpseclib\Net\SSH2;

$key ="MyPassword";
  /* ### if using PrivateKey ### 
  use phpseclib\Crypt\RSA;
  $key = new RSA();
  $key->load(file_get_contents('private-key.ppk'));
  */

$ssh = new SSH2('www.example.com', 22);   // Domain or IP
if (!$ssh->login('your_username', $key))   exit('Login Failed'); 

echo $ssh->exec('pwd');
?>

p.s. Wenn Sie "Zeitüberschreitung der Verbindung" erhalten, handelt es sich wahrscheinlich um das Problem Host/FIREWALL (lokal oder remote) oder nicht um ein Skriptfehler.

0
T.Todua