2014-08-29 7 views
21

Ich verwende die Methode, um eine Verbindung mit einem Remote-Server herzustellen. Eine Verbindung wird korrekt hergestellt, wenn ich den richtigen Hostnamen und die korrekte Portnummer bereitstelle. Wenn ich wegen falsche Anmeldeinformationen nicht verbinden kann, versuche ich eine Callback-Funktion aufzurufen, aber die Art, wie ich es versuche, ruft den Callback nach Verbindungsausfall nicht auf.kann ssh2_connect() Callbacks nicht aufrufen

Das ich den Code habe ich versucht:

$callbacks = array( 
     'ignore' => array($this, 'callbackSshDisconnect'), 
     'debug' => array($this, 'callbackSshDisconnect'), 
     'macerror' => array($this, 'callbackSshDisconnect'), 
     'disconnect' => array($this, 'callbackSshDisconnect'), 
); 

ssh2_connect($hostName,$port,array('hostkey', 'ssh-rsa'),$callbacks); 

public function callbackSshDisconnect($reason, $message, $language) { 
    $this->log('disconnected'); 
    $this->log($reason);die; 
} 

Was mache ich falsch?

+0

Kann jemand helfen? –

+0

Ich denke, was Sie wollen, ist 'Array ('Hostschlüssel' => 'ssh-rsa')' – blue112

Antwort

3

Es gibt nichts, was Sie tun falsch neben dem Tippfehler: array('hostkey', 'ssh-rsa') sollte array('hostkey' => 'ssh-rsa') sein. Die Funktion ssh_connect() gibt für einen Verbindungsfehler nur false zurück; Callbacks werden einfach noch nicht gestartet, wenn die falschen Anmeldeinformationen verwendet werden.

Es gibt Lösungen (zB wie von rubo77 unten vorgeschlagen), aber die, die ich finde, gibt Ihnen die meiste Kontrolle und erlaubt Ihnen, das zu tun, was Sie wollen (z. B. MAC-Fehler verfolgen), verwenden Sie die phpseclib-Bibliothek (http://phpseclib.sourceforge.net/ssh/intro.html) für SSH-Verbindungen und Kontrolle. Es bietet eine sehr genaue Steuerung der Befehle und beinhaltet auch die Protokollierung.

Es ist nicht die einfachste Lösung, aber Sie können so fein steuern, als wenn Sie direkt an der Tastatur/Terminal sind.

Sie haben die Kontrolle über Timeouts und können Callback-Befehle verwenden. Wenn Sie jedoch eine bessere Kontrolle wünschen, verwenden Sie read() und write(), und Sie können Verbindungen oder andere Probleme überwachen. Überprüfen Sie die documentation on logging with phpseclib: Sie können das Protokoll entweder protokollieren und analysieren oder getLastError() aufrufen.

Log-Dateien werden 'Connection closed by server' auf trennen zum Beispiel zeigen, sondern werden Ihnen auch sagen, wenn Sie einen nicht unterstützten Authentifizierungsmodus bei der Anmeldung usw. verwenden

Oder mehr, den Code lesen: Hier sind beispielsweise die Trennung Gründe:

$this->disconnect_reasons = array(
     1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT', 
     2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR', 
     3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED', 
     4 => 'NET_SSH2_DISCONNECT_RESERVED', 
     5 => 'NET_SSH2_DISCONNECT_MAC_ERROR', 
     6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR', 
     7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE', 
     8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED', 
     9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE', 
     10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST', 
     11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION', 
     12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS', 
     13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER', 
     14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE', 
     15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME' 
    ); 
+0

@ rubo77: wie vorgeschlagen erweitert. Vielen Dank. – Robbie

+0

keine Notwendigkeit zu anderen Antworten zu deuten, nur so tun, als Antwort ist die einzige Antwort hier, fühlen Sie sich frei, um meine Grammatik wieder zu verbessern – rubo77

+0

Das Ziel ist es, OP-Programm die richtige Lösung zu helfen, nicht immer die spezifische Frage zu beantworten. Ich schreibe also immer andere Antworten (wenn sie korrekt sind), wenn ich sie hinzufüge. Aber in diesem Fall habe ich nicht bemerkt, dass Sie die Bounty angeboten haben (obwohl jetzt, danke). Aber da Sie offensichtlich nach einer besseren Lösung als Ihrer eigenen gefragt haben, wird Ihnen das hoffentlich helfen. Als Tipp, wenn Sie implementieren, sehen Sie sich die Anweisungen für "sudo" (Advanced interactive section) an, denn wenn Sie das zur Arbeit bringen, sind Sie im Grunde auf dem Weg. Ansonsten tauchen Sie den Code ein; es ist einfach genug zu lesen. – Robbie

7

Wenn ssh2_connect aufgrund eines falschen Hosts, Ports usw. fehlschlägt, ruft es keine Callbacks auf.

Was tut stattdessen falsche Dokumentation

PHP zurückkehrt, sagt:
Gibt eine Ressource auf Erfolg oder FALSE bei einem Fehler.

$result = ssh2_connect($hostName,$port,array('hostkey' => 'ssh-rsa'),$callbacks); 
if ($result === false) 
    exit("ssh2_connect failed"); 

Auch die doc Lesen, Ihre

array('hostkey', 'ssh-rsa') 

sollte

array('hostkey' => 'ssh-rsa') 
0

Selbst, wenn Sie arbeiten Code wie folgt verwenden würde:

$callbacks = array(
    'ignore' => 'callback', 
    'debug' => 'callback', 
    'macerror' => 'callback', 
    'disconnect' =>'callback', 
); 

$session = ssh2_connect($hostName, $port, array('hostkey' => 'ssh-rsa'), $callbacks); 
if($session === false) { 
    print('Connection failed' . PHP_EOL); 
    exit(1); 
} 

if(!ssh2_auth_pubkey_file(
    $session, 
    "user", 
    '/home/user/.ssh/id_rsa.pub', 
    '/home/user/.ssh/id_rsa' 
)) { 
    print('Failed to authenticate session' . PHP_EOL); 
    exit(2); 
} 

// Check this great answer: 
// http://stackoverflow.com/a/12094837/171318 
$stream = ssh2_exec($session, "ls -al"); 
stream_set_blocking($stream, true); 
$stream = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO); 
echo stream_get_contents($stream); 

function callback($reason, $message, $language) { 
    print("callback:" . PHP_EOL); 
    print(" " . $message . PHP_EOL); 
    print(" " . $reason . PHP_EOL); 
} 

Die Callbacks werden in einer normalen Anwendung nicht aufgerufen. Dies liegt daran, dass sie nur unter bestimmten Umständen aufgerufen wurden, die unter dem im Beispiel Callback genannten Call nur aufgerufen werden, wenn ein SSH2_MSG_DISCONNECT Paket empfangen wird. Solch ein Paket wird nicht empfangen, außer der Server schließt die Verbindung, was normalerweise nicht passieren wird.

0

Wenn Sie aufgrund falscher Zugangsdaten keine Verbindung herstellen können, werden Sie sowieso keine Rückrufe erhalten, ssh2_connect() gibt in diesem Fall einfach false zurück.

Wenn Sie wirklich den Grund des Fehlers fangen wollen, können Sie Ausgabepuffer-Handler verwenden, um die Fehlermeldung zu extrahieren (vorausgesetzt, Sie haben Berichterstattung Fehler eingeschaltet):

set_error_handler(function($errno, $errstr, $errfile, $errline, array $errcontext) { 
    list($command,$errormessage)=explode(":",$errstr,2); 
    echo "Error ($errno):", $errormessage."<br><br>"; 
}); 
$connection = ssh2_connect($hostName,$port); 
restore_error_handler(); 
Verwandte Themen