Leiten Sie SSH-Verbindungen über den Hostnamen an den Docker-Container weiter

10

Ich bin in eine ganz bestimmte Situation geraten, und obwohl es andere Möglichkeiten gibt, dies zu tun, bin ich davon besessen und möchte einen Weg finden, dies genau so zu tun:

Hintergrund

Angenommen, ich habe einen Server, auf dem mehrere Dienste ausgeführt werden, die in isolierten Docker-Containern versteckt sind. Da die meisten dieser Dienste http sind, verwende ich einen Nginx-Proxy, um jedem Dienst bestimmte Subdomänen zur Verfügung zu stellen. Beispielsweise wird ein Knotenserver auf einem Docker-Container ausgeführt, dessen Port 80an 127.0.0.1:8000den Host gebunden ist . Ich werde einen vhost in nginx , dass Proxies alle Anfragen erstellen myapp.mydomain.comzu http://127.0.0.1:8000. Auf diese Weise kann nur von außen auf den Docker-Container zugegriffen werden myapp.mydomain.com.

Jetzt möchte ich einen Gogs Docker Container so starten , dass gogs.mydomain.comer auf den Gogs Container zeigt. Also starte ich diesen Gogs-Container mit einem Port 8000, der 127.0.0.1:8001an den Host gebunden ist . Und eine Nginx-Site, die Anfragen gogs.mydomain.coman http://127.0.0.1:8001und weiterleitet, funktioniert gut ...

Da Gogs ein Git-Container sind, möchte ich auch gerne auf die Repos zugreifen, [email protected]:org/repoaber das funktioniert mit dem aktuellen Setup nicht. Eine Möglichkeit, dies zu erreichen, besteht darin, den Port 22des Containers an den Port 0.0.0.0:8022auf dem Host zu binden , und dann kann die git ssh-URL so etwas wie sein [email protected]:8022/repo.

(Das scheint nicht zu funktionieren. Wenn ich mit so einem uri zu einem Ursprung drücke, fordert git das Passwort für den Benutzer gitan gogs.mydomain.com- statt gogs.mydomain.com:8022-, aber das ist wahrscheinlich etwas, was ich falsch mache und für diese Frage nicht geeignet bin. Ich würde mich auch über eine Diagnose freuen.)

Problem

Mein Hauptanliegen ist, dass ich möchte, dass der <gogs container>:22SSH-Port genauso wie ich HTTP-Ports mit nginx proxy; dh alle SSH-Verbindungen gogs.mydomain.com, die an den Port des Containers weitergeleitet werden sollen 22. Jetzt kann ich den SSH-Port des Containers nicht an den SSH-Port des Hosts binden, da auf dem Host bereits ein SSH ausgeführt wird. *.mydomain.comDies würde auch bedeuten, dass alle Verbindungen an das sshd des Containers übergeben werden.


Ich möchte alle SSH-Verbindungen zu:

  • mydomain.com host.mydomain.com oder die IP-Adresse von mydomain, die akzeptiert und an den sshd auf dem Host weitergeleitet werden soll
  • gogs.mydomain.comoder git.mydomain.comakzeptiert und an den sshd auf dem gogs container weitergegeben werden
  • *.mydomain.com(wo *ist etwas anderes als die oben genannten Möglichkeiten) abgelehnt werden

Wenn es http wäre, könnte ich das leicht durch Nginx machen. Gibt es eine Möglichkeit, dies für ssh zu tun?


(Möchte auch auf die Nerven gehen und fragen: Gibt es eine Möglichkeit, dies mit einem TCP-Dienst im Allgemeinen zu erreichen?)

Alle Einblicke in die Art und Weise, wie ich es hier versuche, sind ebenfalls willkommen. Es macht mir nichts aus, wenn mir gesagt wird, dass das, was ich versuche, absolut dumm ist.


Was ich schon im Kopf habe:

Vielleicht könnte ich den sshd-Socket auf dem Host mit dem Container als roVolume teilen ? Das würde bedeuten, dass der sshd im Container alle Verbindungen zu aufnehmen könnte *.mydomain.com. Könnte es eine Möglichkeit geben, das sshd im Container dazu zu bringen, alle Verbindungen außer gogs.mydomain.comoder abzulehnengit.mydomain.com ? Der sshd auf dem Host nimmt jedoch alle Verbindungen auf, *.mydomain.comeinschließlich gogs.mydomain.com; es würde also einen Konflikt geben. Ich weiß nicht, ich habe es nicht wirklich versucht. Soll ich es versuchen?

Zia Ur Rehman
quelle

Antworten:

2

Dies "nach Hostname" zu tun, liegt einfach nicht im Bereich von ssh. Das ssh-Protokoll selbst unterstützt kein namenbasiertes virtuelles Hosting (tatsächlich ist HTTP hier die Ausnahme von der Regel).

Die SSHd auf der empfangenden Seite kann niemals wissen, zu welchem ​​Hostnamen Sie Ihren Client aufgefordert haben, eine Verbindung herzustellen, da diese Informationen nicht innerhalb des Protokolls übergeben werden.

Wenn Sie nur einige Clients benötigen, um damit zu arbeiten, können Sie jeden Client so konfigurieren, dass er eine Verbindung zu Ihrem Server herstellt, und dann wie folgt zum Docker-Container springen:

Host yourcontainer
        Hostname internal.ip.of.your.container
        ProxyCommand ssh your.docker.host nc %h %p

Auf diese Weise ruft ssh den Proxy-Befehl auf, der eine ssh-Sitzung für Ihren Host öffnet und aufruft netcat, um eine Verbindung zu Ihrem Container herzustellen. Auf diese Weise müssen Sie den SSH-Port Ihres Containers nicht wirklich der Außenwelt aussetzen.

Andreas Rogge
quelle
0

Neuere OpenSSH-Versionen haben die ProxyJump-Direktive und das Flag -J:

ssh -J proxyuser@jumphost user@target
ptman
quelle