fichiers scp via l'hôte intermédiaire

85

J'ai accès à 3 machines, A, B et C. Les seules connexions possibles (ssh) sont:

A -> B
B <-> C

Je dois obtenir des fichiers de A à C pour pouvoir scp les fichiers de A à B, puis de B à C. Toutefois, B ne disposant pas de beaucoup d'espace disque, ce n'est donc pas une option. Est-il possible de scp des fichiers de A à C via B? Notez que je ne dispose pas d'un accès root sur aucune des machines. Ne pensez donc pas que je peux configurer des tunnels persistants, mais corrigez-moi si je me trompe!

astrofrog
la source
6
Je sais que cela ne répond pas à la question, mais pour ceux qui ne connaissent pas rsync, ou ne savent pas comment l'utiliser, pour passer d'un hôte à l'autre, cela pourrait être une astuce utile: utilisez l'option '-e' avec rsync comme ceci:A$ rsync <options> -e 'ssh B ssh' source C:destination
Eddified

Réponses:

108

ProxyJump

Nouveau dans OpenSSH 7.3:

A$ scp -oProxyJump=B thefile C:destination

(En coulisse, cela n’utilise que ProxyCommand et ssh -W.)

ProxyCommand

Mise à jour pour inclure -W à partir d'autres réponses:

A$ scp -oProxyCommand="ssh -W %h:%p B" thefile C:destination

Si A possède un très ancien client SSH installé (sans -Wsupport) ou si B est configuré pour interdire le transfert TCP (tout en autorisant les commandes shell), utilisez des alternatives:

A$ scp -oProxyCommand="ssh B socat stdio tcp:%h:%p" thefile C:destination
A$ scp -oProxyCommand="ssh B nc %h %p" thefile C:destination

Les pipes

A$ tar cf - thefile anotherfile | ssh B "ssh C \"cd destination && tar xvf -\""
A$ (echo thefile; echo anotherfile) | cpio -o | ssh B "ssh C \"cd destination && cpio -i\""

Pour un seul fichier:

A$ ssh B "ssh C \"cd destination && cat > thefile\"" < thefile

"Tunnel" à travers B

A$ ssh -f -N -L 4567:C:22 B
(continues running in background)

A$ scp -P 4567 thefile localhost:destinationPath

Lorsque vous avez terminé, n'oubliez pas de supprimer le sshprocessus précédemment lancé (qui est passé à l'arrière-plan en raison de -f -N).

  • -fDemande à ssh de passer en arrière-plan juste avant l'exécution de la commande. Ceci est utile si ssh va demander des mots de passe ou des phrases secrètes, mais que l'utilisateur le souhaite en arrière-plan. Cela implique -n.
  • -NN'exécutez pas de commande à distance. Ceci est utile pour simplement transférer des ports.

Inverser le "tunnel" par B à A

Ne fonctionne pas toujours bien:

A$ ssh -f -N -R 4567:localhost:22 B
(now you can reach A from B, by using localhost:4567)

B$ scp -P 4567 localhost:thefile C:destination
  • -R Spécifie que les connexions au port TCP ou au socket Unix indiqué sur l'hôte distant (serveur) doivent être transférées vers l'hôte et le port donnés, ou le socket Unix, du côté local.
Grawity
la source
Merci beaucoup pour ces exemples @grawity. Une question - est-il possible d'inverser `tar c thefile anotherfile | ssh B "ssh C \" cd destination && tar xv \ "" ´ afin de copier le téléchargement de C à A (étant sur A)
dmeu
@dmeu: Oui, c'est possible.
Grawity
Comment "tuer" le processus ssh lancé précédemment si j'utilise un MacOS?
Aero Windwalker
Remarque: Comme d' habitude, si vous voulez scp de C, bien que B, à A, vous pouvez le faire A$ scp -oProxyJump=B C:destination thefile.
jvriesem
@Pablo Mieux vaut utiliser -S, puis, et -O exit. Ou ... au moins pkill -f.
Grawity
24

Les versions de scp de début 2011 et ultérieur peuvent avoir une option "-3":

 -3      Copies between two remote hosts are transferred through the local
         host.  Without this option the data is copied directly between
         the two remote hosts.  Note that this option disables the
         progress meter.

Si vous avez cela, vous pouvez simplement lancer:

B$ scp -3 A:file C:file
Dan Bloch
la source
Dans mon cas, l'hôte A n'était accessible que depuis B (qui était VPN). L'hôte C était sur le même réseau local que B. Je souhaitais obtenir un fichier de A à C et scp -3 l'a résolu avec brio.
Joe
J'ai eu des problèmes avec cela lorsque les deux hôtes ont demandé un mot de passe. Il semblerait demander les deux à la fois (deux invites de mot de passe sont apparues sur la même ligne) et ensuite, il n'a pas accepté mon mot de passe. Je pourrais éventuellement le faire fonctionner en tapant mon mot de passe à plusieurs reprises (le même mot de passe sur les deux hôtes), mais c'était difficile à comprendre.
Colin D
8

Presque tout a déjà été dit mais voici mon dernier sou: j'utilise la variante ProxyCommand sans ncni soc. Basé sur OpenSSH Proxies et Jumphost Cookbook, j'ai conçu la configuration suivante:

  1. Nous avons donc les joueurs suivants:

    • HOME_HOST: c'est à partir duquel on copie un fichier sur l'hôte cible
    • HOP_HOST: nous copions via cet hôte (enregistré sous HOP_USER)
    • TARGET_HOST: c'est notre destination (authentifié comme TARGET_USER)
  2. J'ai d'abord ajouté la clé publique locale de mon hôte .ssh/id_dsa.pub d'origine .ssh/authorized_keysaux hôtes cible et cible. Oui, la même clé publique de l'hôte d'accueil pour les deux. En général, vous vous attendez à ce que ce soit la clé publique HOP que vous devez ajouter à la clé TARGET.

  3. Ensuite, j'ai modifié .ssh/configun peu en ajoutant l'entrée suivante:

    Host TARGET_HOST
       User TARGET_USER
       ProxyCommand ssh -W %h:%p HOP_USER@HOP_HOST
    
  4. Après que l'opération de copie est aussi simple que: scp FILE TARGET_HOST:. Il affiche les doubles bannières des nœuds hop et cible, mais cela fonctionne.

Bien sûr , vous pouvez utiliser ci - dessus pour ssh directement à la cible: ssh TARGET_HOST. Cela fonctionne avec scp et ssh.

Une autre option plus générale pourrait être l’ utilitaire sshuttle , qui semble être une sorte de proxy transparent (vpn over ssh). Donc dans votre cas de A-> B <-> C cela permet de vous connecter à chaque nœud du réseau de C: A-> B- [CDEFG]. Il n’a pas besoin d’admin, mais nécessite Python 2.7 (3.5 aussi OK), ce qui n’est pas toujours ce que nous avons. Cela vaut la peine de l'essayer.

SQ9MCP
la source
7
ssh -L 4321:hostC:22 youruser@hostB

dans une autre coquille:

scp -P 4321 localfile [email protected]

Ceci utilise le transfert de port. La seule limitation ici est que l'hôte B doit être configuré pour autoriser le transfert de port. Sinon, cela devrait fonctionner correctement.

Dans le sens de l'explication, -Let -Rvous permettent de transférer des ports. Le -Lpremier port indiqué est que ssh commencera à écouter sur la machine d'origine (hôte A) et transmettra tout ce qu'il recevra sur ce port via votre connexion SSH à l'hôte B, puis sera acheminé vers l'hôte C sur le port 22.

modifier

J'ai un peu foiré la syntaxe. Il établit une avance sur votre machine locale.

Brian Vandenberg
la source
@astrofrog - Si l'une de nos réponses satisfait vos besoins, vous devriez probablement en accepter une.
Brian Vandenberg
2

La réponse ProxyCommand de Grawity a fonctionné pour moi, mais comme je suis moins familier avec SSH, il a fallu des expériences. Je pensais épeler plus en détail la réponse de Grawity pour aider les autres débutants de SSH comme moi. Voici les définitions pour la notation plus explicite:

Machine A: la machine sur laquelle vous vous trouvez

Serveur B: [email protected] (hôte de saut ou serveur intermédiaire)

Serveur C: [email protected] (le serveur distant sur lequel vous souhaitez copier)

ProxyCommnad

    A$ scp -oProxyCommand="ssh -W %h:%p [email protected]" thefile [email protected]:destination

Exemple concret

Donc, pour un exemple concret, disons que vous avez accès à un serveur avec IP 0.0.1.2avec un compte d'utilisateur nommé bar(Serveur C). Mais pour y arriver, vous devez d'abord vous connecter à un serveur avec IP 0.0.1.1avec un compte d'utilisateur nommé foo(Serveur B). Vous souhaitez maintenant copier le fichier baz.txtsitué sur votre ordinateur actuel (ordinateur A) dans 0.0.1.2le /home/bar/répertoire du serveur . Pour utiliser la commande Proxy ci-dessus dans cet exemple, vous devez exécuter les opérations suivantes:

    A$ scp -oProxyCommand="ssh -W %h:%p [email protected]" baz.txt [email protected]:/home/bar/

Vous pouvez également tout aussi facilement copier un fichier du serveur C en inversant l’ordre du fichier et de la destination. Ainsi, par exemple, si baz.txtétait déjà sur le serveur 0.0.1.2situé à, /home/bar/vous pouvez le copier sur votre machine en utilisant:

    A$ scp -oProxyCommand="ssh -W %h:%p [email protected]" [email protected]:/home/bar/baz.txt /destination/path/on/A

J'espère que cela aidera les personnes qui ont besoin de précisions un peu plus que les autres.

Joseph Carmack
la source