Kopieren Sie Daten durch einen SSH-Tunnel über mehrere Hops

14

Wir haben zwei Hauptumgebungen in Frage:

Entwicklung und Qualitätssicherung

Jede Umgebung verfügt über zwei Server:

  • Sprungbox
  • Anwendungsserver

Um eine Verbindung zum Anwendungsserver herzustellen, müssen Sie zuerst eine Verbindung zur Jump-Box und dann eine SSH-Verbindung zum Anwendungsserver herstellen.

Es gibt ein paar Regeln, die von der Firewall unterstützt werden:

  • Sie MÜSSEN über die Jump-Box eine Verbindung zum Anwendungsserver herstellen
  • Der Anwendungsserver kann keine Verbindung zu einer der Jump-Boxen herstellen
  • Die Jump-Boxen befinden sich im selben Subnetz und können miteinander kommunizieren.

Unser Problem

Wir haben eine Menge Inhalt (670 GB) auf der DEVELOPMENT APPLICATION SERVER, und wir müssen dies auf die bekommen QA APPLICATION SERVER.

Das Kopieren dieser Daten in die Jump-Boxen ist keine Option, da ihnen der erforderliche Speicherplatz fehlt.

Ich habe einige Nachforschungen angestellt und festgestellt, dass wir möglicherweise eine Reihe von Tunneln über diese Server durchführen können, damit wir die Daten über die Tunnel direkt von einem App-Server auf den anderen übertragen können. Das Problem ist jedoch, dass wir vom Anwendungsserver keine Verbindung zur Jump-Box herstellen können.

Haben wir irgendwelche Optionen? Dies wird eine verzweifelte Situation, und Zeit ist von entscheidender Bedeutung. Wir haben keine Zeit, die Daten herunterzuladen und erneut hochzuladen. Das Kopieren über das Netzwerk auf den Servern geht schnell, da es sich um eine Gigabit-Verbindung handelt.

Barry Chapman
quelle
2
Sobald die Verbindung hergestellt ist, können Sie Folgendes kopieren: $ devel_host $ tar -cf - | ssh -t jumbox 'ssh app_serv "tar -xf -"' oder anders herum tar.
Alex_www
so können wir uns von der dev jump box zum dev app server verbinden, aber nicht umgekehrt. Wenn wir diese Verbindung hergestellt haben, können wir so oder so kopieren? Was ist der beste Weg, um diesen Inhalt auf den anderen App-Server zu verschieben, ohne ihn zuerst auf den Jump-Boxen zu speichern?
Barry Chapman
Genau, "Rohrleitungen" "Teer" ist die einfachste Lösung.
Alex_www

Antworten:

15

Der einfachste Weg ist es, es einfach über scp zu kopieren. Außerdem funktioniert diese Syntax im Gegensatz zu einigen anderen Vorschlägen.

Sie können diese Syntax zur Vereinfachung nicht übertreffen. Sie können rekursiv kopieren, rsyncen oder was immer Sie möchten, ohne die Mühe zu haben, potenziell komplexe Pipes in Betracht zu ziehen. Diese Syntax ist intuitiv klar, wird von den Sys-Admins, die Ihnen folgen, leichter unterstützt und macht keinen nutzlosen Gebrauch von cat .

scp -3 devappserver:/path/to/copy/from qaappserver:/path/to/copy/to

Von der scp-Manpage : -3Kopien zwischen zwei Remote-Hosts werden über den lokalen Host übertragen. Ohne diese Option werden die Daten direkt zwischen den beiden Remote-Hosts kopiert. Beachten Sie, dass diese Option die Fortschrittsanzeige deaktiviert.

Im folgenden Beispiel

  • Ihre Workstation heißt MacBook-Pro.
  • Dev Jump Box heißt devjumpserver
  • Dev Application Server heißt devapplicationserver
    • Ist in der LAN-DNS-Zone mit dem Namen .local
  • QA Jump Box heißt qajumpserver
  • QA Application Server heißt qaapplicationserver
    • Befindet sich in der LAN-DNZ-Zone mit dem Namen .local
  • Wir führen eine Testkopie einer 670 GB / etc / hosts-Datei durch ;-)
  • Es wird davon ausgegangen, dass Sie die SSH-Authentifizierung mit öffentlichem Schlüssel konfiguriert haben.



Hier ist eine ~ / .ssh / config-Datei, die den direkten Zugriff von Ihrer Workstation auf die Anwendungsserver über den entsprechenden Sprung (auch als Bastionserver bezeichnet) einrichtet.

MacBook-Pro: ~ barrychapman $ cat ~ / .ssh / config
Gastgeber *
  ServerAliveInterval 60
Host devapplicationsever
  Hostname devapplicationserver.local
  ProxyCommand ssh -i ~ / .ssh / id_rsa [email protected] -W% ​​h:% p
  Benutzer barrychapman
Host qaapplicationserver
  Hostname qaapplicationserver.local
  ProxyCommand ssh -i ~ / .ssh / id_rsa [email protected] -W% ​​h:% p
  Benutzer barrychapman

MacBook-Pro: ~ barrychapman $



Beim Testen auf das Vorhandensein einer Datei auf dem Zielserver wird diese nicht angezeigt.

MacBook-Pro: ~ barrychapman $ ssh qaapplicationserver ls / tmp / hosts
ls: kann nicht auf / tmp / hosts zugreifen: Keine solche Datei oder kein solches Verzeichnis
Durch Signal 1 getötet.
MacBook-Pro: ~ barrychapman $



Jetzt kopieren wir eine Datei vom Dev Application Server über Ihre Workstation in die QA Application.

MacBook-Pro: ~ barrychapman $ scp -3 devapplicationserver: / etc / hosts qaapplicationserver: / tmp /
Durch Signal 1 getötet.
Durch Signal 1 getötet.
MacBook-Pro: ~ barrychapman $



Überprüfen wir nun, ob die kopierte Datei auf dem QA Application Server vorhanden ist. Diesmal wird es da sein.

MacBook-Pro: ~ barrychapman $ ssh qaapplicationserver ls / tmp / hosts
/ tmp / hosts
Durch Signal 1 getötet.
MacBook-Pro: ~ barrychapman $ 

Hinweis

Wenn Sie eine ProxyCommand-Verbindung beenden, wird die Warnmeldung "Abgebrochen durch Signal 1" angezeigt. Dies bedeutet, dass SSH die ProxyCommand-Verbindung abbricht und kein Grund zur Beunruhigung besteht. Sie können es entfernen, indem Sie es LogLevel Quietzu Ihrer Zeilengruppe "bastion host config" hinzufügen .

ca.
quelle
Prost, das hat unser Problem gelöst. Fröhliche Weihnachten!
Barry Chapman
Was meinst du mit "bastion host config stanza"? @BraveNewCurrency?
Andrew Wolfe
Ich betrachte jede "Host" -Zeile und die Configs darunter als Zeilengruppe (wie in Gedichten). Wenn Sie "LogLevel Quiet" unter Ihrer Bastion "Host" -Zeile hinzufügen, gilt dies nur für diesen Host.
BraveNewCurrency
8

PIPES!

Wenn das Internet eine Reihe von Rohren ist , ist Unix eine Reihe von Rohren - so etwas wie:

cat ginormous-file | ssh user@host1 "cat | ssh user@host2 \"cat >out\" "

sollte arbeiten.

Wenn Sie mehr Hosts überqueren müssen, fügen Sie nach Bedarf mehr Pipes (und mehr geschachtelte Ebenen mit \Anführungszeichen) hinzu. (Beachten Sie jedoch, dass es wahrscheinlich an der Zeit ist, eine Niederlage zuzugeben und ein richtiges VPN einzurichten , wenn die Pipeline / Flucht so komplex wird, dass Sie ein Diagramm zeichnen oder auf Ihre Finger zählen müssen , um zu bestimmen, wie oft Sie Fluchten verdoppeln müssen !)

voretaq7
quelle
1
Wie Alex_www in seinem Kommentar betonte, wenn Sie die Zwischendatei für nichts benötigen, können Sie auch einfach die Ausgabe von tararound weiterleiten . (Auch in Sie nicht brauchen , die catin den Zwischenstufen der Pipeline - sshglücklich ist stdin zu essen und es Relais Das. catMacht mich besser zu fühlen und ist ein Platzhalter für andere nützliche Befehle , die Sie verwenden möchten , könnten, wie tee.)
voretaq7
Ich denke, das Problem des OP ist, dass es keine Maschine gibt, die sowohl die Daten hat als auch die Verbindungen herstellen kann, und es gibt auch keine Maschine, die alles und jeden sehen kann (um als Anschluss für alle Leitungen zu fungieren).
MadHatter
1
@MadHatter Wenn dies der Fall ist, würde eine Kombination unserer beiden Antworten funktionieren (stellen Sie eine Verbindung zum Dev-Server her, leiten Sie einen Port zurück zum SSH-Port des Jump-Servers und führen Sie die SSH-Pipeline über diesen Port aus). Dies macht die Lösung natürlich immer widerlicher und bringt die Leute dazu, vor Ihrem Büro mit großen Schildern zu protestieren VPN! NOW!...
voretaq7
Warum ja. Ja, das würden sie. Hoffnungsvoll!
MadHatter
Bedeutet dies, dass der Zwischenserver (in diesem Fall user@host1) irgendwann über den vollen cat ginormous-fileSpeicherplatz verfügt? Oder werden die Daten einfach direkt an gesendet user@host2? Oder wird es irgendwie gestreamt? Wie ist das tarrelevant? Ich denke, es ist relevant für die vorletzte Frage, die ich gestellt habe. Keine dieser Fragen ist übrigens rhetorisch ...
hello_there_andy
1

Wenn ich das richtig verstehe, haben Sie zwei Jump-Server (jump-qa und jump-dev), die zwei App-Server (app-qa und app-dev) schützen. Die Jump-Server können sich gegenseitig austauschen. Keine andere Box als der entsprechende Jump-Server kann zum entsprechenden App-Server sshen. Die App-Server können zu niemandem ssh. Eine Datei soll von app-dev nach app-qa übertragen werden. Auf beiden Jump-Servern fehlt der Platz für eine Zwischenkopie der Daten.

Sie können dies mit SSH-Tunneling lösen. Wir stellen eine Verbindung zu einem Remote-App-Server her und führen einen Remote-Tunnel, der eine Verbindung zu einem nicht verwendeten Port auf dem Jump-Server herstellt. Wir richten eine zweite Verbindung von einem Jump-Server zum anderen Jump-Server ein und führen einen Tunnel, der das baumelnde Ende des remote weitergeleiteten Ports von Tunnel eins aufnimmt und an den SSH-Port des anderen App-Servers weiterleitet.

Richten Sie die Tunnel ein (jeder dieser Befehle muss in einem separaten Fenster ausgeführt werden jump-qa):

jump-qa% ssh app-qa -R 2345:localhost:2346
jump-qa% ssh jump-dev -L 2346:app-dev:22

Sie sollten jetzt feststellen, dass Sie auf app-qa telnet localhost 2345das ssh-Banner von app-dev ausführen und abrufen können. Anschließend können Sie die Datendatei kopieren:

app-qa% scp -P 2345 localhost:/path/on/app-dev/data.dat data.dat
MadHatter
quelle
Es gibt zwei Jumpboxen - eine vor dem QA-App-Server und eine vor dem DEV-App-Server. Die Sprungkästen können miteinander kommunizieren
Barry Chapman
Hat der Kunde Platz für eine Zwischenkopie?
MadHatter
Nein, es ist nicht genug Platz
Barry Chapman
Wenn Sie Client sagen, auf welchen Server beziehen Sie sich?
Barry Chapman
Ich hatte falsch verstanden. Mein gegenwärtiges Verständnis ist, dass es keinen Kunden gibt; Es gibt zwei Jump-Server und zwei App-Server.
MadHatter