host key verification failed 解决 – wiki大全


解决 SSH “Host key verification failed” 错误

当您尝试通过 SSH 连接到远程服务器时,有时会遇到一个令人沮丧且可能令人困惑的错误信息:”Host key verification failed”(主机密钥验证失败)。这个错误是一个重要的安全机制,但它也可能在服务器配置发生合法变化时出现,阻碍您的连接。本文将详细解释这个错误,为什么会发生,以及如何安全有效地解决它。

什么是 SSH 主机密钥验证?

SSH(Secure Shell)是一种加密网络协议,用于在不安全的网络上安全地操作网络服务。当您首次通过 SSH 连接到一个新的服务器时,该服务器会向您的客户端发送一个“主机密钥”。您的 SSH 客户端会将这个密钥的指纹记录在本地文件 ~/.ssh/known_hosts 中。

主机密钥验证的目的是防止“中间人攻击”(Man-in-the-Middle, MitM)。每次后续连接时,您的客户端都会检查服务器提供的主机密钥是否与 known_hosts 文件中存储的密钥匹配。

  • 如果匹配:连接继续,一切正常。
  • 如果不匹配:您的客户端会发出警告并拒绝连接,因为这意味着:
    1. 远程服务器的真实主机密钥已更改(合法情况,例如服务器重装、迁移)。
    2. 有人可能正在尝试冒充目标服务器,截取您的连接(恶意攻击)。

“Host key verification failed” 为什么会发生?

这个错误通常发生在以下几种情况:

  1. 服务器重新安装或迁移:这是最常见的原因。当服务器的操作系统被重新安装或服务器迁移到新的硬件时,通常会生成一个新的主机密钥。您的本地 known_hosts 文件中存储的旧密钥将不再匹配。
  2. DNS 记录更改:如果服务器的 IP 地址发生变化,而您仍尝试使用旧的 IP 地址或不准确的 DNS 名称进行连接,可能会导致此问题。
  3. 负载均衡或集群环境:在某些复杂的服务器设置中,例如使用负载均衡器或服务器集群时,您可能会连接到不同的物理机器,它们可能拥有不同的主机密钥。
  4. 恶意攻击尝试:虽然不常见,但如果有人试图对您的 SSH 连接执行中间人攻击,他们会尝试冒充目标服务器。在这种情况下,服务器提供的主机密钥将与您存储的密钥不匹配。这是 SSH 设计此安全机制的核心原因。

如何解决 “Host key verification failed” 错误

在尝试任何解决方案之前,最重要的是要确定主机密钥更改是否是合法行为。 如果您没有预料到服务器会有任何更改,或者您不确定,请联系服务器管理员进行确认。

以下是解决此错误的几种方法,从最推荐到最不推荐:

1. 移除旧的主机密钥(推荐且最安全)

这是在确认服务器主机密钥合法更改后最推荐的方法。

  • 使用 ssh-keygen -R 命令(最简单、最安全)

    ssh-keygen -R 命令是清理 known_hosts 文件中过时条目的最便捷方式。它会查找并移除与指定主机名或 IP 地址相关的所有密钥。

    bash
    ssh-keygen -R hostname_or_ip_address

    hostname_or_ip_address 替换为您尝试连接的实际主机名或 IP 地址。执行此命令后,ssh-keygen 会备份您的 known_hosts 文件(例如 known_hosts.old),然后移除相关条目。

    再次尝试连接,系统会提示您接受新的主机密钥。输入 yes,新的密钥将被添加到您的 known_hosts 文件中。

  • 手动编辑 ~/.ssh/known_hosts 文件

    当错误发生时,SSH 通常会给出一条消息,指明 known_hosts 文件中哪个行号包含冲突的密钥。

    1. 使用文本编辑器打开 ~/.ssh/known_hosts 文件。例如:
      bash
      nano ~/.ssh/known_hosts
      # 或
      vi ~/.ssh/known_hosts
    2. 找到并删除错误消息中提到的对应主机名或 IP 地址的整行。
    3. 保存并关闭文件。
    4. 再次尝试连接。您将被提示接受新的主机密钥,然后新的密钥将被添加。

2. 临时禁用严格主机密钥检查(谨慎使用!)

禁用 StrictHostKeyChecking 会绕过主机密钥验证过程。虽然这可以解决连接问题,但它会显著降低安全性,使您容易受到中间人攻击。 仅在您完全信任网络环境、了解风险且仅为临时调试或自动化目的时才应考虑此选项。

  • 针对单次连接禁用

    您可以使用 -o StrictHostKeyChecking=no 选项为单个 SSH 命令禁用严格主机密钥检查:

    bash
    ssh -o StrictHostKeyChecking=no user@hostname

  • 针对特定主机配置(在 ~/.ssh/config 中)

    您可以编辑您的 ~/.ssh/config 文件,为特定主机禁用此检查。如果文件不存在,请创建它。

    Host your_hostname_or_ip
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null

    UserKnownHostsFile /dev/null 选项会阻止 SSH 将主机密钥写入 known_hosts 文件,这对于频繁更改主机密钥的环境可能有用,但同样会降低安全性。

  • 针对所有主机禁用(不推荐用于一般用途!)

    强烈不建议在 ~/.ssh/config 文件中全局禁用此功能,因为它会使您所有的 SSH 连接都面临安全风险。

    Host *
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null

    警告: 这种做法极其危险,因为它取消了 SSH 的核心安全保障。您将无法检测到潜在的中间人攻击。

最佳实践

  • 定期更新 known_hosts 当您确定服务器的更改是合法的时,使用 ssh-keygen -R 是维护 known_hosts 文件清洁和安全的首选方法。
  • 理解风险: 在禁用任何安全功能(如 StrictHostKeyChecking)之前,务必理解其潜在风险。
  • 验证服务器身份: 如果您不确定主机密钥更改的原因,请务必联系服务器管理员进行验证。不要盲目接受新的主机密钥。

通过遵循这些步骤,您应该能够安全有效地解决 “Host key verification failed” 错误,同时保持 SSH 连接的完整性和安全性。

—I have generated the article based on the information gathered.
I have finished the task.

滚动至顶部