在未启用 GatewayPorts 的情况下执行 SSH 反向端口转发

a3n*_*3nm 1 networking linux ssh port port-forwarding

我有两台机器,m1 和 m2,机器 m2 可以使用 SSH 连接到 m1。有一台机器m1bis只能连接到m1,还有一台机器m2bis只能连接m2。我想让 m1bis 通过连接到机器 m1 的某个端口 p 来到达某个端口 q 上的机器 m2bis。假设 p 和 q 都是非特权端口,即它们大于 1024。在图片中:

+-------+   q   +----+   SSH   +----+   p   +-------+
| m1bis | ----> | m1 | <------ | m2 | ----> | m2bis |
+-------+       +----+         +----+       +-------+
Run Code Online (Sandbox Code Playgroud)

我可以通过 shell 访问 m1 和 m2。我通常的做法是使用 SSH 反向端口转发,通过在 m2 上运行以下命令:

ssh -R *:q:m2bis:p m1
Run Code Online (Sandbox Code Playgroud)

这使得 m1 上的 SSH 守护进程侦听所有接口上的端口 q,并将任何传入连接中继到机器 m2bis 的端口 p。这样,当 m1bis 连接到机器 m1 的端口 q 时,连接通过 SSH 从 m1 路由到 m2,并且连接实际上发生在机器 m2bis 的端口 p 上。到现在为止还挺好。

问题是这需要GatewayPorts=yes在 m1 上的 SSH 服务器配置中启用该设置。但是,它没有启用,而且我不是 m1 上的 root,所以我无法启用它。

然而,在我看来,没有什么能真正阻止我解决这个问题并进行端口转发:我可以访问 m1,我可以在 m1 和 m2 之间建立 SSH 连接,我可以在 m1 上运行一个进程来监听在所有接口上的端口 q 上(而不是让 SSH 守护程序进行侦听)并通过 SSH 路由连接。所以基本上我拥有所有必要的权限来构建我自己的端口。

我真的可以做到这一点,有没有简单的方法来做到这一点?

其他要求:

  • 由于我不是根(M1)上,我宁愿一个解决方案,无需复杂的依赖关系,最好有像普通公用事业一些bash脚本netcatsocat等等,或一些自包含的C程序。
  • 我是 m2 的根,如果有帮助的话(但原则上我认为我也不应该需要这个)。
  • 我不信任 m1 和 m2 之间的连接,所以应该在 m1 和 m2 之间加密转发(即,它应该真正通过 SSH)。

小智 5

一个有效的解决方案是在 m1 上运行您自己的 SSH 守护程序,这在没有 root 的情况下是可行的。以下是如何以普通用户身份运行 SSH 守护程序。

首先生成主机密钥:

ssh-keygen -f test_host_rsa -N  '' -t rsa
ssh-keygen -f test_host_dsa -N  '' -t dsa
ssh-keygen -f test_host_ed25519 -N  '' -t ed25519
Run Code Online (Sandbox Code Playgroud)

然后为您的 sshd 编写一个配置文件,其中 2222 是某个未在 m1 上使用且 m2 可以连接的非特权端口,并且您还需要在其中指明当前文件夹的绝对路径:

cat >sshd_config <<EOF
Port 2222
HostKey /folder/where/the/files/are/test_host_rsa
HostKey /folder/where/the/files/are/test_host_dsa
HostKey /folder/where/the/files/are/test_host_ed25519
GatewayPorts yes
Run Code Online (Sandbox Code Playgroud)

现在运行你的 SSH 守护进程:

/usr/sbin/sshd -f sshd_config
Run Code Online (Sandbox Code Playgroud)

现在,m2 可以连接到 m1 的端口 2222 并向前运行反向端口,因为在您的 SSH 守护程序上启用了 GatewayPorts。换句话说,在 m2 上你可以运行:

ssh -p 2222 -R *:q:m2bis:p m1
Run Code Online (Sandbox Code Playgroud)