Wie leitet man eine TCP-Verbindung (speziell MyQSL-Client -> Server) über einen SSH-Tunnel mit mehreren Sprüngen weiter?

694
Nathan Lutterman

Ich möchte eine Verbindung zu einer entfernten MySQL-Datenbank herstellen. Diese Datenbank befindet sich in einem privaten Subnetz in einem anderen Netzwerk. Daher kann ich keine Verbindung zu ihr herstellen. Der Remote-SSH-Zugriff ist auf dem MySQL-Server ebenfalls vollständig deaktiviert.

Mein aktueller Prozess ist folgender:

Ich öffne einen SSH-Tunnel über den öffentlich zugänglichen Server HOST_1. Von diesem Tunnel aus eröffne ich eine SSH-Verbindung zu einem Server (HOST_2), der sich im selben Subnetz wie der MySQL-Server (MYSQL_HOST) befindet. Mit der SSH-Sitzung, die ich zu diesem Zeitpunkt geöffnet habe (auf HOST_2), verwende ich den MySQL-Client, um eine Verbindung zu MYSQL_HOST zu öffnen.

Hier ist ein Super-Duper-Diagramm, was aktuell gemacht wird:

diagram of current connection

Was ich will, tun, ist mein lokalen Computer des MySQL - Client verwenden, um 127.0.0.1:3306 und haben die Verbindung alle den Weg von Host_1 durch getunnelt zu verbinden, zu Host_2, und dann mysql_host, als ob ich den MySQL - Server mit wurden Laufen von 127.0.0.1 an erster Stelle.

Auch hier kann ich keinen SSH-Tunnel von HOST_2 in den MYSQL_HOST öffnen, also kein Tunneling von dort aus. Ich muss herausfinden, wie ich die MySQL-Clientverbindung über den SSH-Tunnel an HOST_2 weiterleiten kann, und dann HOST_2 die MySQL-Clientverbindung an MYSQL_HOST weiterleiten lassen.

Ich dachte, ich könnte das vielleicht gebrauchen rediroder ncerreichen. Ich bin mir jedoch nicht sicher, wie.

Ich habe einige Fragen gelesen, verstehe aber nicht alles genug, um die Informationen zusammenzustellen, um die Antwort zu erhalten, die ich suche:

  1. Ein SSH-Tunnel über mehrere Hops
  2. UDP-Verkehr durch den SSH-Tunnel
  3. https://unix.stackexchange.com/questions/267090/reroute-mysql-connection-through-external-machine

Ich weiß, dass es wieder Informationen auf dieser Seite gibt, die mir helfen würden, aber ich weiß nicht, wie ich sie verwenden soll: http://sshmenu.sourceforge.net/articles/transparent-mulithop.html

Vielen Dank!

2

2 Antworten auf die Frage

1
Omnipresence

Diese Antwort setzt voraus, dass sshd so konfiguriert ist, dass Portweiterleitung für HOST_1 und HOST_2 möglich ist.

Sie haben bereits das meiste gefunden, was Sie brauchen (Option zwei in der Antwort von Mika Fischer in Ihrem ersten Link).

Tunnel von localhost nach host1 und von host1 nach host2:

ssh -L 9999:localhost:9999 host1 ssh -L 9999:localhost:1234 -N host2 Dadurch wird ein Tunnel von localhost nach host1 und ein weiterer Tunnel von host1 nach host2 geöffnet. Der Port 9999 bis host2: 1234 kann jedoch von jedermann auf host1 verwendet werden. Dies kann ein Problem sein oder nicht.

Die Idee ist, die Portweiterleitung aneinander zu reihen (dh Sie leiten einen lokalen Port an einen Remote-Port weiter, den Sie dann an einen noch weiter entfernten Port weiterleiten).

Für Ihr Beispiel wäre der Befehl

ssh -tt -L 3306:localhost:XXXX [user@]HOST_1 ssh -L XXXX:MYSQL_HOST:3306 [user@]HOST_2 wobei XXXX ein beliebiger Port über 1024 ist, der nicht bereits verwendet wird (verwenden Sie dieselbe Nummer, um beide Instanzen zu ersetzen)

Nach der Ausführung werden Sie zweimal nach dem Kennwort gefragt (einmal für HOST_1 und einmal für HOST_2), es sei denn, Sie verwenden SSH-Schlüssel für die kennwortlose Anmeldung. Der Tunnel funktioniert so lange, wie Sie über HOST_1 mit HOST_2 verbunden sind.

Hier ist die Aufschlüsselung:

ssh ist der lokale SSH-Client, den Sie ausführen

-tterzwingt die Zuweisung von Pseudo-tty (siehe Pseudo-Terminal wird nicht zugewiesen, da stdin kein Terminal ist, warum dies erforderlich ist)

-L 3306:localhost:XXXX [user@]HOST_1sagt Ihrem lokalen SSH-Client, 3306 auf Ihrem lokalen System an Port XXXX auf "localhost" auf der anderen Seite der SSH-Verbindung weiterzuleiten. Sie müssen nur angeben, user@ob sich der Benutzer auf Ihrem lokalen Computer von dem Benutzer unterscheidet, mit dem Sie sich unter HOST_1 verbinden. Im Allgemeinen können Sie einen anderen lokalen Port als 3306 angeben, aber dann würden Sie Ihren MySQL-Client auf 127.0.0.1: [Ihren gewählten Port] verweisen.

ssh(der zweite) Wie Sie vielleicht wissen, hat ssh die Möglichkeit, einen einzelnen Befehl auszuführen, anstatt eine Shell zu starten. Sie verwenden dies, um eine weitere SSH-Sitzung auf HOST_1 auszuführen, die den nächsten Link in der Portweiterleitungskette erstellt.

-L XXXX:MYSQL_HOST:3306 [user@]HOST_2Da diese ssh-Sitzung auf HOST_1 ausgeführt wird, leitet XXXX auf der lokalen Seite (HOST_1) (die von 3306 auf Ihrem Client weitergeleitet wird) an Port 3306 auf MYSQL_HOST auf der fernen Seite (HOST_2) weiter. Sie müssen nur angeben, user@ob sich der Benutzer von HOST_1 von dem Benutzer unterscheidet, zu dem Sie sich mit HOST_2 verbinden.

Wenn zusätzliche Hops erforderlich sind, fügen Sie Instanzen ssh -L XXXX:localhost:XXXX hostXfür jeden Hop in der Mitte hinzu, sofern auf jedem Server im Pfad ein verfügbarer Port vorhanden ist.

Dies ist eine großartige Antwort. Vielen Dank, dass Sie sich die Zeit genommen haben, die Dinge so detailliert zu erklären. Ich habe es noch nicht getestet, da ich keine Gelegenheit hatte. Ich bezeichne es als die Antwort, da hier genug Informationen vorhanden sind, um es herauszufinden. Danke noch einmal!! Nathan Lutterman vor 6 Jahren 0
1
Gordon Davisson

Da Sie die SSH-Verbindung über HOST_1 zu HOST_2 führen, können Sie dies nur mit einem -LPort for Forward tun :

ssh -A -o 'ProxyCommand = ssh -q Benutzer @ HOST_1 nc% h% p' Benutzer @ HOST_2 -L 3306: MYSQL_HOST: 3306

Dies tut im Wesentlichen das, was Sie jetzt tun: Öffnet eine SSH-Verbindung zu HOST_2, die über eine SSH-Verbindung zu HOST_1 weitergeleitet wird, und leitet dann Verbindungen von 3306 auf dem lokalen Host über diese an MYSQL_HOST: 3306 weiter. Beachten Sie, dass MYSQL_HOST die Verbindung von HOST_2 sehen wird, da hier der Tunnel verlassen und wieder eine normale TCP-Verbindung wird.

Übrigens, wenn Sie OpenSSH 7.3 oder höher auf dem lokalen Computer und auf HOST_1 installiert haben, können Sie das SSH-Proxying mit der neuen -JOption (oder der ProxyJumpDirektive in Ihrer ssh-Konfigurationsdatei) vereinfachen :

ssh -A -J Benutzer @ HOST_1 Benutzer @ HOST_2 -L 3306: MYSQL_HOST: 3306

Dies erleichtert auch das Durchlaufen mehrerer SSH-Proxys:

ssh -A -J Benutzer @ HOST_1, Benutzer @ HOST_3, Benutzer @ HOST_3 Benutzer @ HOST_4 -L 3306: MYSQL_HOST: 3306