Kann ich stdout auf einem Server an stdin auf einem anderen Server weiterleiten?


74

stdoutauf einem CentOS-Server muss stdinauf einen anderen CentOS-Server umgeleitet werden. Ist das möglich?

Aktualisieren

ScottPack, MikeyB und Jofel haben alle gültige Antworten. Ich habe Scott die Antwort gegeben, weil es immer schön ist, in Sicherheit zu sein, auch wenn meine Frage keine Sicherheitsanforderung enthält. Die Vorschläge der beiden anderen Fellows werden jedoch auch funktionieren.


1
Es ist erwähnenswert, dass der (einzige) Hauptvorteil des Nicht-SSH-Ansatzes die Durchsatzgeschwindigkeit ist. Wenn Sie sich in einem schnellen Netzwerk befinden und keine Sicherheit erforderlich ist, lohnt es sich möglicherweise, zwei Befehle in zwei Fenster einzugeben.
Random832

Antworten:


94

Das ist ein unverfrorenes Ja.

Wenn sshein Befehl auf einem Remote-Server ausgeführt wird, führt er eine ausgefallene interne Eingabe- / Ausgabeumleitung durch. Tatsächlich finde ich dies eine der subtil schöneren Funktionen von OpenSSH. Wenn Sie Insbesondere verwenden ssheinen beliebigen Befehl auf einem entfernten System auszuführen, dann ssh Karte STDINund STDOUTderjenigen der Befehl ausgeführt wird.

Angenommen, Sie möchten ein Backup-Tarball erstellen, möchten oder können es jedoch nicht lokal speichern. Lassen Sie uns einen Blick auf diese Syntax werfen:

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

Wir erstellen einen Tarball und schreiben ihn an STDOUTnormale Dinge. Da wir mit ssh einen Remote-Befehl ausführen, wird STDIN dem STDINvon zugeordnet cat. Welche wir dann in eine Datei umleiten.


11
Das ist keine "ausgefallene interne Eingabe- / Ausgabe-Umleitung" - nur das schlichte, langweilige, normale Zeug. ssh liest wie jedes andere Tool aus STDIN und übergibt es an den Remote-Prozess. :)
Daniel Pittman

7
@DanielPittman: Aber es macht einfach so viel mehr Spaß , es als "ausgefallenen internen" Müll zu bezeichnen.
Scott Pack

7
In ähnlicher Weise ergibt sich netcatan beiden Enden ein sehr einfacher und leichter Kommunikationskanal. tar cf - /path/to/dir | nc 1.2.3.4 5000auf einem Server nc -l -p 5000 > backupfile.tarauf dem anderen.
MikeyB

1
@ MikeyB: Guter Punkt. Netcat ist ein Klartextprotokoll. Gehen Sie also vorsichtig mit vertraulichen Daten um. Ich benutze Netcat eher für spezifischere Dinge wie die Erfassung von Netzwerklaufwerken (ala dd) über ein lokales Netzwerk und die Überprüfung von Ports.
Scott Pack

2
@MikeyB: Ihr Leute was mit eurem Fliegen und euren Hosensitzen!
Scott Pack

28

Eine bequeme Möglichkeit, Daten zwischen Hosts weiterzuleiten, wenn Sie sich keine Sorgen um die Sicherheit über das Kabel machen müssen, besteht darin, netcatdie Verbindung an beiden Enden herzustellen.

Auf diese Weise können Sie sie auch asynchron einrichten:

Führen Sie auf dem "Empfänger" (in Wirklichkeit haben Sie bidirektionale Kommunikation, aber es ist einfacher, sich das so vorzustellen) Folgendes aus:

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

Führen Sie auf dem "Absender" Folgendes aus:

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

Sehr gut zu wissen. Dies ist gut, wenn die physische Verbindung als vertrauenswürdig eingestuft wird, beispielsweise als Backup-Netzwerk, oder wenn die Verbindung bereits getunnelt ist.
Wesley

Oder ob die Daten sowieso öffentlich sind.
Samuel Edwin Ward

1
+1 Netcat ist ein unschätzbares Tool, insbesondere wenn kein SSH-Server ausgeführt wird.
kwarrick

21

Ein sehr leistungsfähiges Tool zum Erstellen von uni- und bidirektionalen Verbindungen ist socat. Um einen kurzen Überblick über die Möglichkeiten zu erhalten, sehen Sie sich die Beispiele in der Manpage an .

Es ersetzt netcatund ähnliche Tools vollständig und unterstützt SSL-verschlüsselte Verbindungen. Für Anfänger mag es nicht einfach genug sein, aber es ist zumindest gut zu wissen, dass es existiert.


1
@WesleyDavid: Zu Ihrem "Update": Der Vollständigkeit halber habe ich meiner Antwort hinzugefügt, dass socat SSL-Unterstützung bietet, sodass Verschlüsselung auch mit socat möglich ist. In den meisten Fällen ist ssh jedoch die bessere und einfachere Lösung, daher hätte ich auch die Antwort von ScottPack gewählt.
Jofel

5

TL; DR

Die Dinge werden nur etwas komplizierter, wenn Sie einen Bastion-Server haben , der verwendet werden muss.

  1. Sie können sshals Befehl übergeben, um sshso zu mögen:

    • 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. Vorsicht vor Pseudo-Terminals


Beachten Sie, dass der wichtigste Punkt hier ist, dass ssh, wie bei den meisten Werkzeugen, standardmäßig nur behandelt stdoutund stdinkorrigiert wird.

Wenn Sie jedoch beginnen Option wie um zu sehen , Disable pseudo-terminal allocation.und Force pseudo-terminal allocation.man kann einen wenig Versuch und Irrtum tun müssen. In der Regel möchten Sie das ttyVerhalten jedoch nicht ändern , es sei denn, Sie versuchen, verstümmelten / binären Müll in einem Terminal-Emulator zu beheben (was ein Mensch eintippt).

Zum Beispiel neige ich dazu, -Atden ssh-agent meiner Workstation weiterzuleiten und tmux aus der Ferne auszuführen, ohne Binärdateien zu blockieren (wie dies der Fall ist ssh -At bastion.internal tmux -L bruno attach). Und auch für Hafenarbeiter (wie so sudo docker exec -it jenkins bash).

Diese beiden -tFlags führen jedoch dazu, dass es schwierig ist, Datenbeschädigungen aufzuspüren, wenn ich so etwas wie Folgendes versuche:

# 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

Versuchen Sie, Ihren öffentlichen ssh-Schlüssel mit nur einem Befehl auf einem anderen Host zu speichern

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

2

Ich finde dies am einfachsten, nachdem für den Benutzer kein Passwort-Handshake zwischen den Servern eingerichtet wurde, als den Sie den Befehl ausführen:

Unkomprimiert

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

Komprimierung im laufenden Betrieb

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

Die Verwendung der Komprimierung für die TAR-Datei ist eine sehr schlechte Idee, wenn Ihre sshbereits für die Komprimierung konfiguriert ist.
Anthon

@Anthon Warum so schlecht und wie würde man prüfen, ob die ssh-Komprimierung bereits aktiviert ist?
Tom Hale

1
@TomHale Abhängig von der Geschwindigkeit Ihres Systems kann dies den Gesamtvorgang verlangsamen, da die zweite Komprimierung Zeit in Anspruch nimmt, es jedoch unwahrscheinlich ist, dass zusätzliche Bytes verloren gehen. Compressionkönnte in einer der config-dateien gesetzt werden, eine schnelle überprüfung, ob ssh -v localhost exit 2>&1 | fgrep -i compressirgendwelche ausgaben vorliegen (afaik gibt es keine möglichkeit, die konfiguration zu sichern, wie ssh sie eingelesen hat).
Anthon

tarhat eine -C pathFlagge , die sowohl für die Werke cund xBefehle. Sie müssen dort keinen separaten cdBefehl eingeben. (Es ist jedoch zu beachten, dass Sie mehr als einen Befehl ausführen können.)
Bruno Bronosky

@Bruno, -Cist eine GNU-Erweiterung (obwohl sie jetzt auch von bsdtar und schily tar unterstützt wird)
Stéphane Chazelas
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.