Comment puis-je effectuer des transferts Multihop SCP?


85

Je souhaite copier un fichier de ma machine A sur le serveur C, mais je n'ai accès au serveur C que par le biais du serveur B.

Au lieu de transférer d'abord sur le serveur B, connectez-vous puis transférez-le 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).

Réponses:


48

Vous pouvez ajouter des -ooptions à la scpplace 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.


C'est ma façon préférée de le faire. Messagerie .ssh / config pour le multihopping n’est pas la meilleure solution si vous accédez au même hôte soit directement depuis une passerelle.
GabrieleV

Comment cela serait-il avec différents noms d'utilisateur / ports et ports?
Pablo Un

J'essaie ceci et je dois entrer un mot de passe. Comment puis-je réparer cela. Merci.
vendredi

44

En supposant OpenSSH, ajoutez-le à 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 proche. Il peut ensuite utiliser des applications telles que scp et sftp sur la machine distante.

Pour que cela fonctionne, vous devez disposer de 'nc', autrement dit netcat, sur la machine nommée à proximité. Mais beaucoup de systèmes modernes l'auront déjà.

La solution tar de towo est plus efficace pour les problèmes ponctuels, à condition que vous ayez mémorisé la syntaxe et les règles de fonctionnement de tar.


C’est la même méthode que j’utilise ... Dans cet exemple, «distant» serait le serveur C et «près», le serveur B, pour clarification…
Jeremy Bouse Le

Beaucoup de machines modernes n'ont pas 'nc': normalement, elles ne sont disponibles que sur les machines Linux et uniquement sur demande (ne font pas partie de l'installation standard).
Mei

1
ssh a maintenant l'option -W, qui le fait automatiquement sans 'nc', mais je me demande pourquoi il n'y a pas de scp -W
kubanczyk

3
Au cas où je ne serais pas le seul, cela ne serait pas évident: si le nom d'utilisateur activé nearest différent de celui indiqué distant, l'utilisateur proche s'en va ProxyCommand ssh nearuser@near...et l'utilisateur distant se connecte sur une User distantuserligne distincte .
Mu Mind

Il suffit de taper ssh multi hope et d'appuyer sur Google. Je me sens chanceux
chandank

19

Avec les versions plus récentes de ssh sur le serveur près de la machine (B), les opérations suivantes fonctionneront sans netcat:

Host distant
    ProxyCommand ssh near -W distant:22

Toutefois, AllowTcpForwarding doit être défini sur yes (valeur par défaut) sur la machine proche (B).

edit: nécessite OpenSSH 5.4+ sur B


fonctionne comme un charme :)
gongzhitaao

1
Et à partir d’OpenSSH 7.4p1 au minimum, il existe une commande "ProxyJump" dans laquelle il suffit de répertorier chaque utilisateur @ hôte: port séparé par une virgule. Agréable!
hmijail

ProxyJump est bien, mais cela n'a pas pris User et IdentityFile du fichier de configuration. ProxyCommand -W fait cela et fonctionne également avec scp.
rickfoosusa

18

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

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

Ensuite, vous pouvez ssh au 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 le cas correct de p avec scp et ssh


5

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 copie des fichiers d'un remotePathsur server2directement dans votre machine à localPath. En interne, la requête scp est proxy 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 (fichier à télécharger):

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>

3

Si vous voulez être vraiment méchant, vous pouvez enchaîner ssh et tar, par exemple 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; Regardez le -Dcommutateur dans la page de manuel et transférez simplement un port sur le port ssh de l'autre serveur.


2

Vous pouvez également le faire à l’inverse et peut-être plus facilement.

Supposons qu'une session ssh soit ouverte avec la machine à laquelle vous voulez envoyer le fichier. Ce PC le plus éloigné, nous l'appellerons hop2. Votre hôte "proxy" sera hop1. Le PC qui est l’origine du fichier, nous appellerons cette origine.

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 que vous avez intercepté lors de la construction du 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 et à l’origine. Par coïncidence, les ports 5555 et 6666 sont maintenant ouverts sur leur origine, ce qui redirige vers le port 22 de hop2. Dans cette session, les deux suivants sont des itinéraires scp valides vers hop2:

Sur 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 une chaîne de plus de deux sauts.


1

Essayez d’adapter l’exemple suivant openssh config pour une configuration pouvant être utilisée par 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 de passerelle / passerelle "bastion-uat". Vous voudrez probablement aussi ajouter ForwardAgent yessi vous utilisez une clé pour vous connecter.


Ne pas utiliser ForwardAgent yespour cela. Le transfert d'agent n'est pas nécessaire dans ce cas car aucun client ssh ne s'exécutera sur le bastion et le transfert d'un agent lorsqu'il n'en a pas besoin va simplement réduire la sécurité. Et je pense qu'il sshmanque à votre commande. Si sshvous n'avez pas besoin d' une version récente nc, vous pouvez taper à la ssh -W %h:%p bastion-uatplace.
Kasperd

@kasperd Édité pour inclure ssh. Re ForwardAgent; un client ssh sera exécuté afin d'exécuter la commande nc elle-même. Peut-être que vous faites allusion à la coquille?
Benjamin Goodacre

1

Ce n'est pas scp (ce que l'OP a demandé), mais je l'ai trouvé super simple à utiliser rsyncpour copier d'un local à un autre 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 de configuration pour mes besoins changeants. Comme l'indique l'auteur du lien ci-dessus, le fichier de destination précédant le signe deux-points (:) est important pour indiquer que le chemin spécifié est sur le serveur de destination. De plus, en utilisant rsync, vous avez les options de comparaison de date, de synchronisation de dossier, etc. J'espère que cela aidera quelqu'un!


-2

scp -o 'ProxyJump jumpboxname' un nom de fichier.txt finaldestinationhost: / tmp /.


3
Ne jetez pas simplement un peu de code inexpliqué ici. Il y a beaucoup de bonnes réponses à cette question et vous devez ajouter de la valeur aux réponses existantes - ce n'est pas le cas.
Sven
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.