Назад | Перейти на главную страницу

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

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

Задний план

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

Теперь я хочу начать очки docker-контейнер таким образом, чтобы gogs.mydomain.com указывает на контейнер для очков. Итак, я начинаю этот контейнер для очков с портом 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 требует пароль для пользователя git на gogs.mydomain.com - вместо того gogs.mydomain.com:8022 - но, вероятно, я делаю что-то неправильно и выходит за рамки этого вопроса, однако я был бы признателен за любой диагноз и для этого)

Проблема

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


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

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


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

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


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

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

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

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

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

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

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

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

ssh -J proxyuser@jumphost user@target