Zia*_*man 12 ssh reverse-proxy docker
我遇到了一个非常具体的情况,虽然还有其他方法可以做到这一点,但我有点着迷于此,并想找到一种完全像这样的方法:
假设我有一台服务器运行多个服务,这些服务隐藏在隔离的 docker 容器中。由于大多数这些服务都是 http,我使用 nginx 代理向每个服务公开特定的子域。例如,节点服务器运行在 docker 容器上,其端口80
绑定到127.0.0.1:8000
主机上。我将在 nginx 中创建一个虚拟主机,将所有请求代理myapp.mydomain.com
到http://127.0.0.1:8000
. 这样,docker 容器不能从外部访问,除了通过myapp.mydomain.com
.
现在我想以指向 gogs容器的方式启动一个gogsgogs.mydomain.com
docker 容器。所以我启动了这个 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
主机上的端口,然后 git ssh url 可以是类似git@gogs.mydomain.com:8022/repo
.
(这似乎不工作;当我推到与URI这样的原点,混帐要求密码对git
上gogs.mydomain.com
-而不是gogs.mydomain.com:8022
-但不过这可能是什么我做错了,超出范围的这个问题,我也很感激任何诊断)
我主要担心的是,我希望<gogs container>:22
代理ssh 端口,就像我使用 nginx 代理 http 端口一样;即任何gogs.mydomain.com
要传递到容器端口的ssh 连接22
。现在我无法将容器的 ssh 端口绑定到主机的 ssh 端口,因为主机上已经有一个 sshd 正在运行。此外,这意味着*.mydomain.com
要传递到容器的 sshd 的任何连接。
我想要任何 ssh 连接:
mydomain.com
host.mydomain.com
或 mydomain 的 IP 地址被接受并转发到主机上的 sshdgogs.mydomain.com
或被git.mydomain.com
接受并传递到 gogs 容器上的 sshd*.mydomain.com
(*
除了上述可能性之外的任何其他地方)被拒绝如果是 http,我可以通过 nginx 轻松完成这项工作。有没有办法为 ssh 做到这一点?
(也想出去问问:一般来说,有没有办法用任何tcp 服务来实现这一点?)
对我在这里尝试做的方式的任何见解,也欢迎。当我试图做的事情完全愚蠢时,我不介意被告知。
也许我可以将主机上的 sshd 套接字与容器共享为一个ro
卷?这意味着容器内的 sshd 可以获取到*.mydomain.com
. 有没有办法让容器内的 sshd拒绝除gogs.mydomain.com
or之外的所有连接git.mydomain.com
?但是,主机上的 sshd 将获取所有连接,*.mydomain.com
包括gogs.mydomain.com
; 所以会有冲突。我不知道,我还没有真正尝试过。我应该试试吗?
“通过主机名”执行此操作根本不在 ssh 的范围内。ssh 协议本身不支持基于名称的虚拟主机(事实上 HTTP 是此处规则的例外)。
接收端的 SSHd 永远无法知道您要求客户端连接到的主机名,因为此信息不会在协议内部传递。
如果您只需要几个客户端来使用此功能,您可以将每个客户端配置为连接到您的服务器,然后跳转到 docker 容器,如下所示:
Host yourcontainer
Hostname internal.ip.of.your.container
ProxyCommand ssh your.docker.host nc %h %p
Run Code Online (Sandbox Code Playgroud)
这样,ssh 将调用代理命令,该命令将打开到您的主机的 ssh 会话并调用netcat
以建立到您的容器的连接。这样你就不需要将容器的 ssh 端口暴露给外界。