Пересылать ssh-соединения в Docker-контейнер по имени хоста

10

Я попал в очень специфическую ситуацию, и хотя есть и другие способы сделать это, я вроде как стал одержим этим и хотел бы найти способ сделать это именно так:

Задний план

Скажем, у меня есть сервер, на котором запущено несколько сервисов в изолированных док-контейнерах. Поскольку большинство из этих сервисов являются http, я использую прокси nginx для предоставления определенных поддоменов каждому сервису. Например, сервер узла работает в док-контейнере, порт которого 80привязан к 127.0.0.1:8000хосту. Я создам vhost в nginx, который проксирует все запросы myapp.mydomain.comк http://127.0.0.1:8000. Таким образом, к док-контейнеру нельзя получить доступ снаружи, кроме как через myapp.mydomain.com.

Теперь я хочу запустить контейнер докера gogs таким образом, gogs.mydomain.comчтобы он указывал на контейнер gogs. Поэтому я запускаю этот контейнер gogs с портом, 8000привязанным к 127.0.0.1:8001хосту. И сайт nginx проксирует запросы gogs.mydomain.comк http://127.0.0.1:8001и это работает хорошо ...

Тем не менее, gogs является git-контейнером, я также хотел бы получить доступ к репозиториям, например, через, git@gogs.mydomain.com:org/repoно это не работает с текущей настройкой. Один из способов сделать это - привязать порт 22контейнера к порту 0.0.0.0:8022на хосте, и тогда URL-адрес git ssh может быть чем-то вроде git@gogs.mydomain.com:8022/repo.

(Это не похоже на работу, когда я нажимаю на происхождение с URI , как это, мерзавец требует пароль для пользователя gitна gogs.mydomain.com- вместо gogs.mydomain.com:8022- но это, вероятно , что - то я делаю не так , и выходит за рамки этого вопроса, однако, Я был бы признателен за любой диагноз для этого тоже)

проблема

Моя главная проблема заключается в том, что я хочу, чтобы ssh-порт <gogs container>:22был проксирован так же, как я использую nginx; т.е. любые ssh-соединения для gogs.mydomain.comпередачи на порт контейнера 22. Теперь я не могу связать ssh-порт контейнера с ssh-портом хоста, потому что на хосте уже работает sshd. Кроме того, это будет означать, что любые соединения *.mydomain.comпередаются в sshd контейнера.


Я хочу, чтобы любые соединения SSH:

  • mydomain.com host.mydomain.com или IP-адрес mydomain, который будет принят и переслан sshd на хосте
  • gogs.mydomain.comили git.mydomain.comбыть принятым переданным в sshd на контейнере gogs
  • *.mydomain.com(где *есть что-то кроме возможностей выше), чтобы быть отклоненным

Если бы это был http, я мог бы легко заставить это работать через nginx. Есть ли способ сделать это для SSH?


(Также хотел бы выйти на конечности и спросить: есть ли способ сделать это с любой службой tcp в целом?)

Любое понимание того, как я пытаюсь сделать это здесь, также приветствуется. Я не против, когда мне говорят, что то, что я пытаюсь сделать, совершенно глупо.


Что у меня уже есть в голове:

Может быть, я мог бы поделиться сокетом sshd на хосте с контейнером как roтом? Это будет означать, что sshd внутри контейнера может перехватывать все соединения *.mydomain.com. Может ли быть способ заставить sshd внутри контейнера отклонять все соединения, кроме gogs.mydomain.comили git.mydomain.com? Тем не менее, sshd на хосте в *.mydomain.comлюбом случае подхватит все соединения, включая gogs.mydomain.com; так что будет конфликт. Я не знаю, я на самом деле не пробовал это. Должен ли я попробовать это?

Зия Ур Рехман
источник

Ответы:

2

Выполнение этого «по имени хоста» просто не входит в сферу применения ssh. Сам протокол ssh не поддерживает виртуальный хостинг на основе имен (фактически HTTP является исключением из этого правила).

SSHd на принимающей стороне никогда не может знать, к какому имени хоста вы обратились к клиенту, поскольку эта информация не передается внутри протокола.

Если вам просто нужно несколько клиентов для работы с этим, вы можете настроить каждый клиент для подключения к вашему серверу, а затем перейти к контейнеру Docker следующим образом:

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

Таким образом, ssh вызовет команду прокси, которая откроет сеанс ssh для вашего хоста и вызовет netcatсоединение с вашим контейнером. Таким образом, вам не нужно выставлять ваш контейнер ssh-порт внешнему миру.

Андреас Рогге
источник
0

Последние версии OpenSSH имеют директиву ProxyJump и флаг -J:

ssh -J proxyuser@jumphost user@target
ptman
источник