web-dev-qa-db-fra.com

Comment effectuer des transferts Multihop SCP?

Je souhaite copier un fichier de ma machine A vers le serveur C, mais n'ai accès qu'au serveur C via le serveur B.

Au lieu de transférer d'abord sur le serveur B, connectez-vous puis transférez sur le serveur C, est-il possible de transférer le fichier directement avec SCP ou des programmes similaires?

(Emacs tramp-mode a cette fonctionnalité pour éditer des fichiers à distance).

87
sverrejoh

Vous pouvez ajouter -o options sur scp au lieu de .ssh/config.

scp -o ProxyCommand="ssh $jump_Host nc $Host 22" $local_path $Host:$destination_path

$jump_Host est votre "serveur B" dans ce cas.

48
John Tantalo

En supposant OpenSSH, ajoutez à votre configuration SSH dans .ssh/config

Host distant
ProxyCommand ssh near nc distant 22

Cela permettra à SSH de se connecter "directement" à la machine nommée distante en effectuant un proxy via la machine nommée near. Il peut ensuite utiliser des applications comme scp et sftp sur la machine distante.

Pour que cela fonctionne, vous avez besoin de "nc" aka netcat installé sur la machine nommée near. Mais beaucoup de systèmes modernes l'ont déjà.

la solution tar de Towo est plus efficace pour les problèmes ponctuels, en supposant que vous avez mémorisé la syntaxe et les règles de fonctionnement de tar.

44
tialaramex

Avec des versions plus récentes de ssh sur le serveur près de la machine (B), ce qui suit fonctionnera sans netcat:

Host distant
    ProxyCommand ssh near -W distant:22

Il faudra cependant que AllowTcpForwarding soit oui (par défaut) sur la machine proche (B)

edit: nécessite OpenSSH 5.4+ sur B

19
danblack

Vous pouvez ssh vers le serveur B en utilisant quelque chose comme

ssh -L 5022:<server C IP>:22 <user_serverB>@<server B IP>

Ensuite, vous pouvez ssh vers le serveur C en utilisant

ssh -p 5022 <user_serverC>@localhost 

De même, scp fonctionnerait en utilisant

scp -P 5022 foo.txt <user_serverc>@localhost:

N'oubliez pas d'utiliser la casse correcte de p avec scp et ssh

18
Saurabh Barjatiya

C'est possible et relativement facile, même lorsque vous devez utiliser des certificats pour l'authentification (typique dans les environnements AWS).

La commande ci-dessous copiera les fichiers d'un remotePath sur server2 directement dans votre machine à localPath. En interne, la demande scp est mandatée via server1.

scp -i user2-cert.pem -o ProxyCommand="ssh -i user1-cert.pem -W %h:%p user1@server1" user2@server2:/<remotePath> <localpath>

L'inverse fonctionne également (télécharger le fichier):

scp -i user2-cert.pem -o ProxyCommand="ssh -i user1-cert.pem -W %h:%p user1@server1" <localpath> user2@server2:/<remotePath>

Si vous utilisez plutôt l'authentification par mot de passe, essayez avec

scp -o ProxyCommand="ssh -W %h:%p user1@server1" user2@server2:/<remotePath> <localpath>

Si vous utilisez les mêmes informations d'identification d'utilisateur sur les deux serveurs:

scp -o ProxyCommand="ssh -W %h:%p commonuser@server1" commonuser@server2:/<remotePath> <localpath>
5
donhector

Si vous voulez être vraiment méchant, vous pouvez enchaîner ssh et tar, quelque chose comme tar c mydir | ssh server "ssh otherserver | tar x", mais cela peut se heurter à toutes sortes de problèmes.

Le moyen le plus simple serait simplement de configurer un tunnel SSH avec les méthodes intégrées de SSH; regarde le -D basculez dans la page de manuel et transférez simplement un port vers le port ssh de l'autre serveur.

3
towo

Vous pouvez également le faire à l'envers et c'est peut-être plus facile.

Supposons que vous ayez une session ssh ouverte avec la machine à laquelle vous souhaitez envoyer le fichier. Ce PC le plus éloigné, nous l'appellerons hop2. Votre hôte "proxy" sera hop1. Le PC qui est fichier-Origin, nous l'appellerons Origin.

Origin:~/asdf.txt  --> hop1 --> hop2:~/asdf.txt

Vous pouvez créer des tunnels rendant un port local disponible sur un PC distant. Nous définissons ainsi un port à ouvrir sur le PC distant, qui sera une redirection vers le port sur lequel vous vous êtes arrêté lorsque vous avez construit le tunnel.

Sur hop2:

ssh -R 5555:127.0.0.1:22 <hop1_user>@<hop1_IP>
#this has the effect of building a tunnel from hop2 to hop1, making hop2's port 22 available on hop1 as port 5555

Maintenant, dans cette session de tunnel ouverte, vous pouvez faire la même chose de hop1 à file_Origin.

Sur hop1:

ssh -R 6666:127.0.0.1:5555 <Origin_user>@<Origin_IP>
#this has the effect of building a tunnel from hop1 to Origin while also pulling the active tunnel with it, making hop1's port 5555 (hop2's port 22) available on Origin as port 6666.

Vous êtes maintenant tunnelé de hop2 à hop1 vers Origin. Par coïncidence, les ports 5555 et 6666 sont désormais ouverts sur Origin, qui sont des redirections vers le port 22. de hop2 Dans cette session, les deux routes suivantes sont des routes scp valides vers hop2:

à l'origine:

scp -P 6666 ~/asdf.txt <hop2_user>@<127.0.0.1>:~/asdf.txt

De cette façon, vous pouvez avoir un nombre arbitraire de sauts entre les deux, et il est plus facile de travailler avec pour enchaîner plus de deux sauts.

2
SYANiDE

Essayez d'adapring l'exemple de configuration openssh suivant pour une configuration qui peut être utilisée pour plusieurs hôtes:

Host uat-*
     ProxyCommand ssh bastion-uat nc %h %p

Cela suppose un ensemble de serveurs commençant par "uat-" qui ne sont accessibles que via le serveur jumpbox/passerelle "bastion-uat". Vous souhaitez probablement également ajouter ForwardAgent yes si vous utilisez une clé pour vous connecter.

1
Benjamin Goodacre

Ce n'est pas scp (qu'OP a demandé), mais j'ai trouvé super simple d'utiliser rsync pour copier du local vers le distant sur un seul saut avec:

rsync -v -e 'ssh -A -t user@jumpserver ssh -A -t user@destinationserver' /path/to/sourcefile :/path/to/destination

Source: http://mjbright.blogspot.com/2012/09/using-rsync-over-multi-hop-ssh.html

J'avais essayé la suggestion -o ProxyPass ci-dessus et je ne voulais pas changer la configuration pour mes besoins changeants. Comme l'indique l'auteur du lien ci-dessus, le fichier de destination précédant deux-points (:) est important pour indiquer que le chemin spécifié se trouve sur le serveur de destination. En outre, en utilisant rsync, vous avez les options de comparaison de dates, de synchronisation de dossiers, etc. J'espère que cela aide quelqu'un!

1
texas-bronius