Wie leite ich Daten an eine SFTP-Verbindung weiter?

9

ftp unterstützt den put "|..." "remote-file.name"Befehl, Daten an eine ftp-Verbindung weiterzuleiten. Gibt es etwas Ähnliches für SFTP?

In SFTP erhalte ich folgenden Fehler:

sftp 'jmw@backupsrv:/uploads'
sftp> put "| tar -cx /storage" "backup-2012-06-19--17-51.tgz"
stat | tar -cv /storage: No such file or directory

Wie oben führt der SFTP-Client den Befehl offensichtlich nicht aus.

Ich möchte den Pipe-Befehl verwenden, um den Dateistream direkt nach SFTP umzuleiten. (weil nicht mehr genügend Speicherplatz vorhanden ist, um eine Sicherungsdatei auf derselben Festplatte zu erstellen, bevor sie auf den SFTP-Server hochgeladen wird.)

JMW
quelle
1
Ich habe darüber nachgedacht, ein FIFO zu verwenden, aber weder SFTP noch SCP werden von einem FIFO lesen.
Tom Anderson
1
auch gute idee, das ist meins: qxs.ch/2012/07/05/sftp-upload-tool
JMW

Antworten:

4

Da dies das erste Ergebnis ist, das Sie durch Googeln für diese Frage finden und das noch nicht erwähnt wurde, füge ich die Lösung hinzu, die ich auch hier gefunden habe:

Sie können hierfür die Curls-SFTP-Implementierung verwenden. Da curl wahrscheinlich bereits auf vielen Systemen installiert ist, wird dies möglicherweise der Lösung mit benutzerdefinierten Clients vorgezogen.

Anwendungsbeispiel:

pg_dump -d database | pigz -1 | curl -u username -T - sftp://sftpserver/folder/dbbackup.sql.gz

curlverwendet Ihre .ssh/known_hostsDatei zur Schlüsselüberprüfung. Dies kann fehlschlagen, wenn Ihr SSH-Client neuere Verschlüsselungsstandards verwendet, die von der in curl verwendeten Bibliothek nicht unterstützt werden

Um dies zu beheben, können Sie die anderen Schlüsseltypen mit dem folgenden Befehl zur bekannten Hosts-Datei hinzufügen:

ssh-keyscan sftpserver >> ~/.ssh/known_hosts

oder Sie können die Schlüsselüberprüfung mithilfe des -kFlags deaktivieren (das würde ich allerdings nicht empfehlen).

bsod
quelle
3

Ich hatte viel Spaß daran, eine Lösung für dieses Problem zu finden. Es erfordert das Tool nc (netcat) auf beiden Computern und SSH (SFTP wird nicht benötigt).

In diesem Beispiel werde ich den Computer aufrufen, der die Daten enthält, die zum Sichern von Linux-a benötigt werden, und den Computer, der das Backup von Linux-b empfangen muss.

Lassen Sie Netcat unter Linux-a einen Port abhören (ich habe 2000 genommen) und leiten Sie ihn in eine Datei um. Dies wird einfach dort sitzen und warten, bis etwas an diesem Port durchkommt.

[kenny@linux-b /var/backups]$ nc -l 2000 > backup.tgz

Öffnen Sie unter Linux-B einen SSH-Tunnel zu Linux-A, ich habe wieder Port 2000 verwendet. Dadurch wird alles, was Sie auf TCP-Port 2000 auf localhost werfen, auf TCP-Port 2000 unter Linux-a umgeleitet, wo Netcat lauscht.

[kenny@linux-a /var/data]$ ssh -L 2000:localhost:2000 -CfN linux-b

Erstellen Sie nun das Tar-Archiv, senden Sie die Ausgabe jedoch an stdout (mit -) und leiten Sie sie zur Komprimierung an gzip weiter. Leiten Sie das nun an einen anderen Netcat weiter, der es an Localhost auf TCP auf Port 2000 sendet.

[kenny@linux-a /var/data]$ tar cf - important-data | gzip -fc | nc localhost 2000

Wir sind fertig! Unter Linux-b hört der Netcat nicht mehr zu und eine neue Datei wird erstellt. Das Beste daran ist, dass das Tar-Archiv nie auf der Festplatte von Linux-A abgelegt wurde.

[kenny@linux-b /var/backups]$ file backup.tgz 
backup.tgz: gzip compressed data, from Unix, last modified: Thu Jul  5 13:48:03 2012

Ich weiß, dass es nicht genau das ist, wonach Sie in der Frage gefragt haben, aber wenn Sie Netcat zur Verfügung haben, ist es eine praktikable Lösung für Ihre Art von Problem.

Bearbeiten: Ich habe eines vergessen: Wenn Sie diese Anweisungen befolgen, haben Sie immer noch einen SSH-Tunnel unter Linux-a. Finden Sie heraus, wie die Prozess-ID lautet, und beenden Sie sie.

[kenny@linux-a /var/data]$ ps -ef | grep "ssh -L"
kenny     5741     1  0 13:40 ?        00:00:00 ssh -L 2000:localhost:2000 -CfN linux-b
kenny     5940  3360  0 14:13 pts/1    00:00:00 grep --color=auto ssh -L
[kenny@linux-a /var/data]$ kill 5741
Kenny Rasschaert
quelle
3
Ich mag es, aber es gibt 2 Probleme: sftponly Benutzer können normalerweise keine Portweiterleitung verwenden und sftponly Benutzer können nicht auf nc auf dem sftp Server zugreifen (denken Sie daran, dass sie keinen ssh-Zugriff haben)
JMW
1
Das ist durchaus berechtigte Kritik.
Kenny Rasschaert
Off-Topic, aber warum ist in diesem Beitrag ein Screenshot des "The Prestige" eingebettet?
Rilindo
2

output-stream-generating-command | ssh user@remotehost 'input-stream-accepting-command' ist eine Option, wenn Ihr Remote-Benutzer eine gültige Shell hat.

voretaq7
quelle
5
Dies ist NICHT sftp!
Jirib
3
@JiriXichtkniha Nein, das ist es nicht, jedoch wird SFTP fast immer als Subsystem Ihres SSH-Servers implementiert, und dies ist das nächste Analogon zu der Funktionalität, die in der Frage angefordert wird (Pipe-Daten über SFTP müssen von einem Programm verarbeitet werden) am anderen Ende). Manchmal lautet die Antwort "Sie verwenden das falsche Werkzeug - tun Sie es thisstattdessen." - Das scheint mir eine dieser Zeiten zu sein.
voretaq7
2
sftp ist protol und unterscheidet sich von nur Piping über ssh, das war's! Ihr Vorschlag würde nicht funktionieren, wenn der Remote-Teil nur SFTP wäre.
Jirib
1
Ich darf mich nicht als SSH-Benutzer anmelden
JMW
1
@JMW in diesem Fall, soweit ich weiß, sind Sie hier ziemlich durchgeknallt - ich habe noch nie eine Version von sftp gesehen, die das SWeiterleiten an einen Befehl auf dem Remote-System unterstützt (wahrscheinlich, weil dies das Ecure-Bit besiegen würde, indem jemand hineingelassen würde Ihre Situation, in der ohnehin keine Shell ausgeführt wird). Ich könnte mich jedoch irren - ich bin hauptsächlich mit der SFTP-Funktionalität in OpenSSH und dem proprietären SSH-Server vertraut, den Sun für den
Versand
1

voretaq7 wies darauf hin, dass der sftp-client keine leitungsdatenübertragung für benutzer unterstützt, die sftp nur zur verbindung mit dem server verwenden dürfen.

Zum Glück gibt es libssh2, das SFTP unterstützt. Wir brauchen also nur 2 andere Clients, die libssh2 verwenden und die ich aufgerufen habe:

  • sftp_stdin_upload (zum Hochladen auf einen SFTP-Server)
  • sftp_stdout_download (zum Herunterladen von einem SFTP-Server)

Der Quellcode befindet sich unter der folgenden URL: http://www.qxs.ch/2012/07/05/sftp-upload-tool/


Da ich nicht so viel Erfahrung mit libssh2-Programmierung habe, freue ich mich über jede Rückmeldung zum Quellcode.

JMW
quelle
Funktioniert bei mir nicht :-( / usr / bin / ld: libssh2-1.4.2 / src / .libs / libssh2.a (unknownhost.o): undefinierter Verweis auf das Symbol 'EVP_sha1' / usr / lib / libcrypto. so.1.0.0: Fehler beim Hinzufügen von Symbolen: DSO fehlt in der Befehlszeile collect2: Fehler: ld hat 1 Exit-Status zurückgegeben
tobixen
Dieser Code hat nur einen POC-Status. Fühlen Sie sich frei, es selbst zu reparieren. :-)
JMW