Puis-je diriger stdout sur un serveur vers stdin sur un autre serveur?


74

stdoutsur un serveur CentOS doit être connecté à stdinun autre serveur CentOS. Est-ce possible?

Mise à jour

ScottPack, MikeyB et jofel ont tous des réponses valables. J'ai attribué la réponse à Scott car, même si ma question ne mentionnait pas la sécurité comme une exigence, il est toujours agréable d'être en sécurité. Cependant, les suggestions des deux autres boursiers fonctionneront également.


1
Il convient de noter que le (seul) avantage majeur de l'approche non-SSH est la vitesse de traitement. Si vous êtes sur un réseau rapide et que la sécurité n'est pas nécessaire, cela peut valoir le désagrément supplémentaire de taper deux commandes dans deux fenêtres.
Random832

Réponses:


94

C'est un oui sans reproche.

Lorsque l’on sshexécute une commande sur un serveur distant, il effectue une sorte de redirection interne sophistiquée des entrées / sorties. En fait, j'estime qu'il s'agit d'une des fonctionnalités légèrement plus agréables d'OpenSSH. Plus précisément, si vous utilisez sshpour exécuter une commande arbitraire sur un système distant, puis ssh la carte STDINet STDOUTà celle de la commande en cours d' exécution.

Supposons, à titre d'exemple, que vous souhaitiez créer une archive tar de sauvegarde, mais que vous ne vouliez pas ou ne puissiez pas la stocker localement. Jetons un coup d'oeil à cette syntaxe:

$ tar -cf - /path/to/backup/dir | ssh remotehost "cat - > backupfile.tar"

Nous créons une archive et l'écrivons dans STDOUTdes choses normales. Puisque nous utilisons ssh pour exécuter une commande à distance, STDIN est mappé sur le STDINde cat. Que nous redirigeons ensuite vers un fichier.


11
Ce n'est pas une sorte de "redirection d'entrée / sortie interne sophistiquée" - juste le truc ordinaire, ennuyeux. SSH lit à partir de STDIN, comme n'importe quel autre outil, et le transmet au processus distant. :)
Daniel Pittman

7
@DanielPittman: Mais c'est tellement plus amusant de l'appeler une "poubelle interne".
Scott Pack

7
De même, netcatles deux extrémités constituent un excellent canal de communication simple et facile. tar cf - /path/to/dir | nc 1.2.3.4 5000sur un serveur, nc -l -p 5000 > backupfile.tarsur l'autre.
MikeyB

1
@ MikeyB: Bon point. Netcat est un protocole en texte clair, soyez donc prudent avec les données sensibles. J'ai tendance à utiliser netcat pour des tâches plus spécifiques, telles que l'acquisition de lecteurs de réseau (ala dd) sur un réseau local et le balayage de ports.
Scott Pack

2
@MikeyB: Vous qui faites quoi avec votre siège volant et vos sièges pantalons!
Scott Pack

28

Un moyen pratique de canaliser les données entre les hôtes lorsque vous n'avez pas à vous soucier de la sécurité sur le fil consiste à utiliser netcatles deux extrémités de la connexion.

Cela vous permet également de les configurer de manière asynchrone:

Sur le "récepteur" (en réalité, vous aurez une communication bidirectionnelle, mais il est plus facile de penser comme ça), lancez:

nc -l -p 5000 > /path/to/backupfile.tar

Et sur "l'expéditeur", lancez:

tar cf - /path/to/dir | nc 1.2.3.4 5000

Très bon à savoir. Cela est utile si la connexion physique est sécurisée, comme un réseau de secours, ou si la connexion est déjà sous tunnel.
Wesley

Ou si les données sont quelque chose qui est public de toute façon.
Samuel Edwin Ward

1
+1 netcat est un outil précieux, surtout quand aucun serveur ssh n'est en cours d'exécution.
Kwarrick

21

Un outil très puissant pour créer des connexions uni- et bidirectionnelles est socat. Pour un bref aperçu des possibilités, consultez les exemples de la page de manuel .

Il remplace netcatcomplètement les outils similaires et prend en charge les connexions cryptées SSL. Pour les débutants, ce n’est peut-être pas assez simple, mais il est au moins bon de savoir qu’il existe.


1
@WesleyDavid: Pour votre "Mise à jour": Juste pour compléter, j'ai ajouté à ma réponse que socat prend en charge SSL, le cryptage est donc possible avec socat. Cependant, ssh est dans la plupart des cas la solution la meilleure et la plus facile. J'aurais donc également choisi la réponse de ScottPack.
Jofel

5

TL; DR

Les choses deviennent un peu plus compliquées lorsque vous avez un serveur bastion à utiliser.

  1. Vous pouvez passer sshcomme commande pour sshaimer ainsi:

    • cat local_script.sh | ssh -A usera@bastion ssh -A userb@privateserver "cat > remote_copy_of_local_script.sh; bash remote_copy_of_local_script.sh"
  2. Attention aux pseudo-terminaux


Notez que le point essentiel ici est que ssh, comme la plupart des outils, traite stdoutet stdincorrige par défaut.

Cependant, lorsque vous commencez à voir des options telles que Disable pseudo-terminal allocation.et Force pseudo-terminal allocation.vous devrez peut-être faire quelques essais et erreurs. Mais, en règle générale, vous ne voulez pas modifier le ttycomportement sauf si vous essayez de réparer les fichiers illisibles / binaires dans un émulateur de terminal (dans lequel un type humain est entré).

Par exemple, j’ai tendance à utiliser -Atpour que le ssh-agent de mon poste de travail soit transféré et pour que l’exécution de tmux à distance ne soit pas synonyme de binaire (comme c’est le cas ssh -At bastion.internal tmux -L bruno attach). Et pour docker aussi (comme ça sudo docker exec -it jenkins bash).

Cependant, ces deux -tindicateurs rendent difficile la traçabilité de la corruption des données lorsque j'essaie de faire quelque chose comme ceci:

# copy /etc/init from jenkins to /tmp/init in testjenkins running as a container
ssh -A bastion.internal \
ssh -A jenkins.internal \
sudo tar cf - -C /etc init | \
sudo docker exec -i testjenkins \
bash -c 'tar xvf - -C /tmp'

# note trailing slashes to make this oneliner more readable.

2

Essayez de mettre votre clé publique ssh dans un autre hôte par une seule commande

ssh root@example.com 'cat >> .ssh/authorized_keys' < .ssh/id_rsa.pub

2

Je trouve que c'est le plus simple. Après avoir configuré aucun protocole de transfert de mot de passe entre serveurs pour l'utilisateur pour lequel vous exécutez la commande, procédez comme suit:

Non compressé

tar cf - . | ssh servername "cd /path-to-dir && tar xf -"

Compression à la volée

tar czf - . | ssh servername "cd /path-to-dir && tar xzf -"

Utiliser la compression sur le fichier tar est une très mauvaise idée si votre sshest déjà configuré pour la compression.
Anthon

@ Anthony Pourquoi si mal, et comment vérifier si la compression SSH est déjà activée?
Tom Hale

1
@TomHale En fonction de la vitesse de vos systèmes, cela pourrait ralentir le fonctionnement général, car la deuxième compression prend du temps, mais il est peu probable que des octets supplémentaires soient supprimés. Compressionpeut être défini dans l’un des fichiers de configuration, une vérification rapide consiste à vérifier si ssh -v localhost exit 2>&1 | fgrep -i compressune sortie est donnée (autant que je sache, il n’ya pas d’option permettant de vider la configuration telle que ssh l’a lue).
Anthon

tara un -C pathdrapeau qui fonctionne pour les commandes cet x. Vous n'êtes pas obligé de mettre une cdcommande séparée là-bas. (Mais il est bon de noter que vous pouvez exécuter plus d'une commande.)
Bruno Bronosky

@Bruno, -Cest une extension GNU (bien que maintenant aussi supporté par bsdtar et schily tar)
Stéphane Chazelas
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.