Я попал в очень специфическую ситуацию, и хотя есть другие способы сделать это, я как бы одержим этим и хотел бы найти способ сделать это именно так:
Скажем, у меня есть сервер, на котором запущено несколько сервисов, спрятанных в изолированных контейнерах докеров. Поскольку большинство из этих сервисов являются 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-соединения:
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
; так был бы конфликт. Не знаю, на самом деле я не пробовал. Должен Я попробую?
Выполнение этого «по имени хоста» просто не входит в сферу действия 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