Was ist der beste Weg, eine Datei über eine SSH-Sitzung von einem Remote-Host auf einen lokalen Host zu übertragen?

StackOverflow https://stackoverflow.com/questions/49896

  •  09-06-2019
  •  | 
  •  

Frage

Wenn ich über SSH eine Verbindung zu Remote-Hosts herstelle, möchte ich häufig eine Datei von diesem System zur Anzeige oder Verarbeitung auf das lokale System übertragen.Gibt es eine Möglichkeit, die Datei zu kopieren, ohne (a) ein neues Terminal zu öffnen/die SSH-Sitzung anzuhalten (b) sich erneut beim lokalen oder Remote-Host zu authentifizieren, was funktioniert (c) auch wenn einer oder beide Hosts hinter a liegen? NAT-Router?

Ziel ist es, möglichst viel vom Ist-Zustand zu nutzen:dass zwischen den beiden Maschinen eine Verbindung besteht, dass ich auf beiden authentifiziert bin, dass ich mich im Arbeitsverzeichnis der Datei befinde – ich muss also kein anderes Terminal öffnen und den Remote-Host kopieren und einfügen und Pfad hinein, was ich jetzt mache.Die beste Lösung wäre auch, dass vor Beginn der Sitzung keine Einrichtung erforderlich wäre. Wenn die Einrichtung jedoch einmalig ist oder automatisiert werden kann, ist das vollkommen akzeptabel.

War es hilfreich?

Lösung 7

Hier ist meine bevorzugte Lösung für dieses Problem.Richten Sie beim Erstellen der SSH-Sitzung einen Reverse-SSH-Tunnel ein.Dies wird durch zwei Bash-Funktionen vereinfacht:grabfrom() muss auf dem lokalen Host definiert werden, während grab() auf dem Remote-Host definiert werden sollte.Sie können alle anderen von Ihnen verwendeten SSH-Variablen hinzufügen (z. B.-X oder -Y), wie Sie es für richtig halten.

function grabfrom() { ssh -R 2202:127.0.0.1:22 ${@}; };
function grab() { scp -P 2202 $@ localuser@127.0.0.1:~; };

Verwendung:

localhost% grabfrom remoteuser@remotehost
password: <remote password goes here>
remotehost% grab somefile1 somefile2 *.txt
password: <local password goes here>

Positiv:

  • Es funktioniert ohne spezielle Software auf beiden Hosts außer OpenSSH
  • Es funktioniert, wenn sich der lokale Host hinter einem NAT-Router befindet
  • Es kann als Paar aus zwei einzeiligen Bash-Funktionen implementiert werden

Negativ:

  • Es verwendet eine feste Portnummer, also:
    • funktioniert nicht mit mehreren Verbindungen zum Remote-Host
    • könnte mit einem Prozess in Konflikt geraten, der diesen Port auf dem Remote-Host verwendet
  • Es erfordert, dass localhost SSH-Verbindungen akzeptiert
  • Beim Einleiten der Sitzung ist ein spezieller Befehl erforderlich
  • Die Authentifizierung gegenüber dem Localhost erfolgt nicht implizit
  • Es ist nicht möglich, das Zielverzeichnis auf localhost anzugeben
  • Wenn Sie von mehreren lokalen Hosts auf denselben Remote-Host zugreifen, möchte SSH nicht, dass sich die Schlüssel ändern

Zukünftige Arbeit:Das ist immer noch ziemlich klobig.Offensichtlich wäre es möglich, das Authentifizierungsproblem durch die entsprechende Einrichtung von SSH-Schlüsseln zu lösen, und es ist sogar noch einfacher, die Angabe eines Remote-Verzeichnisses zu ermöglichen, indem man einen Parameter zu grab() hinzufügt.

Schwieriger ist es, die anderen negativen Aspekte anzugehen.Es wäre schön, einen dynamischen Port auszuwählen, aber soweit ich weiß, gibt es keine elegante Möglichkeit, diesen Port an die Shell auf dem Remote-Host zu übergeben.Soweit ich das beurteilen kann, erlaubt OpenSSH nicht, beliebige Umgebungsvariablen auf dem Remote-Host festzulegen, und Bash kann keine Umgebungsvariablen von einem Befehlszeilenargument übernehmen.Selbst wenn Sie einen dynamischen Port auswählen könnten, gibt es keine Möglichkeit sicherzustellen, dass er nicht auf dem Remote-Host verwendet wird, ohne vorher eine Verbindung herzustellen.

Andere Tipps

zssh (A ZMODEM Wrapper über OpenSh) macht genau das, was Sie wollen.

  • Installieren zssh und verwenden Sie es anstelle von openssh (was Sie meiner Meinung nach normalerweise verwenden)

  • Das musst du haben lrzsz Paket auf beiden Systemen installiert.

Dann, um eine Datei zu übertragen zyxel.png vom Remote- zum lokalen Host:

antti@local:~$ zssh remote
Press ^@ (C-Space) to enter file transfer mode, then ? for help
...
antti@remote:~$ sz zyxel.png
**B00000000000000
^@
zssh > rz
Receiving: zyxel.png
Bytes received:  104036/ 104036   BPS:16059729

Transfer complete
antti@remote:~$ 

Das Hochladen verläuft ähnlich, nur dass Sie einfach wechseln rz(1) Und Gr.(1).

Putty-Benutzer können es versuchen Le Putty, das eine ähnliche Funktionalität hat.

Auf einer Linux-Box verwende ich den SSH-Agenten und SSHFS.Sie müssen den SSHD so einrichten, dass er Verbindungen mit Schlüsselpaaren akzeptiert.Dann verwenden Sie ssh-add, um Ihren Schlüssel zum SSH-Agenten hinzuzufügen, sodass Sie nicht jedes Mal Ihr Passwort eingeben müssen.Stellen Sie sicher, dass Sie -t Sekunden verwenden, damit der Schlüssel nicht ewig geladen bleibt.
ssh-add -t 3600 /home/user/.ssh/ssh_dsa

Danach,
sshfs-Hostname:/ /PathToMountTo/
mountet das Serverdateisystem auf Ihrem Computer, sodass Sie Zugriff darauf haben.

Persönlich habe ich ein kleines Bash-Skript geschrieben, das meinen Schlüssel hinzufügt und die Server bereitstellt, die ich am häufigsten verwende. Wenn ich also mit der Arbeit beginne, muss ich nur das Skript starten und meine Passphrase eingeben.

Verwendung einiger wenig bekannter und selten verwendeter Funktionen von openssh Implementierung können Sie genau das erreichen, was Sie wollen!

  • nutzt den aktuellen Stand aus
  • Sie können das Arbeitsverzeichnis verwenden, in dem Sie sich befinden
  • erfordert keine Tunneleinrichtung, bevor die Sitzung beginnt
  • erfordert kein Öffnen eines separaten Terminals oder einer separaten Verbindung
  • kann als einmaliges Angebot in einer interaktiven Sitzung oder als Teil einer automatisierten Sitzung verwendet werden

Sie sollten nur das eingeben, was jeweils steht local>, remote>, Undssh> Eingabeaufforderungen in den folgenden Beispielen.

local> ssh username@remote
remote> ~C
ssh> -L6666:localhost:6666
remote> nc -l 6666 < /etc/passwd
remote> ~^Z
[suspend ssh]
[1]+  Stopped                 ssh username@remote
local> (sleep 1; nc localhost 6666 > /tmp/file) & fg
[2] 17357
ssh username@remote
remote> exit
[2]-  Done                    ( sleep 1; nc localhost 6666 > /tmp/file )
local> cat /tmp/file
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
...

Oder, öfter, Sie möchten in die andere Richtung gehen, zum Beispiel, wenn Sie Sie möchten so etwas wie Ihre ~/.ssh/id_rsa.pub Datei aus Ihren lokalen Rechner auf den ~/.ssh/authorized_keys Datei der entfernten Maschine.

local> ssh username@remote
remote> ~C
ssh> -R5555:localhost:5555
remote> ~^Z
[suspend ssh]
[1]+  Stopped                 ssh username@remote
local> nc -l 5555 < ~/.ssh/id_rsa.pub &
[2] 26607
local> fg
ssh username@remote
remote> nc localhost 5555 >> ~/.ssh/authorized_keys
remote> cat ~/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2ZQQQQBIwAAAQEAsgaVp8mnWVvpGKhfgwHTuOObyfYSe8iFvksH6BGWfMgy8poM2+5sTL6FHI7k0MXmfd7p4rzOL2R4q9yjG+Hl2PShjkjAVb32Ss5ZZ3BxHpk30+0HackAHVqPEJERvZvqC3W2s4aKU7ae4WaG1OqZHI1dGiJPJ1IgFF5bWbQl8CP9kZNAHg0NJZUCnJ73udZRYEWm5MEdTIz0+Q5tClzxvXtV4lZBo36Jo4vijKVEJ06MZu+e2WnCOqsfdayY7laiT0t/UsulLNJ1wT+Euejl+3Vft7N1/nWptJn3c4y83c4oHIrsLDTIiVvPjAj5JTkyH1EA2pIOxsKOjmg2Maz7Pw== username@local

Eine kleine Erklärung ist angebracht.

Der erste Schritt besteht darin, eine zu öffnen LocalForward;Wenn Sie noch nicht dann können Sie die ~C Escape-Zeichen, um eine ssh-Befehlszeile, die Ihnen die folgenden Befehle gibt:

remote> ~C
ssh> help
Commands:
      -L[bind_address:]port:host:hostport    Request local forward
      -R[bind_address:]port:host:hostport    Request remote forward
      -D[bind_address:]port                  Request dynamic forward
      -KR[bind_address:]port                 Cancel remote forward

In diesem Beispiel erstelle ich eine LocalForward auf Port 6666 von localhost sowohl für den Client als auch für den Server;Die Portnummer kann eine beliebige beliebiger offener Port.

Der nc Der Befehl stammt von der netcat Paket;Es wird als die "TCP/IP Schweizer Taschenmesser";Es handelt sich um eine einfache, aber sehr flexible und nützliches Programm.Machen Sie es zu einem Standardbestandteil Ihres Unix-Werkzeuggürtels.

An dieser Stelle nc lauscht auf Port 6666 und wartet auf einen weiteren Programm, um eine Verbindung zu diesem Port herzustellen, damit es den Inhalt von /etc/passwd.

Als nächstes verwenden wir ein weiteres Escape-Zeichen ~^Z welches ist tildegefolgt von control-Z.Dadurch wird der SSH-Prozess vorübergehend unterbrochen und lässt uns in unser Schneckenhaus zurückfallen.

Eine Rückseite auf dem lokalen System, die Sie verwenden können nc , um eine Verbindung mit dem Port 6666 weitergeleitet.Beachten Sie das Fehlen eines -l in diesem Fall, weil diese option teilt mit: nc auf einem Port zu lauschen, als wäre es ein Server, der nicht das, was wir wollen;Stattdessen wollen wir einfach verwenden nc als Kunde, um Verbinden Sie sich mit dem bereits zuhörenden nc auf der entfernten Seite.

Der Rest der Magie rund um das nc ist erforderlich, da wenn Sie erinnern sich, dass ich oben sagte, dass die ssh Prozess wurde vorübergehend ausgesetzt werden, so dass die & werde das ganze setzen (sleep + nc) Ausdruck in den Hintergrund und die sleep gibt Ihnen genug Zeit, damit SSH Rückkehr in den Vordergrund mit fg.

Im zweiten Beispiel ist die Idee im Grunde die gleiche, außer dass wir ein Tunnel in die andere Richtung mit -R anstatt -L Sodass Wir etablieren eine RemoteForward.Und dann ist auf der lokalen Seite, wo Sie möchten die Funktion -l Argument zu nc.

Das Escape-Zeichen ist standardmäßig ~, aber Sie können das ändern mit:

 -e escape_char
         Sets the escape character for sessions with a pty (default: ‘~’).  The escape character is only recognized at the beginning of a line.  The escape character followed by a dot
         (‘.’) closes the connection; followed by control-Z suspends the connection; and followed by itself sends the escape character once.  Setting the character to “none” disables any
         escapes and makes the session fully transparent.

Eine vollständige Erklärung der mit den Escape-Zeichen verfügbaren Befehle finden Sie im SSH-Manpage

ESCAPE CHARACTERS
     When a pseudo-terminal has been requested, ssh supports a number of functions through the use of an escape character.

     A single tilde character can be sent as ~~ or by following the tilde by a character other than those described below.  The escape character must always follow a newline to be interpreted
     as special.  The escape character can be changed in configuration files using the EscapeChar configuration directive or on the command line by the -e option.

     The supported escapes (assuming the default ‘~’) are:

     ~.      Disconnect.

     ~^Z     Background ssh.

     ~#      List forwarded connections.

     ~&      Background ssh at logout when waiting for forwarded connection / X11 sessions to terminate.

     ~?      Display a list of escape characters.

     ~B      Send a BREAK to the remote system (only useful for SSH protocol version 2 and if the peer supports it).

     ~C      Open command line.  Currently this allows the addition of port forwardings using the -L, -R and -D options (see above).  It also allows the cancellation of existing remote port-
             forwardings using -KR[bind_address:]port.  !command allows the user to execute a local command if the PermitLocalCommand option is enabled in ssh_config(5).  Basic help is avail‐
             able, using the -h option.

     ~R      Request rekeying of the connection (only useful for SSH protocol version 2 and if the peer supports it).

Die Verwendung von ControlMaster (der Schalter -M) ist die beste Lösung, viel einfacher und einfacher als die anderen Antworten hier.Es ermöglicht Ihnen, eine einzelne Verbindung für mehrere Sitzungen gemeinsam zu nutzen.Klingt so, als ob es tut, was der Poster will.Sie müssen jedoch immer noch die scp- oder sftp-Befehlszeile eingeben.Versuch es.Ich verwende es für mein gesamtes SSH.

Zu diesem Zweck habe ich meinen Heimrouter so eingerichtet, dass er Port 22 zurück an meinen Heimcomputer weiterleitet (der durch eine Firewall geschützt ist und nur SSH-Verbindungen von meinem Arbeitscomputer akzeptiert), und ich habe auch ein Konto bei eingerichtet DynDNS um dynamisches DNS bereitzustellen, das automatisch zu meiner Heimat-IP aufgelöst wird.

Wenn ich dann eine SSH-Verbindung zu meinem Arbeitscomputer herstelle, führe ich als Erstes ein Skript aus, das einen SSH-Agenten startet (falls Ihr Server dies nicht automatisch tut).Das Skript, das ich ausführe, ist:

#!/bin/bash

ssh-agent sh -c 'ssh-add < /dev/null && bash'

Es fragt nach der Passphrase meines SSH-Schlüssels, damit ich sie nicht jedes Mal eingeben muss.Dieser Schritt ist nicht erforderlich, wenn Sie einen SSH-Schlüssel ohne Passphrase verwenden.

Für den Rest der Sitzung ist das Zurücksenden von Dateien an Ihren Heimcomputer ganz einfach

scp file_to_send.txt your.domain.name:~/

Hier ist ein Hack namens ssh-xfer Dies behebt genau das Problem, erfordert jedoch das Patchen von OpenSSH, was meiner Meinung nach ein Nichtstarter ist.

Sie können das SCP-Protokoll zum Übertragen einer Datei verwenden. Sie können auf diesen Link verweisen

http://tekheez.biz/scp-protocol-in-unix/

Sie sollten in der Lage sein, öffentliche und private Schlüssel einzurichten, sodass keine Authentifizierung erforderlich ist.

Wie Sie vorgehen, hängt von den Sicherheitsanforderungen usw. ab (beachten Sie, dass es Linux/Unix-SSH-Würmer gibt, die nach Schlüsseln suchen, um andere Hosts zu finden, die sie angreifen können).

Ich mache das ständig hinter Linksys- und Dlink-Routern.Ich denke, dass Sie möglicherweise ein paar Einstellungen ändern müssen, aber das ist keine große Sache.

Verwenden Sie den Schalter -M.

„Versetzt den SSH-Client in den ‚Master‘-Modus für die gemeinsame Nutzung von Verbindungen.Mehrere -M-Optionen versetzen SSH in den „Master“-Modus, wobei eine Bestätigung erforderlich ist, bevor Slave-Verbindungen akzeptiert werden.Einzelheiten finden Sie in der Beschreibung von ControlMaster in ssh_config(5).

Ich verstehe nicht ganz, wie das die Frage des OP beantworten soll – kannst du das etwas näher erläutern, David?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top