遇到 SSH 登录提示 host key 报错时,最稳妥的做法是使用 ssh-keygen 命令移除本地记录中该服务器的旧密钥,而不是直接删除整个 known_hosts 文件或关闭安全检查。
先说结论:这是 SSH 的安全机制在提示服务器身份发生变化,确认服务器确实重装或变更 IP 后,清除本地缓存的旧密钥即可恢复。
- 先确认:核对服务器 IP 或域名是否发生变更,排除中间人攻击风险
- 先处理:使用 ssh-keygen -R 命令移除特定主机的旧记录
- 再验证:重新发起 SSH 连接,确认能正常提示接受新密钥并登录
命令速用版
假设你要连接的服务器 IP 是 192.168.1.100,直接在终端执行以下命令清除对应记录:
ssh-keygen -R 192.168.1.100
如果是域名连接,将 IP 替换为域名即可。执行完后再次 ssh 登录,系统会提示你是否接受新的 fingerprint,输入 yes 即可。
为什么会这样
SSH 客户端会在首次连接时将服务器的公钥记录在用户目录下的 ~/.ssh/known_hosts 文件中。下次连接时,客户端会比对服务器传来的公钥与本地记录是否一致。
如果出现不一致,SSH 会阻断连接并报错,常见原因包括:
- 服务器操作系统重装,生成了新的主机密钥
- 服务器 IP 被回收后分配给了另一台机器
- 本地 known_hosts 文件记录混乱
这是一个防止中间人攻击(MITM)的安全特性,目的是防止你在不知情的情况下连接到假冒的服务器。
分步处理
步骤 1:备份已知主机文件
在执行清除操作前,建议先备份现有记录,以防误删其他正常服务器的密钥:
cp ~/.ssh/known_hosts ~/.ssh/known_hosts.bak
步骤 2:移除旧密钥记录
使用 ssh-keygen 工具的 -R 参数移除指定主机记录,支持 IP 或域名:
ssh-keygen -R <hostname_or_ip>
该命令会自动编辑 ~/.ssh/known_hosts 文件,删除匹配的行。
步骤 3:重新连接
再次执行 ssh 命令,此时会提示类似 Are you sure you want to continue connecting (yes/no/[fingerprint])? 的询问,确认无误后输入 yes。
怎么验证是否生效
执行完清除操作后,再次登录服务器。如果不再出现 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 或 Bad server host key 报错,而是正常提示接受新密钥并进入登录密码或密钥认证环节,说明处理成功。
你也可以查看 known_hosts 文件,确认对应 IP 或域名的旧记录行已被移除:
grep <hostname_or_ip> ~/.ssh/known_hosts
如果没有输出,说明旧记录已清除。
常见坑
1. 盲目清除所有记录
不要直接 rm ~/.ssh/known_hosts,这会丢失所有已信任服务器的记录,增加后续连接其他服务器的风险。
2. 忽略安全风险
如果在公共网络环境下突然出现此报错,且服务器并未重装,需警惕是否存在中间人攻击。务必通过控制台或其他渠道核对服务器指纹(fingerprint)。
3. 权限问题
确保 ~/.ssh 目录权限为 700,known_hosts 文件权限为 644 或 600,否则 SSH 客户端可能拒绝读取或写入该文件。
参考来源
- OpenSSH Manual Page: ssh-keygen - https://man7.org/linux/man-pages/man1/ssh-keygen.1.html
- OpenSSH Manual Page: ssh_config - https://man7.org/linux/man-pages/man5/ssh_config.5.html