当你第一次连接到给定的 SSH 服务器时,你会得到一个关于密钥指纹的常见问题;之后,SSH 客户端将服务器公钥的副本存储在.ssh/known_hosts
文件中。但 SSH 客户端实际上存储了两个密钥:一个用于服务器名称,一个用于服务器IP。
例如,假设服务器foo.example.com
有 IP 10.0.0.8
。在您第一次连接ssh foo.example.com
时(指向同一个公钥。known_hosts
foo.example.com
10.0.0.8
当您连接回同一台服务器时,SSH 会验证这两个映射。如果第一个映射(用于名称的映射)产生的公钥与 中记录的不同known_hosts
,您会收到带有大写字母的可怕错误消息(这就是它如何变得可怕),并且客户端拒绝连接任何进一步(因此该消息不仅令人恐惧,而且还很不方便)。
另一种情况是当第一个映射匹配时:
- 用户类型:
ssh foo.example.com
.
- DNS 系统将该名称解析为 IP
10.0.0.8
。
- SSH 客户端连接到该机器,并获取 SSH 服务器公钥。
.ssh/known_hosts
获得的公钥与条目下的公钥匹配foo.example.com
。
- 但是获得的公钥与条目下的公钥不匹配。
.ssh/known_hosts
10.0.0.8
在这种情况下,您会收到您在问题中显示的确切消息。SSH 客户端可以确保您正在与预期的服务器对话——公钥与为相同服务器名称记录的公钥匹配——但仍然有问题,因此会出现警告和确认提示。
当服务器 IP 更改时,可能会发生这种情况。对于上面的示例,假设上周foo.example.com
有 IP 10.0.0.7
,但bar.example.com
有 IP 10.0.0.8
。那时,你连接到两者。但上周末,一位患有轻微强迫症的系统管理员决定必须更改一些 IP,以便他可以设置更高效、更规则和数学上优雅的网络规则。所以他“移动服务器”,并设置为bar.example.com
IP10.0.0.16
和. 我们的朋友系统管理员尽职尽责地配置了 DNS 以报告新 IP。现在,我们是星期一,您想再次联系。您的 SSH 客户端与 DNS 对话,获取 的新 IP ,一切都很好,只是记录的密钥与 的公钥不匹配foo.example.com
10.0.0.8
foo.example.com
10.0.0.8
foo.example.com
:确实,您的known_hosts
文件包含 的公钥的副本bar.example.com
,列在 IP 下10.0.0.8
,截至上周,它是bar
的 IP,而不是foo
的。
对于这种情况,具有强迫症的系统管理员并不是绝对必要的。它也可能发生在动态 IP 设置或某些负载平衡情况下。
解决方案:使用文本编辑器并从您的known_hosts
(第 14 行,在您的情况下)中删除有问题的条目。您还可以使用该命令ssh-keygen -R <host>
删除特定条目。下次连接时,客户端会显示另一个警告(这一次抱怨目标 IP没有任何记录的公钥),但这个警告会飞过,几乎不会被注意到,因为根本不会有任何提示。然后,SSH 客户端将再次将公钥记录在 中known_hosts
,并进行正确设置,至少在系统管理员再次听到声音之前。
或者,通过将选项设置CheckHostIP
为no
(在系统范围内/etc/ssh/ssh_config
,或您的.ssh/config
,或直接在命令行上:)来禁用 SSH 客户端中的主机 IP 检查ssh -o CheckHostIP=no foo.example.com
。主机 IP 检查对于检测服务器名称漂移的异常情况很有用,但对于某些系统管理员来说,服务器 IP 杂耍是完全“正常的”。