首次通过 ssh 连接服务器时,服务器会向用户显示所选密钥算法的公钥,以进行验证。验证后,结果通常会保存到文件中,~/.ssh/known_hosts
以抵御后续的 MITM 攻击(首次使用时信任或 TOFU 原则)。
$ ssh host.example.com
The authenticity of host 'host.example.com (1.2.3.4)' can't be established.
ECDSA key fingerprint is SHA256:xxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no)?
这显然无助于抵御第一次连接上的 MITM 攻击,而只是将问题转移到用户身上,用户现在必须采取某种流程来验证所提供的公钥 - 我们都知道结果会如何。
是否可以分发由公司 CA 签名的 ssh 服务器密钥,以在首次接触时抵御 MITM 攻击?带有证书链的公钥-私钥基础结构通常支持此功能 - 但我从未见过它在公司环境中用于保护 ssh 服务器。
一般的想法是信任一组主机的 CA 密钥:
trust *.example.com SHA256:<fingerprint(public key(corporate-ca))>
符合该要求并且经过 CA 签名的每一个主机都是可信的:
ca.example.com
+- host.example.com
这与 HTTPS 的保护方式类似,并且由于 ssh 使用相同的底层技术 - 类似的东西是否已经在 OpenSSH 中实现,而我只是没有找到它?
答案1
这个有可能。
引用文档:
AUTHORIZED_KEYS FILE FORMAT
[...]
cert-authority
Specifies that the listed key is a certification authority (CA)
that is trusted to validate signed certificates for user authentication.
Certificates may encode access restrictions similar to these key options.
If both certificate restrictions and key options are present, the most
restrictive union of the two is applied.
实现此目标的步骤:
- 生成 SSH 服务器 CA 密钥:
ssh-keygen -f server_ca
- 生成 SSH 服务器主机密钥:
ssh-keygen -t ecdsa -b 521 -N '' -C 'somehost.example.com' -f ssh-ecdsa.key
- 使用你的 CA 密钥对主机密钥进行签名:
ssh-keygen -s server_ca -I somehost.example.com -h -n 'somehost.example.com,somehost,<list of SANs>,<list of IPv4>,<list of IPv6>' -V +3650d ssh-ecdsa.key
- 在您的 SSH 服务器中部署主机密钥 + 证书(将证书和密钥复制到
/etc/ssh
,然后编辑/etc/ssh/sshd_config
):
HostCertificate /etc/ssh/ssh-ecdsa.key-cert.pub
HostKey /etc/ssh/ssh-ecdsa.key
- 设置您的客户端以信任您的 CA 密钥来识别主机(~/.ssh/known_hosts)
@cert-authority example.com ssh-rsa AAAA[...]
笔记:
- 它与常规 X.509 PKI 不兼容。
- 需要维护(并使用)密钥撤销列表 (KRL)。请参阅OpenSSH 手册了解详情。
- 麻烦,考虑使用类似保险库以及一个配置管理工具来自动化这一过程。
- 看看猴子球项目采用了“SSH 信任网”的想法。
在下面的链接中查找更多信息,特别是有关如何设置以便为用户签署密钥的信息。
链接:
答案2
另一种方法是将 SSH 密钥指纹发布到 DNS 中,如下所示安全外壳指纹记录 (SSHFP)记录:
参见 RFC 4255https://www.rfc-editor.org/rfc/rfc4255
这使得公钥验证成为一个自动化过程,一旦你设置VerifyHostKeyDNS
到yes
(全局)ssh 客户端默认设置中。
答案3
如果是在公司环境中,您还可以拥有一个集中管理的所有机器的 SSH 密钥列表,然后可以/etc/ssh/ssh_known_hosts
使用您最喜欢的配置管理工具将其部署到所有客户端上。这也可以用于机器之间的直接基于主机的身份验证。(集中管理 SSH 主机密钥也有助于防止在重新安装服务器时发生不必要的主机密钥更改。)
当然,这种方法仅适用于客户端和服务器均受您控制的“内部” SSH 访问。如果您需要任意外部用户通过 SSH 访问(并且您不能只向他们提供 known_hosts 文件),DNSSEC 保护的 DNS 中的 SSHFP 记录可能是最佳选择。