![通过远程端口转发通过 Jumphost 进行 SSH 会话](https://linux22.com/image/122854/%E9%80%9A%E8%BF%87%E8%BF%9C%E7%A8%8B%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91%E9%80%9A%E8%BF%87%20Jumphost%20%E8%BF%9B%E8%A1%8C%20SSH%20%E4%BC%9A%E8%AF%9D.png)
我们在通过远程端口转发进行 SSH 连接时遇到问题。
该场景是一个企业网络,内部网络上的服务器(我们称之为“源”)必须通过 SSH 登录到 DMZ 中的服务器(“目标”)。由于 DMZ 中的目标服务器对于来自内部网络的连接被锁定(甚至无法从内部网络看到),因此我们在 DMZ 中有一个跳转主机(“jumphost”)。我们通过在跳转主机上设置远程端口转发来实现此目的。
我们从内部网络上的源服务器运行此命令到跳转主机:
origin> ssh -R *:1234:target:22 myusername@jumphost
这是为了在跳转主机上建立 SSH 会话,使其开始侦听端口 1234(只是一个任意端口号示例),并将该端口上的连接转发到目标服务器端口 22 (SSH)。
然后我们在端口 1234 上建立第二个 SSH 会话,仍然是从源服务器到跳转主机,然后该会话实际上在端口 22 上连接到目标服务器 - 这是我们的“真正”SSH 会话,我们可以在其中完成我们的工作目标服务器:
origin> ssh jumphost -P 1234
配置
跳转主机已配置为允许远程端口转发,在 sshd_config 中进行以下设置:
AllowTcpForwarding yes
GatewayPorts yes
此外,在源服务器和跳转主机之间设置了防火墙开口,用于端口 22(用于初始 SSH 连接以设置远程端口转发)和端口 1234(用于转发端口上的后续 SSH 连接)。跳转主机和目标之间也有防火墙,已在端口 22 上打开。
结果
当我们建立第二个连接(通过转发端口的连接)时,该连接立即关闭(“连接被远程主机关闭”)。
在目标服务器上运行 tcpdump 显示没有任何活动,即连接似乎被阻止。
但是,我们能够成功建立从跳转主机到目标的常规 SSH 会话。仅当通过转发端口进入时,连接才会关闭,尽管两者都连接到端口 22 上的目标。
更重要的是,如果我们将端口转发指向内部网络上的服务器(即从内部网络上的原点到 DMZ 中的跳转主机,然后返回到内部网络上的第三台服务器的连接),那么 SSH会话建立成功。
猜测和疑问
所有这些让我相信某些网络安全设置正在发挥作用,它阻止通过跳转服务器上的转发端口连接到 DMZ 内的目标服务器。不幸的是我知识不够,无法知道:
(1) 从网络安全策略的角度来看,来自源服务器、通过跳转服务器上的转发端口的 SSH 连接是否“不同”,是否可以在技术上被阻止?如果可以,如何阻止?需要做什么才能解除该限制?
(2) 不允许此连接通过的任何其他原因 - 防火墙配置、路由器配置、源站或跳转主机上的 SSH 设置,还有其他原因吗?
(3) 是否会因为源服务器不知道目标服务器而失败,从而导致第一个 ssh 命令无法按预期工作?换句话说,第一个 ssh 命令(“目标”)中指定的主机名是在客户端(源)还是在我们连接到创建隧道(跳转主机)的服务器上解释的?
最令我困惑的是,可以从跳转主机到目标建立常规 SSH 会话,我认为通过转发端口进入的 SSH 连接将是相同的,但不知怎的,事实并非如此。
非常感谢任何意见。
答案1
看起来您应该使用本地端口转发而不是远程端口转发。您可能需要参考 Dirk Loss 撰写的以下有用的博客文章:
它包括以下说明图:
为了阅读该图,您需要知道它描述了创建和使用 SSH 隧道所涉及的 4 个不同角色之间的关系:
- 用于建立隧道的ssh 客户端(即
ssh
OpenSSH 命令行客户端); sshd
用于维护隧道另一端的ssh 服务器(即OpenSSH 服务器守护进程);- 应用程序服务器(例如另一个 ssh 服务器或 http 服务器);
- 想要通过隧道访问应用程序服务器的应用程序客户端(例如另一个 ssh 客户端或 Web 浏览器)。
同样重要的是要了解两种不同类型的转发对应于两种不同的用例:
本地转发:应用程序客户端通过 ssh 客户端连接的地方
远程转发:应用程序客户端通过 ssh 服务器连接
之所以称为远程转发,是因为转发是在远程(在 ssh 服务器)而不是在本地(在 ssh 客户端)执行的。我还发现“远程转发=反向转发”是一个有用的助记符。
正如您所看到的,为了通过代理上的服务器启动从主机ssh
上的客户端到第三台主机的连接,您必须使用本地端口转发。远程端口转发适用于您希望隧道的入口点位于运行服务器的主机而不是运行客户端的主机的情况。origin
sshd
jumphost
target
sshd
ssh
在手册页中,本地端口转发语法编写如下:
ssh -L [bind_address:]port:host:hostport user@remote
可以更直观地写成如下:
ssh -L [local_bind_address:]local_port:remote_host:remote_host_port user@proxy_host
或者,使用您的命名约定:
ssh -L [origin_bind_address:]origin_port:target_host:target_host_port user@jump_host
如果我们修改您的命令以使用本地端口转发,那么我们最终会得到以下结果:
user@origin:~$ ssh -L *:1234:target:22 myusername@jumphost