我正在建立一个具有许多 Linux 主机(50-200 个)的网络,并且我希望能够从一个 IP 地址和一个端口访问所有 200 个主机。
规则如下。每台主机最多可以有 20 个用户,但几乎所有主机都只有 2 个或 3 个用户。所有身份验证都将通过公钥进行。所有密钥都保证是唯一的。一次可以有任意数量的活动连接。所有主机都将具有唯一的网络内部 IP,并且所有主机都将在端口 22 上监听 SSH 连接。
鉴于上述限制,我该如何设置一个可以处理所有主机上所有用户的 SSH 连接的服务?
答案1
最简单且常用的方法是让一个系统使用 SSH 的常规“TCP 转发”功能充当网关。也就是说,您以普通用户身份连接到(公共)主机 A,设置隧道,并通过该隧道连接到您需要的任何内部地址。
这将是与使用相同的技术ssh -L
,但有更简单的方法来配置它而不必弄乱端口,例如ssh -W
或新ssh -J
选项:
ssh -J gatehost internalhost
# Older clients:
ssh -o ProxyCommand="ssh -W %h:%p gatehost" internalhost
putty -proxycmd "plink -nc %host:%port gatehost" internalhost
其他方法不太可能令人满意。SSH 中没有 TLS SNI 等效项,因此与 sniproxy 或 haproxy 能够根据请求的主机名将 TLS 连接路由到不同主机不同,您无法对 SSH 执行相同操作。
公共主机不可能看到用户的公钥和同时将 SSH 流量代理到另一台主机。用户身份验证是在加密设置完成后作为后续步骤进行的(与 TLS/HTTPS 没有太大区别),因此公共主机需要拦截密钥交换握手才能查看用户密钥。但如果我没记错的话,SSH 的用户身份验证阶段使用“通道绑定”——它包括有关之前完成的加密握手的详细信息,恰恰以防止像这样的“中间人”攻击——如果密钥交换是在客户端和主机 A 之间完成的,但用户身份验证消息以某种方式转发到主机 B,则协议将检测到这一点。
公共主机可以像平常一样接受用户身份验证,并且自动通过 ssh 连接到另一台主机,而不是启动 shell——这是可行的,但基本实现仅支持交互式会话,不支持 SFTP、隧道和代理转发。(也许有商业产品可以完美地做到这一点,但我希望它们的定价会根据大型银行或政府支付的价格而定。)