Qual è il modo migliore per portare un file da un host remoto a un host locale tramite una sessione SSH?

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

  •  09-06-2019
  •  | 
  •  

Domanda

Quando mi connetto a host remoti tramite ssh, spesso desidero portare un file su quel sistema sul sistema locale per la visualizzazione o l'elaborazione.Esiste un modo per copiare il file senza (a) aprire un nuovo terminale/mettere in pausa la sessione ssh (b) autenticarsi nuovamente sugli host locali o remoti che funzioni (c) anche quando uno o entrambi gli host sono dietro un Router NAT?

L’obiettivo è sfruttare quanto più possibile lo stato attuale:che esiste una connessione tra le due macchine, che sono autenticato su entrambe, che sono nella directory di lavoro del file --- quindi non devo aprire un altro terminale e copiare e incollare l'host remoto e percorso, che è quello che faccio adesso.Inoltre, la soluzione migliore non richiederebbe alcuna configurazione prima dell'inizio della sessione, ma se la configurazione fosse una tantum o potesse essere automatizzata, sarebbe perfettamente accettabile.

È stato utile?

Soluzione 7

Ecco la mia soluzione preferita a questo problema.Configura un tunnel ssh inverso dopo aver creato la sessione ssh.Ciò è reso semplice da due funzioni bash:grabfrom() deve essere definito sull'host locale, mentre grab() deve essere definito sull'host remoto.Puoi aggiungere qualsiasi altra variabile ssh che usi (ad es.-X o -Y) come ritieni opportuno.

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

Utilizzo:

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

Positivi:

  • Funziona senza software speciale su entrambi gli host oltre OpenSSH
  • Funziona quando l'host locale si trova dietro un router NAT
  • Può essere implementato come una coppia di due funzioni bash su una riga

Aspetti negativi:

  • Utilizza un numero di porta fisso, quindi:
    • non funzionerà con più connessioni all'host remoto
    • potrebbe entrare in conflitto con un processo che utilizza quella porta sull'host remoto
  • Richiede che localhost accetti connessioni ssh
  • Richiede un comando speciale all'avvio della sessione
  • Non gestisce implicitamente l'autenticazione sull'host locale
  • Non consente di specificare la directory di destinazione su localhost
  • Se esegui il passaggio da più host locali allo stesso host remoto, a ssh non piacerà la modifica delle chiavi

Lavoro futuro:Questo è ancora piuttosto complicato.Ovviamente sarebbe possibile gestire il problema dell'autenticazione impostando opportunamente le chiavi ssh ed è ancora più semplice consentire la specifica di una directory remota aggiungendo un parametro a grab()

Più difficile è affrontare gli altri aspetti negativi.Sarebbe carino scegliere una porta dinamica ma, per quanto ne so, non esiste un modo elegante per passare quella porta alla shell sull'host remoto;Per quanto ne so, OpenSSH non ti consente di impostare variabili di ambiente arbitrarie sull'host remoto e bash non può prendere variabili di ambiente da un argomento della riga di comando.Anche se potessi scegliere una porta dinamica, non c'è modo di garantire che non venga utilizzata sull'host remoto senza prima connettersi.

Altri suggerimenti

zssh (UN ZMODEM wrapper over openssh) fa esattamente quello che vuoi.

  • Installare zssh e usalo al posto di openssh (che presumo tu usi normalmente)

  • Dovrai avere il lrzsz pacchetto installato su entrambi i sistemi.

Quindi, per trasferire un file zyxel.png dall'host remoto all'host locale:

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:~$ 

Il caricamento avviene in modo simile, tranne per il fatto che devi semplicemente cambiare rz(1) E tg(1).

Gli utenti di Putty possono provare Il Putty, che ha funzionalità simili.

Su una macchina Linux utilizzo ssh-agent e sshfs.È necessario configurare sshd per accettare connessioni con coppie di chiavi.Quindi usi ssh-add per aggiungere la chiave a ssh-agent in modo da non dover digitare la password ogni volta.Assicurati di utilizzare -t secondi, in modo che la chiave non rimanga caricata per sempre.
ssh-add -t 3600 /home/utente/.ssh/ssh_dsa

Dopo di che,
nome host sshfs:/ /PathToMountTo/
monterà il file system del server sul tuo computer in modo che tu possa accedervi.

Personalmente, ho scritto un piccolo script bash che aggiunge la mia chiave e monta i server che utilizzo di più, quindi quando inizio a lavorare non mi resta che avviare lo script e digitare la mia passphrase.

Usando alcune caratteristiche poco conosciute e usate raramente dell'implementazione OpenSSH puoi realizzare esattamente ciò che desideri!

  • approfitta dello stato attuale
  • puoi utilizzare la directory di lavoro in cui ti trovi
  • non richiede alcuna configurazione del tunneling prima dell'inizio della sessione
  • non richiede l'apertura di un terminale o di una connessione separata
  • può essere utilizzato come offerta una tantum in una sessione interattiva o può essere utilizzato come parte di una sessione automatizzata

Dovresti solo digitare ciò che si trova in ciascuno di essi local>, remote>, Essh> richiede negli esempi seguenti.

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
...

Oppure, più spesso vuoi andare nella direzione opposta, ad esempio se vuoi fare qualcosa come trasferire il tuo ~/.ssh/id_rsa.pub file dalla macchina locale a ~/.ssh/authorized_keys File della macchina remota.

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

È opportuna una piccola spiegazione.

Il primo passo è aprire un file LocalForward;Se non ne hai già uno stabilito, puoi usare il ~C Fuga il personaggio per aprire una riga di comando ssh che ti darà i seguenti comandi:

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 questo esempio stabilisco a LocalForward sulla porta 6666 di LocalHost sia per il client che per il server;Il numero di porta può essere qualsiasi porta aperta arbitraria.

IL nc il comando proviene da netcat pacchetto;È descritto come il "coltello dell'esercito svizzero TCP/IP";È un programma semplice, ma molto flessibile e utile.Rendilo una parte standard della tua cintura degli strumenti Unix.

A questo punto nc sta ascoltando sulla porta 6666 e in attesa di un altro programma per connettersi a quella porta in modo che possa inviare il contenuto di/etc/passwd.

Successivamente utilizziamo un altro carattere di escape ~^Z che è tildeseguito da control-Z.Ciò sospende temporaneamente il processo SSH e ci rilascia nella nostra conchiglia.

Uno sul sistema locale che puoi utilizzare nc Per connettersi alla porta inoltrata 6666.Da notare la mancanza di a -l In questo caso perché questa opzione dice nc ascoltare una porta come se fosse un server che non è quello che vogliamo;invece vogliamo semplicemente usare nc come client per connettersi all'ascolto già nc sul lato remoto.

Il resto della magia intorno a nc Il comando è richiesto perché se ricordi sopra ho detto che il ssh Il processo è stato temporaneamente sospeso, quindi il & metterò il tutto (sleep + nc) espressione sullo sfondo e il sleep ti dà abbastanza tempo per SSH per tornare in primo piano con fg.

Nel secondo esempio l'idea è sostanzialmente la stessa tranne che abbiamo impostato un tunnel che va nella direzione opposta usando -R invece di -L in modo da stabilire a RemoteForward.E poi sul lato locale è dove si desidera usare il -l argomento a nc.

Il carattere di escape per impostazione predefinita è ~ ma puoi cambiarlo con:

 -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.

Una spiegazione completa dei comandi disponibili con i caratteri di escape è disponibile nel file pagina man ssh

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).

Usare ControlMaster (l'interruttore -M) è la soluzione migliore, molto più semplice e facile rispetto al resto delle risposte qui.Ti consente di condividere una singola connessione tra più sessioni.Sembra che faccia quello che vuole il poster.Tuttavia, devi comunque digitare la riga di comando scp o sftp.Provalo.Lo uso per tutto il mio lavoro.

Per fare questo ho configurato il mio router di casa per inoltrare la porta 22 al mio computer di casa (che è protetto da firewall per accettare solo connessioni ssh dal mio computer di lavoro) e ho anche configurato un account con DynDNS per fornire un DNS dinamico che si risolverà automaticamente nel mio IP di casa.

Quindi, quando accedo tramite ssh al mio computer di lavoro, la prima cosa che faccio è eseguire uno script che avvia un ssh-agent (se il tuo server non lo fa automaticamente).Lo script che eseguo è:

#!/bin/bash

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

Richiede la mia passphrase della chiave ssh in modo da non doverla digitare ogni volta.Non è necessario questo passaggio se usi una chiave ssh senza passphrase.

Per il resto della sessione, inviare i file al tuo computer di casa è semplicissimo

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

Ecco un hack chiamato ssh-xfer che risolve il problema esatto, ma richiede l'applicazione di patch a OpenSSH, che per quanto mi riguarda è un fallimento.

È possibile utilizzare il protocollo SCP per trasferire un file. Puoi fare riferimento a questo collegamento

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

Dovresti essere in grado di impostare chiavi pubbliche e private in modo che non sia necessaria alcuna autenticazione.

Il modo in cui lo fai dipende dai requisiti di sicurezza, ecc. (tieni presente che ci sono worm ssh linux/unix che esamineranno le chiavi per trovare altri host che possono attaccare).

Lo faccio continuamente da dietro sia i router Linksys che quelli dlink.Penso che potresti dover modificare un paio di impostazioni ma non è un grosso problema.

Utilizzare l'opzione -M.

"Posiziona il client ssh in modalità 'master' per la condivisione della connessione.Molteplici opzioni -M posizionano ssh in modalità "master" con la richiesta di conferma prima che le connessioni slave vengano accettate.Fare riferimento alla descrizione di ControlMaster in ssh_config(5) per i dettagli."

Non vedo bene come questo risponda alla domanda dell'OP: puoi approfondire un po' questo argomento, David?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top