web-dev-qa-db-fra.com

fichiers scp via l'hôte intermédiaire

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!

74
astrofrog

ProxyJump

Nouveau dans OpenSSH 7.3:

A$ scp -oProxyJump=B thefile C:destination

(En coulisse, cela utilise simplement 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 un très ancien client SSH est installé sur A (sans la prise en charge de -W) ou si B est configuré pour interdire le transfert de TCP (mais autorise toujours 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 processus ssh précédemment démarré (qui est passé en arrière-plan en raison de -f -N).

  • -f Demande à 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.
  • -N Ne pas exécuter une 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 donné 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.
96
grawity

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
23
Dan Bloch

Presque tout a déjà été dit mais voici mon dernier sou: j'utilise la variante ProxyCommand sans nc ni 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 le nom HOP_USER)
    • TARGET_Host: c'est notre destination (authentifié comme TARGET_USER)
  2. J'ai d'abord ajouté ma clé publique locale de l'hôte hôte .ssh/id_dsa.pub à .ssh/authorized_keys sur les hôtes de saut et cibles. Oui, la même clé publique de l'hôte d'accueil aux deux. En général, vous vous attendez à ce que ce soit la clé publique HOP que vous devez ajouter à la clé TARGET.

  3. Puis j'ai légèrement modifié .ssh/config en ajoutant l'entrée suivante:

    Host TARGET_Host
       User TARGET_USER
       ProxyCommand ssh -W %h:%p HOP_USER@HOP_Host
    
  4. Après cela, 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 sur 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 se 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.

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

À titre d’explication, -L et -R vous permettent de transférer des ports. Dans -L, le premier port indiqué est le port que ssh commencera à écouter sur la machine d'origine (hôte A) et transmettra tout ce qu'il reçoit 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.

7
Brian Vandenberg

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

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

Server 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

Ainsi, pour un exemple concret, supposons que vous avez accès à un serveur avec IP 0.0.1.2 avec un compte d'utilisateur nommé bar (Serveur C). Mais pour y accéder, vous devez d'abord vous connecter à un serveur avec l'adresse IP 0.0.1.1 avec un compte d'utilisateur nommé foo (Serveur B). Vous souhaitez maintenant copier le fichier baz.txt situé sur votre ordinateur actuel (ordinateur A) dans le répertoire du serveur 0.0.1.2's /home/bar/. Pour utiliser le ci-dessus ProxyCommand, dans cet exemple, vous exécuteriez ce qui suit:

    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.2 situé à /home/bar/, vous pouvez le copier sur votre ordinateur 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.

1
Joseph Carmack