我已经进入了一个非常具体的情况,虽然还有其他方法可以做到这一点,但我还是有点沉迷于此,想find一种方法来做到这一点:
假设我有一台服务器运行多个服务,并将其隐藏在独立的docker集装箱中。 由于大多数这些服务都是http,我正在使用一个nginx代理来向每个服务公开特定的子域名。 例如,节点服务器在端口80绑定到主机上的127.0.0.1:8000的Docker容器上运行。 我将在nginx中创build一个虚拟主机,将所有对myapp.mydomain.com请求代理到http://127.0.0.1:8000 。 这样一来,除了通过myapp.mydomain.com之外,docker容器不能从外部访问。
现在我想以gogs.mydomain.com指向gogs容器的方式启动一个gogs docker容器。 所以我启动这个在端口8000绑定到127.0.0.1:8001 gogs容器 。 和一个nginx网站代理请求gogs.mydomain.com到http://127.0.0.1:8001 ,它运作良好…
然而,gogs是一个git容器,我也想通过[email protected]:org/repo访问repos,但是不能用于当前的设置。 一种方法是将容器的端口22绑定到主机上的端口0.0.0.0:8022 ,然后git ssh url可以是[email protected]:8022/repo 。
(这似乎并没有工作;当我推到这样的uri的起源,git要求gogs.mydomain.com用户git的密码 – 而不是gogs.mydomain.com:8022 – 但这可能是我'这个问题做错了,也不在这个范围之内,不过,我也希望对此有任何诊断)
我主要关心的是,我希望ssh端口<gogs container>:22被代理,就像我使用nginx代理http端口; 即任何SSH连接gogs.mydomain.com传递到容器的端口22 。 现在我不能将容器的ssh端口绑定到主机的ssh端口,因为主机上已经有一个sshd运行了。 此外,这将意味着任何连接到*.mydomain.com传递到容器的sshd。
我想要任何SSH连接:
mydomain.com host.mydomain.com或mydomain的IP地址被接受并转发到主机上的sshd gogs.mydomain.com或git.mydomain.com被接受传递到gogs容器上的sshd *.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永远不会知道你要求你的客户端连接到什么主机名,因为这个信息没有被传递到协议中。
如果你只需要几个客户端来处理这个问题,你可以configuration每个客户端连接到你的服务器,然后像下面这样跳转到docker容器:
Host yourcontainer Hostname internal.ip.of.your.container ProxyCommand ssh your.docker.host nc %h %p
这种方式ssh将调用代理命令,这将打开一个ssh会话到您的主机,并呼吁netcatbuild立一个连接到您的容器。 这样你并不需要把你的容器的ssh端口暴露给外部世界。
最近的OpenSSH版本有ProxyJump指令和-J标志:
ssh -J proxyuser@jumphost user@target