Ich habe HTTP-Reverse-Proxys in unserer Entwicklungsumgebung sehr gern und fand den DNS-basierten Reverse-Proxy für virtuelle Hosts sehr nützlich. Wenn nur ein Port (und der Standardport) in der Firewall geöffnet ist, erleichtert dies die Verwaltung erheblich.
Ich würde gerne etwas Ähnliches finden, um SSH-Verbindungen herzustellen, habe aber nicht viel Glück gehabt. Ich würde es vorziehen, nicht einfach SSH-Tunneling zu verwenden, da dies andere Portbereiche als den Standard erfordert. Gibt es irgendetwas, das das kann?
Könnte HAProxy dies tun?
ssh
reverse-proxy
Ahanson
quelle
quelle
Antworten:
Ich glaube nicht, dass namenbasiertes SSH möglich sein wird, wenn man bedenkt, wie das Protokoll funktioniert.
Hier sind ein paar alternativen.
Sie können den Host, der für Port 22 antwortet, als Gateway einrichten. Anschließend können Sie den SSH-Server so konfigurieren, dass Anforderungen basierend auf dem Schlüssel an das Innere weitergeleitet werden. SSH Gateway Beispiel mit Schlüsseln
Sie können Ihren Client so einstellen, dass er diesen Host als Proxy verwendet. Das heißt, es wird ssh an den Gateway-Host gesendet und dieser Host verwendet, um eine Verbindung zum internen Host herzustellen. SSH-Proxy mit Client- Konfiguration .
Sie können auch einen einfachen HTTP-Proxy am Rand einrichten. Verwenden Sie dies dann, um eingehende Verbindungen zuzulassen. SSH über HTTP-Proxy .
Bei alledem ist es natürlich sehr wichtig, dass Sie das Gateway ordnungsgemäß konfigurieren und sperren.
quelle
Ich habe in den letzten 16 Monaten immer wieder nach einer Lösung für dieses Problem gesucht. Aber jedes Mal, wenn ich nachschaue, scheint es unmöglich zu sein, dies mit dem SSH-Protokoll zu tun, das in relevanten RFCs spezifiziert und von größeren Implementierungen implementiert ist.
Wenn Sie jedoch bereit sind, einen leicht modifizierten SSH-Client zu verwenden, und wenn Sie bereit sind, Protokolle auf eine Weise zu verwenden, die nicht genau beabsichtigt war, als sie entworfen wurden, ist dies möglich. Mehr dazu weiter unten.
Warum ist es nicht möglich
Der Client sendet den Hostnamen nicht als Teil des SSH-Protokolls.
Möglicherweise wird der Hostname als Teil einer DNS-Suche gesendet, aber diese wird möglicherweise zwischengespeichert, und der Pfad vom Client über Resolver zu autorisierenden Servern führt möglicherweise nicht über den Proxy, und selbst wenn dies der Fall ist, gibt es keine zuverlässige Möglichkeit, bestimmte DNS-Suchen zuzuordnen bestimmte SSH-Clients.
Mit dem SSH-Protokoll selbst können Sie nichts Besonderes anfangen. Sie müssen einen Server auswählen, ohne das SSH-Versionsbanner vom Client gesehen zu haben. Sie müssen ein Banner an den Client senden, bevor etwas an den Proxy gesendet wird. Die Banner von den Servern können unterschiedlich sein, und Sie können nicht erraten, welches das richtige ist.
Auch wenn dieses Banner unverschlüsselt gesendet wird, können Sie es nicht ändern. Jedes Bit dieses Banners wird während des Verbindungsaufbaus überprüft, so dass Sie ein wenig später einen Verbindungsfehler verursachen würden.
Die Schlussfolgerung für mich ist ziemlich klar, man muss etwas auf der Client-Seite ändern, damit diese Konnektivität funktioniert.
Die meisten Problemumgehungen kapseln den SSH-Verkehr in einem anderen Protokoll. Man kann sich auch eine Ergänzung des SSH-Protokolls vorstellen, bei der das vom Client gesendete Versionsbanner den Hostnamen enthält. Dies kann mit vorhandenen Servern kompatibel bleiben, da ein Teil des Banners derzeit als Freiform-Identifikationsfeld angegeben ist. Obwohl Clients in der Regel auf das Versionsbanner vom Server warten, bevor sie ihr eigenes senden, gestattet das Protokoll dem Client, ihr Banner zu senden zuerst. Einige neuere Versionen des ssh-Clients (z. B. unter Ubuntu 14.04) senden das Banner, ohne auf das Server-Banner zu warten.
Ich kenne keinen Client, der Schritte unternommen hat, um den Hostnamen des Servers in dieses Banner aufzunehmen. Ich habe einen Patch an die OpenSSH-Mailingliste gesendet , um eine solche Funktion hinzuzufügen. Es wurde jedoch aufgrund des Wunsches abgelehnt, den Hostnamen niemandem preiszugeben, der den SSH-Verkehr untersucht. Da ein geheimer Hostname grundsätzlich nicht mit dem Betrieb eines namensbasierten Proxys kompatibel ist, sollten Sie nicht erwarten, bald eine offizielle SNI-Erweiterung für das SSH-Protokoll zu erhalten.
Eine echte Lösung
Die Lösung, die für mich am besten funktionierte, war eigentlich die Verwendung von IPv6.
Mit IPv6 kann jedem Server eine separate IP-Adresse zugewiesen werden, sodass das Gateway anhand der Ziel-IP-Adresse herausfinden kann, an welchen Server das Paket gesendet werden soll. Die SSH-Clients können manchmal in Netzwerken ausgeführt werden, in denen die einzige Möglichkeit zum Abrufen einer IPv6-Adresse die Verwendung von Teredo ist. Teredo ist als unzuverlässig bekannt, jedoch nur, wenn das native IPv6-Ende der Verbindung ein öffentliches Teredo-Relay verwendet. Man kann einfach ein Teredo-Relay auf das Gateway setzen, auf dem Sie den Proxy ausführen würden. Miredo kann in weniger als fünf Minuten als Relais installiert und konfiguriert werden.
Ein Workaround
Sie können einen Sprunghost / Bastionshost verwenden. Dieser Ansatz ist für Fälle gedacht, in denen Sie den SSH-Port der einzelnen Server nicht direkt dem öffentlichen Internet aussetzen möchten. Es hat den zusätzlichen Vorteil, dass die Anzahl der für SSH benötigten extern zugewandten IP-Adressen reduziert wird, weshalb es in diesem Szenario verwendet werden kann. Die Tatsache, dass es sich um eine Lösung handelt, die aus Sicherheitsgründen eine weitere Schutzschicht hinzufügen soll, hindert Sie nicht daran, sie zu verwenden, wenn Sie die zusätzliche Sicherheit nicht benötigen.
Ein schmutziger Hack, damit es funktioniert, wenn die eigentliche Lösung (IPv6) außerhalb Ihrer Reichweite liegt
Der Hack, den ich beschreiben möchte, sollte nur als das absolut letzte Mittel verwendet werden. Bevor Sie überhaupt über diesen Hack nachdenken, empfehle ich dringend, für jeden Server, den Sie über SSH extern erreichen möchten, eine IPv6-Adresse zu erhalten. Verwenden Sie IPv6 als primäre Methode für den Zugriff auf Ihre SSH-Server und verwenden Sie diesen Hack nur, wenn Sie einen SSH-Client über ein IPv4-Netzwerk ausführen müssen, auf dessen Bereitstellung Sie keinen Einfluss haben.
Die Idee ist, dass der Verkehr zwischen Client und Server ein einwandfrei gültiger SSH-Verkehr sein muss. Der Proxy muss jedoch nur genug über den Paketstrom wissen, um den Hostnamen zu identifizieren. Da SSH keine Möglichkeit zum Senden eines Hostnamens definiert, können Sie stattdessen andere Protokolle in Betracht ziehen, die eine solche Möglichkeit bieten.
HTTP und HTTPS ermöglichen es dem Client, einen Hostnamen zu senden, bevor der Server Daten gesendet hat. Die Frage ist nun, ob es möglich ist, einen Strom von Bytes aufzubauen, der gleichzeitig als SSH-Verkehr und als HTTP und HTTPS gültig ist. HTTPs ist so ziemlich ein Nichtstarter, aber HTTP ist möglich (für ausreichend liberale Definitionen von HTTP).
Sieht das für Sie nach SSH oder HTTP aus? Es ist SSH und vollständig RFC-konform (mit der Ausnahme, dass einige der Binärzeichen durch das SF-Rendering ein wenig entstellt wurden).
Die SSH-Versionszeichenfolge enthält ein Kommentarfeld, das oben den Wert hat
/ HTTP/1.1
. Nach dem Zeilenwechsel hat SSH einige binäre Paketdaten. Das erste Paket ist eineMSG_SSH_IGNORE
Nachricht, die vom Client gesendet und vom Server ignoriert wird. Die zu ignorierende Nutzlast ist:Wenn ein HTTP-Proxy ausreichend liberal ist, was er akzeptiert, wird dieselbe Folge von Bytes als aufgerufene HTTP-Methode interpretiert,
SSH-2.0-OpenSSH_6.6.1
und die Binärdaten am Anfang der Ignorierungsnachricht werden als HTTP-Headername interpretiert.Der Proxy würde weder die HTTP-Methode noch den ersten Header verstehen. Aber es könnte den
Host
Header verstehen , der alles ist, was es braucht, um das Backend zu finden.Damit dies funktioniert, muss der Proxy nach dem Prinzip entworfen werden, dass er nur genügend HTTP verstehen muss, um das Backend zu finden, und sobald das Backend gefunden wurde, leitet der Proxy einfach den Raw-Byte-Stream weiter und verlässt die reale Terminierung der vom Backend auszuführenden HTTP-Verbindung.
Es mag ein bisschen schwierig klingen, so viele Annahmen über den HTTP-Proxy zu machen. Wenn Sie jedoch bereit sind, eine neue Software zu installieren, die mit der Absicht entwickelt wurde, SSH zu unterstützen, dann klingen die Anforderungen für den HTTP-Proxy nicht allzu schlecht.
In meinem Fall funktionierte diese Methode auf einem bereits installierten Proxy ohne Änderungen an Code, Konfiguration oder anderem. Und dies war für einen Proxy, der nur mit HTTP und ohne SSH geschrieben wurde.
Proof-of-Concept- Client und Proxy . (Haftungsausschluss, dass es sich bei Proxy um einen von mir betriebenen Dienst handelt. Sie können den Link jederzeit ersetzen, sobald ein anderer Proxy bestätigt wurde, der diese Verwendung unterstützt.)
Vorsichtsmaßnahmen für diesen Hack
quelle
the gateway can use the destination IP address to find out which server to send the packet to
in der IPv6-Lösung erläutern, was Sie damit meinen ?-J
Befehlsoption für ssh . Sie können also Folgendes verwenden: ssh -J user1 @ front user2 @ targetIch glaube nicht, dass dies möglich wäre, zumindest nicht so, wie Sie es beschrieben haben, obwohl ich es lieben würde, wenn ich mich als falsch erweisen würde. Es scheint nicht, dass der Client den Hostnamen sendet, zu dem er eine Verbindung herstellen möchte (zumindest nicht im Klartext). Der erste Schritt der SSH-Verbindung scheint darin zu bestehen, die Verschlüsselung einzurichten.
Außerdem würden Sie Probleme mit der Überprüfung des Hostschlüssels haben. SSH-Clients überprüfen Schlüssel basierend auf einer IP-Adresse sowie einem Hostnamen. Sie hätten mehrere Hostnamen mit unterschiedlichen Schlüsseln, aber die gleiche IP, mit der Sie sich verbinden.
Eine mögliche Lösung wäre ein "Bastion" -Host, auf dem Clients auf diesen Rechner zugreifen, eine normale (oder auf Wunsch eingeschränkte) Shell erhalten und von dort aus in interne Hosts sshen können.
quelle
Es ist ein neues Kind auf dem Block. SSH piper leitet Ihre Verbindung basierend auf vordefinierten Benutzernamen weiter, die den inneren Hosts zugeordnet werden sollten. Dies ist die beste Lösung im Zusammenhang mit Reverse-Proxy.
SSh Piper auf Github
Meine ersten Tests haben bestätigt, dass SSH und SFTP funktionieren.
quelle
debug1: Sending subsystem: sftp
. Es stellt sich heraus, dass die Shirt-Front keine Subsysteme unterstützt. Unterstützen Sie Saum in SSh Piper?Ich frage mich, ob Honeytrap (der Honeypot mit geringer Interaktion), der über einen Proxy-Modus verfügt, nicht geändert werden kann, um dies zu erreichen.
Dieser Honeypot kann jedes Protokoll an einen anderen Computer weiterleiten. Das Hinzufügen eines namensbasierten vhost-Systems (wie von Apache implementiert) könnte es zu einem perfekten Reverse-Proxy für jedes Protokoll machen, nicht wahr?
Ich habe nicht die Fähigkeiten, das zu erreichen, aber vielleicht könnte es ein großartiges Projekt sein.
quelle
Mit zunehmender Anzahl der Ports / Hosts, auf die Sie hinter einer Firewall zugreifen möchten, steigt der Komfort von VPNs.
VPNs mag ich allerdings nicht.
quelle
wegen der arbeitsweise von ssh denke ich ist das nicht möglich. Ähnlich wie bei https müssten Sie unterschiedliche (externe) IP-Adressen für verschiedene Hosts haben, da das Gateway nicht weiß, wo Sie eine Verbindung herstellen möchten, da alles in ssh verschlüsselt ist
quelle