将 SSH 请求转发到外部服务器到内部服务器

将 SSH 请求转发到外部服务器到内部服务器

我目前有一个 VM 配置,其中有 1 个外部 IP 指向一个 VM,该 VM 带有一个 Nginx HTTP 反向代理,该代理从几个没有外部 IP 的内部 VM 提供 HTTP 网页。

我需要一个类似的设置来将对某些主机名的 SSH 请求重定向到内部服务器,这是为了托管的 git 存储库,它位于代理后面,因此没有自己的外部 IP,所以我需要某种 iptables 规则来允许我反向代理/转发 SSH 请求到相应的虚拟机。

有人能给我指出正确的方向吗?

答案1

如果所有客户端都可以连接到端口 22,并且端口转发可以根据客户端想要访问的主机名将它们引导到正确的服务器,那将会非常方便。

不幸的是,这是不可能的。

客户端永远不会发送它要连接的主机名。(据我所知,客户端发送主机名的可用于此类代理的唯一协议是:http、https、smtp、dns)。此外,客户端将只打开 TCP 连接并等待来自服务器的横幅。这意味着您将完全没有应用层信息来作为服务器选择的依据。只有当您选择了服务器并从该服务器获取横幅以发送给客户端后,客户端才会开始使用 ssh。

从代理向客户端伪造横幅也行不通,因为代理不知道横幅的具体样子,如果横幅错误,ssh 客户端稍后会在连接设置过程中注意到这一点,并报告完整性错误。

不过您还有其他一些选择。

解决方案 1

将不同的端口号从网关转发到每台服务器上的端口 22。例如:

-A PREROUTING -i eth0 -d 192.0.2.42 -p tcp --dport 62210 -j DNAT --to-destination 192.168.42.10:22
-A PREROUTING -i eth0 -d 192.0.2.42 -p tcp --dport 62211 -j DNAT --to-destination 192.168.42.11:22

解决方案 2

通过其他协议代理 SSH。这可以使用 HTTP CONNECT 命令或 SOCKS 来实现。在 ssh 客户端上,您可以使用ProxyCommand指定使用相关协议的客户端,并在网关上运行代理。然后,网关上的代理软件将连接到实际的 ssh 服务器。

解决方案 3

代理思想的一个变体是通过 ssh 隧道传输 ssh。您可以从客户端运行以下命令:

ssh -o ProxyCommand='ssh -W %h:%p bastion-host' [email protected]

bastion-host可以是分配给代理的任何主机名。如果对代理进行身份验证,publickeyauthorized_keys可以限制授予的访问权限类型。应该可以将访问限制为仅转发到一个相关的 ssh 端口,而不允许将与代理的 ssh 连接用于其他任何用途。

解决方案 4

使用 IPv6。然后,您可以获得足够的 IP 地址,以便为每台服务器分配一个。如果 ssh 客户端在只能使用 Teredo 来获取 IPv6 访问权限的网络上运行,则可以通过在代理上运行 Teredo 中继来确保 ssh 连接仍然可靠。安装 Miredo 并将其配置为 Teredo 中继只需不到五分钟的时间。

答案2

只需使用 SSH 端口转发,这样会更安全(因为您不会向网络开放其他系统)。例如,您的主机 A 具有公有和私有 IP 地址,而主机 B 和 C 位于私有网络上。要连接到 B,请使用以下技术:

terminal-1$ ssh -L 10022:B_private_IP:22 A_public_IP

terminal-2$ ssh -p10022 user_at_B@0

只要终端 1 窗口正在运行,您就拥有到主机 B 的 ssh 隧道。

您可以使用 ~/.ssh/config 自动完成整个过程,因此您只需执行“ssh user_at_B@B”之类的操作,它就会为您启动隧道。

相关内容