Przekazywanie połączeń ssh do kontenera dokującego według nazwy hosta

10

Wpadłem w bardzo specyficzną sytuację i chociaż są na to inne sposoby, miałem obsesję na tym punkcie i chciałbym znaleźć sposób na zrobienie tego dokładnie tak:

tło

Powiedzmy, że mam serwer z kilkoma usługami schowanymi w izolowanych kontenerach dokerów. Ponieważ większość z tych usług to http, używam proxy nginx, aby udostępnić określone subdomeny każdej usłudze. Na przykład serwer węzła działa na kontenerze dokowanym, a jego port jest 80powiązany 127.0.0.1:8000z hostem. Stworzę vhosta w nginx, który pośredniczy w wysyłaniu wszystkich żądań myapp.mydomain.comdo http://127.0.0.1:8000. W ten sposób do kontenera dokowanego nie można uzyskać dostępu z zewnątrz, chyba że przez myapp.mydomain.com.

Teraz chcę uruchomić kontener dokujący gogs w taki sposób, gogs.mydomain.comaby wskazywał kontener gogs. Więc zaczynam ten kontener gogs z portem 8000powiązanym 127.0.0.1:8001z hostem. I strona nginx prosi o gogs.mydomain.comto http://127.0.0.1:8001i działa dobrze ...

Jednak, jako że gog jest kontenerem git, chciałbym również uzyskać dostęp do repozytoriów jak przez, [email protected]:org/repoale to nie działa z obecną konfiguracją. Jednym ze sposobów, aby to zadziałało, byłoby powiązanie portu 22kontenera z portem 0.0.0.0:8022na hoście, a wtedy git ssh url może być podobny [email protected]:8022/repo.

(Wydaje się, że to nie działa; kiedy pcham do źródła z takim identyfikatorem URI, git wymaga hasła dla użytkownika gitna gogs.mydomain.com- zamiast gogs.mydomain.com:8022- ale prawdopodobnie to coś robię źle i nie wchodzi w zakres tego pytania, ale: Byłbym wdzięczny za każdą diagnozę)

Problem

Moim głównym zmartwieniem jest to, że chcę, aby port ssh <gogs container>:22był proxy tak samo, jak proxy dla portów HTTP za pomocą nginx; tzn. wszelkie połączenia ssh w celu gogs.mydomain.comprzekazania do portu kontenera 22. Teraz nie mogę powiązać portu ssh kontenera z portem ssh hosta, ponieważ na hoście jest już uruchomiony sshd. Oznaczałoby to również, że wszelkie połączenia do *.mydomain.comprzekazania do sshd kontenera.


Chcę, aby wszelkie połączenia ssh:

  • mydomain.com host.mydomain.com lub adres IP mydomain, który zostanie zaakceptowany i przesłany do sshd na hoście
  • gogs.mydomain.comlub git.mydomain.comzostać zaakceptowanym przekazane do sshd na kontenerze gogs
  • *.mydomain.com(gdzie *jest coś innego niż powyższe możliwości) do odrzucenia

Gdyby to był http, mógłbym łatwo sprawić, by działało to za pomocą nginx. Czy jest na to sposób dla ssh?


(Chciałbym również wyjść na kończynę i zapytać: czy istnieje sposób, aby to osiągnąć za pomocą jakiejkolwiek usługi tcp w ogóle?)

Wszelkie spostrzeżenia na temat sposobu, w jaki próbuję to zrobić tutaj, są również mile widziane. Nie mam nic przeciwko byciu poinformowanym, kiedy to, co próbuję zrobić, jest całkowicie głupie.


Co mam już na myśli:

Może mógłbym udostępnić gniazdo sshd na hoście z kontenerem jako rowolumin? Oznaczałoby to, że sshd wewnątrz kontenera może odbierać wszystkie połączenia z *.mydomain.com. Czy może istnieć sposób, aby sshd wewnątrz kontenera odrzucił wszystkie połączenia inne niż gogs.mydomain.comlub git.mydomain.com? Jednak sshd na hoście odbierze wszystkie połączenia, w *.mydomain.comtym gogs.mydomain.com; więc będzie konflikt. Nie wiem, nie próbowałem tego. Powinienem spróbować?

Zia Ur Rehman
źródło

Odpowiedzi:

2

Robienie tego „według nazwy hosta” po prostu nie wchodzi w zakres ssh. Sam protokół ssh nie obsługuje hostingu wirtualnego opartego na nazwie (w rzeczywistości HTTP jest wyjątkiem od reguły tutaj).

SSHd po stronie odbierającej nigdy nie może wiedzieć, z jaką nazwą hosta poprosiłeś klienta, aby się połączyć, ponieważ te informacje nie są przekazywane do protokołu.

Jeśli potrzebujesz tylko kilku klientów, możesz skonfigurować każdego klienta, aby łączył się z serwerem, a następnie przeskoczyć do kontenera dokowanego w następujący sposób:

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

W ten sposób ssh wywoła polecenie proxy, które otworzy sesję ssh na twoim hoście i zadzwoni, netcataby ustanowić połączenie z twoim kontenerem. W ten sposób tak naprawdę nie musisz narażać swojego portu ssh kontenerów na świat zewnętrzny.

Andreas Rogge
źródło
0

Najnowsze wersje OpenSSH mają dyrektywę ProxyJump i flagę -J:

ssh -J proxyuser@jumphost user@target
ptman
źródło