Archive for the ‘SFTP’ tag
Daten verschlüsselt übertragen mit PHP und SSH
Kann man mit PHP Daten oder Dateien zwischen 2 Rechnern verschlüsselt übertragen? Natürlich kann man, wenn die Gegenstelle es auch beherrscht.
Hier soll es weder um eine Verschlüsselung zwischen Browser und Webserver (HTTPS) noch um die verschlüsselte Kommunikation zu einem Mailserver (IMAPS oder POPS) oder einem FTP (FTPS) gehen, sondern um eine Verschlüsselung zwischen 2 Rechnern mittels SSH. Wir wollen nicht eine Datei verschlüsseln (es gibt ja diverse Algorithmen dafür, angefangen bei zip+passwort, mcrypt, pgp/gpg, AES etc) und sie dann unverschlüsselt übertragen, sondern stattdessen die Verbindung ansich verschlüsseln und dann darin „unverschlüsselt“ kommunizieren.
Mit Linux-Systemen hat man am wenigsten Probleme, denn dort ist ein SSH-Server standardmäßig mit installiert und gestartet. Unter Windows muß man Software nachinstallieren, beispielsweise freeSSHd oder sshwindows. Ich muss allerdings zugeben, dass ich bisher nur mit Linux-Rechnern gearbeitet habe. Dies betrifft natürlich nur die Gegenstelle. Auf dem Rechner wo PHP läuft braucht man keinen solchen Dienst.
Damit PHP mittels SSH kommunizieren kann, muß die ssh2-extention aus der PECL geladen werden. Einfach in das php/ext Verzeichnis entpacken und dann in der php.ini laden:
extension=php_ssh2.dll|so
Eine Verbindung aufzubauen ist recht einfach. Entweder macht man das via Username+Password, oder via Key.
$connection = @ssh2_connect($host, $port); if (!$connection) throw new Exception("Could not connect to ".$host." on port ".$port); $auth_methods = ssh2_auth_none($connection, $username); if (in_array('password', $auth_methods)) { if (! @ssh2_auth_password($connection, $username, $password)) { throw new Exception("Could not authenticate with username $username and password $password."); } } elseif (in_array('publickey', $auth_methods)) { if (!ssh2_auth_pubkey_file($connection, 'root', '/path/to/ssh_keys/id_rsa.pub', '/path/to/ssh_keys/id_rsa', 'keypassword')) { throw new Exception("Could not authenticate with username $username and private key"); } } else { throw new Exception("cannot authenticate because password and privatekey are not allowed"); }
Wenn die Verbindung aufgebaut ist und der Login funktioniert hat, hat man mehrere Möglichkeiten:
- Man möchte nur den anderen Rechner steuern mittels SSH. Dann nutzt man ssh2_exec()
$stream = ssh2_exec($connection, 'whoami');
- Man möchte Dateien zwischen den beiden Rechnern austauschen. Dazu kann man via sftp oder scp eine weitere Verbindung innerhalb der SSH-Verbindung aufbauen und mit Hilfe der SSH-Wrapper einfach die copy()-Funktion nutzen.
$sftp = @ssh2_sftp($connection); if (!$sftp) { throw new Exception("Could not initialize SFTP subsystem."); } $localPath = "/home/test/testfile.txt"; $dir = "/home/target/"; $remoteFilename = "testtargetfile.txt"; $fullRemotePath = "ssh2.sftp://".$sftp.$dir.$remoteFilename; if (!file_exists($fullRemotePath)) { $result = @copy($localPath, $fullRemotePath); if ($result === false) { throw new Exception("Could not upload data file to: ".$dir." $remoteFilename"); } } else { throw new Exception("File already exists, will not overwrite: ".$dir." $remoteFilename"); }
Wie man in der Wrapper-Übersicht sehen kann, ist sftp auf jeden Fall vorzuziehen, damit kann man alles tun: Dateien lesen, schreiben, löschen usw.
Probiert es einfach mal aus, zum Beispiel um euch regelmäßig Dateien zuhause auf dem Homeserver abzulegen, oder auf den Root-Server eines Bekannten Backups zu kopieren (vorher komprimieren macht Sinn), um Daten auf seine Server im Cluster zu verteilen oder oder oder. Spätestens wenn man über unsichere Netzwerke wie das Internet kommuniziert, sollte man über Verschlüsselung nachdenken.
Hier gibt es noch Information rund um PHP und verfügbare Wrapper.