118 votes

scp des fichiers via un hôte intermédiaire

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

A -> B
B <-> C

J'ai besoin d'obtenir des fichiers de A à C, donc je pourrais scp les fichiers de A à B, et ensuite les scp de B à C. Cependant, B n'a pas beaucoup d'espace disque, donc ce n'est pas une option. Existe-t-il un moyen de scp les fichiers de A vers C via B ? Remarque : je n'ai pas d'accès root sur l'une des machines, je ne pense donc pas pouvoir configurer de tunnels persistants, mais corrigez-moi si je me trompe !

144voto

James Mertz Points 390

ProxyJump

Nouveau dans OpenSSH 7.3 :

A$ scp -oProxyJump=B thefile C:destination

(En coulisses, cela utilise simplement ProxyCommand et ssh -W .)

ProxyCommand

Mis à jour pour inclure les -W des autres réponses :

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

Si A a installé un très vieux client SSH (sans -W ), ou si B est configuré pour interdire le transfert 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

Tuyaux

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 tuer le programme précédemment lancé. ssh (qui est passé à l'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. C'est utile si ssh doit demander des mots de passe ou des phrases de passe, mais que l'utilisateur veut qu'il soit en arrière-plan. Ceci implique -n.
  • -N N'exécutez pas une commande à distance. Cette option est utile pour le transfert de ports.

Tunnel inversé à travers B vers A

Mais ça ne marche pas toujours :

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 (serveur) distant doivent être transférées à l'hôte et au port donnés, ou au socket Unix, du côté local.

36voto

Dan Bloch Points 481

Les versions de scp datant de début 2011 et plus tard 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 tu as ça, tu peux juste courir :

B$ scp -3 A:file C:file

9voto

Martin Peck Points 8078
ssh -L 4321:hostC:22 youruser@hostB

dans un autre Shell :

scp -P 4321 localfile youruser@127.0.0.1

Il s'agit d'utiliser la redirection 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.

En guise d'explication, -L y -R vous permettent de transférer des ports. Dans -L le premier port indiqué est le port sur lequel ssh commencera à écouter sur la machine d'origine (hôte A), et il transmettra tout ce qu'il recevra sur ce port via votre connexion SSH à l'hôte B, puis à l'hôte C sur le port 22.

modifier

Je me suis un peu trompé dans la syntaxe. Il met en place un forward sur votre machine LOCALE.

9voto

SQ9MCP Points 91

Presque tout a déjà été dit mais voici mon dernier sou : j'utilise la variante de ProxyCommand sans nc ni soc . Sur la base de _Proxies OpenSSH et Jumphost Cookbook_ J'ai réalisé la configuration suivante :

  1. Nous avons donc les joueurs suivants :

    • HOME_HOST : c'est à partir de là que nous copions un fichier vers l'hôte cible.
    • HOP_HOST : nous copions par le biais de cet hôte (connecté en tant que HOP_USER)
    • TARGET_HOST : c'est notre destination (authentifié comme TARGET_USER)
  2. Tout d'abord, j'ai ajouté ma clé publique locale depuis mon hôte d'origine. .ssh/id_dsa.pub a .ssh/authorized_keys sur les hôtes de départ et d'arrivée. Oui, la même clé publique de l'hôte d'origine vers les deux. Normalement, on s'attend à ce que ce soit la clé publique du HOP qui soit ajoutée à celle de la TARGET.

  3. Puis j'ai modifié .ssh/config un peu en ajoutant l'entrée suivante :

    Host TARGET_HOST
       User TARGET_USER
       ProxyCommand ssh -W %h:%p HOP_USER@HOP_HOST
  4. Ensuite, l'opération de copie est aussi simple que cela : scp FILE TARGET_HOST: . Il affiche des bannières doubles à partir des nœuds de départ et d'arrivée, mais il fonctionne.

Bien sûr, vous pouvez utiliser le système ci-dessus pour vous connecter directement à la cible : ssh TARGET_HOST . Il fonctionne avec scp et ssh.

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

4voto

jmc1337 Points 41

La réponse de Grawity concernant ProxyCommand a fonctionné pour moi, mais comme je suis moins familier avec SSH, j'ai dû faire quelques essais. J'ai pensé que je pourrais expliquer la réponse de Grawity avec plus de détails pour aider les autres débutants en SSH comme moi. Voici les définitions pour une notation plus explicite :

Machine A : la machine sur laquelle vous vous trouvez

Serveur B : userB@ip.address.for.B (l'hôte de saut ou le serveur intermédiaire)

Serveur C : userC@ip.address.for.C (le serveur distant vers lequel vous souhaitez effectuer la copie)

ProxyCommnad

    A$ scp -oProxyCommand="ssh -W %h:%p userB@ip.address.for.B" thefile userC@ip.address.for.C:destination

Exemple concret

Pour un exemple concret, disons que vous avez accès à un serveur avec l'IP 0.0.1.2 avec un compte utilisateur nommé bar (Serveur C). Mais pour y accéder, vous devez d'abord vous connecter à un serveur dont l'IP est la suivante 0.0.1.1 avec un compte utilisateur nommé foo (Serveur B). Vous voulez maintenant copier le fichier baz.txt situé sur votre machine actuelle (Machine A) vers le serveur 0.0.1.2 's /home/bar/ répertoire. Pour utiliser les ProxyCommand pour cet exemple, vous devez exécuter ce qui suit :

    A$ scp -oProxyCommand="ssh -W %h:%p foo@0.0.1.1" baz.txt bar@0.0.1.2:/home/bar/

Vous pouvez tout aussi bien copier un fichier à partir 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/ puis vous pouvez le copier sur votre machine en utilisant :

    A$ scp -oProxyCommand="ssh -W %h:%p foo@0.0.1.1" bar@0.0.1.2:/home/bar/baz.txt /destination/path/on/A

J'espère que cela aidera les personnes qui ont besoin que les choses leur soient expliquées un peu plus que les autres.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X