SSH主机密钥验证失败(Host key verification failed)深度解析与解决方案

SSH主机密钥验证失败(Host key verification failed)深度解析与解决方案

在使用SSH(Secure Shell)或基于SSH协议的工具(如SCP、SFTP)进行远程连接或文件传输时,"Host key verification failed"是极为常见的报错。该报错看似阻碍了操作,实则是SSH协议的核心安全机制在发挥作用------防止中间人攻击(Man-in-the-Middle, MITM)。本文将结合实际报错案例,从原理、原因、解决方案到安全实践,全面拆解这一问题,帮助读者彻底掌握应对方法。

一、问题概述:从实际报错场景切入

本人在执行SCP命令向Kali虚拟机传输文件时,触发如下报错,导致文件传输失败:

bash 复制代码
scp Cwebscanner-master.zip kali@192.168.1.69:/home/kali/Downloads
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:m8h8XK+PhKKNRqus76T/PBSW+icLoCyPmAF9OVYO3Xg.
Please contact your system administrator.
Add correct host key in /Users/liuxiaowei/.ssh/known_hosts to get rid of this message.
Offending ED25519 key in /Users/liuxiaowei/.ssh/known_hosts:29
Host key for 192.168.1.69 has changed and you have requested strict checking.
Host key verification failed.
scp: Connection closed

核心报错信息:Host key verification failed (主机密钥验证失败),且明确指出了问题位置------本地/Users/liuxiaowei/.ssh/known_hosts文件的第29行,存储着与目标主机(192.168.1.69)不匹配的旧密钥。

二、核心原理:SSH主机密钥验证机制

要理解报错原因,首先要掌握SSH的主机密钥验证逻辑,这是SSH安全通信的基础:

  1. 首次连接:密钥存储 :当用户首次通过SSH/SCP连接远程主机时,远程主机会向客户端发送自己的主机密钥 (类似主机的"数字身份证",由远程主机的SSH服务生成,默认存储在/etc/ssh/目录下,如ssh_host_ed25519_key.pubssh_host_rsa_key.pub等)。客户端会提示用户确认该密钥的真实性,用户输入"yes"后,客户端会将该主机的IP/域名与对应的密钥指纹,存储到本地用户目录下的~/.ssh/known_hosts文件中。

  2. 后续连接:密钥校验 :之后每次连接该远程主机时,客户端会先从known_hosts文件中读取该主机的历史密钥,再与远程主机当前发送的密钥进行比对。若一致,则正常建立连接;若不一致,则立即触发"Host key verification failed"报错,拒绝连接------这是为了防止攻击者伪造目标主机,拦截并窃取用户的账号密码、传输数据等敏感信息。

关键结论:该报错的本质是"本地记录的远程主机密钥"与"远程主机当前的实际密钥"不匹配,SSH为规避中间人攻击风险,强制终止连接。

三、报错原因:正常场景与风险场景区分

密钥不匹配并非都是攻击导致,需先区分正常场景与风险场景,避免盲目操作带来安全隐患。

1. 正常场景(无安全风险,最常见)

这类场景是由于远程主机的密钥发生了合法变更,导致本地记录失效:

  • 远程主机重装系统/SSH服务:重装系统或重新安装、重置SSH服务时,原有的主机密钥会被删除,SSH服务会自动生成新的密钥对,导致密钥变更。

  • 手动重置远程主机SSH密钥 :管理员手动删除/etc/ssh/目录下的主机密钥文件,重启SSH服务后,系统会生成新密钥。

  • 目标IP被重新分配:若远程主机使用DHCP自动获取IP,路由器重启或IP租期到期后,该IP可能被分配给其他新设备,新设备的SSH密钥与原主机不同,导致校验失败。

2. 风险场景(需紧急排查)

若排除上述正常场景,则需警惕中间人攻击:攻击者在客户端与目标主机之间伪造一个"代理",冒充目标主机与客户端通信,试图窃取用户的登录凭证(如用户名、密码)或传输的敏感数据。此时,客户端接收到的是攻击者的密钥,而非真实目标主机的密钥,因此触发校验失败。

四、解决方案:分步操作,先验证再解决

解决问题的核心逻辑是:先验证远程主机的真实性,排除攻击风险;再清除本地旧密钥,重新建立合法的密钥关联。以下是详细步骤:

步骤1:验证远程主机真实性(关键!不可跳过)

这是保障安全的核心步骤,需通过"可信渠道"确认目标主机(192.168.1.69)的当前SSH密钥是否合法:

  1. 获取可信渠道访问:直接操作目标主机(如Kali虚拟机本机登录),或通过其他已确认安全的网络连接(如直接连接目标主机所在的局域网,而非公共网络)访问。

  2. 查看远程主机当前SSH密钥指纹 :登录目标主机后,执行如下命令,查看其当前的ED25519密钥指纹(报错中明确提示是ED25519密钥,优先验证该类型):

    `# 查看ED25519密钥指纹(推荐,安全性更高)

    ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

若需验证其他类型密钥(如RSA),可执行

ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub`

  1. 比对指纹一致性 :命令执行后,会输出类似如下结果:
    256 SHA256:m8h8XK+PhKKNRqus76T/PBSW+icLoCyPmAF9OVYO3Xg root@kali (ED25519)
    若输出的指纹(SHA256:后面的字符串)与报错中显示的指纹完全一致,则说明是正常的密钥变更,可继续后续操作;若不一致,立即停止当前操作,排查网络是否存在中间人攻击(如检查路由器设备、断开公共网络连接等)。

步骤2:清除本地旧的无效密钥

报错信息中已明确指出无效密钥的位置:Offending ED25519 key in /Users/liuxiaowei/.ssh/known_hosts:29,即known_hosts文件的第29行是与目标主机不匹配的旧密钥。可通过两种方式清除:

方式1:精准删除(推荐,不影响其他主机记录)

直接删除known_hosts文件中指定行的旧密钥,适合熟悉命令行的用户:

  • macOS系统 :sed命令需添加-i ''参数(表示原地编辑,不生成备份文件):
    sed -i '' '29d' /Users/liuxiaowei/.ssh/known_hosts

  • Linux系统 :sed命令直接使用-i参数:
    sed -i '29d' /home/用户名/.ssh/known_hosts

  • 通用方式(自动匹配IP删除) :若不确定行号,可使用ssh-keygen -R命令,自动删除指定IP的所有密钥记录(推荐新手使用):
    ssh-keygen -R 192.168.1.69

    执行后会提示"Host 192.168.1.69 found: line 29",并自动删除该行记录。

方式2:手动编辑文件(适合新手)

通过文本编辑器打开known_hosts文件,手动删除无效行:

  1. 打开文件:

    • macOS:执行open /Users/liuxiaowei/.ssh/known_hosts,用文本编辑打开;

    • Linux:执行vim /home/用户名/.ssh/known_hosts,或使用图形化文本编辑器(如gedit);

    • Windows(WSL或Git Bash):执行notepad ~/.ssh/known_hosts

  2. 找到包含"192.168.1.69"的行(报错提示第29行),删除该行内容;

  3. 保存文件并关闭。

步骤3:重新执行SSH/SCP命令,建立新的密钥关联

清除旧密钥后,重新执行最初的SCP命令(或SSH登录命令):

bash 复制代码
scp Cwebscanner-master.zip kali@192.168.1.69:/home/kali/Downloads

此时客户端会提示确认新的主机密钥,类似如下信息:

bash 复制代码
The authenticity of host '192.168.1.69 (192.168.1.69)' can't be established.
ED25519 key fingerprint is SHA256:m8h8XK+PhKKNRqus76T/PBSW+icLoCyPmAF9OVYO3Xg.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

输入"yes"后,客户端会将新的密钥指纹写入known_hosts文件,后续连接即可正常建立,文件传输顺利完成。

五、常见问题排查:解决操作中的小插曲

在执行上述步骤时,可能会遇到以下问题,可针对性解决:

1. 执行sed命令报错"invalid command code ."(macOS)

原因:macOS的sed命令与Linux不同,缺少-i ''参数会导致报错。解决方案:严格按照步骤2中macOS的命令格式执行,即添加-i ''

2. 清除旧密钥后,重新连接仍报错

排查方向:

  • 是否清除了正确的IP/行号?可重新执行ssh-keygen -R 192.168.1.69确认;

  • 远程主机是否再次变更了密钥?重新验证远程主机的密钥指纹;

  • 是否存在多个known_hosts文件?检查当前登录用户是否正确(如root用户与普通用户的known_hosts文件路径不同)。

3. 无法直接操作远程主机,无法验证密钥指纹

解决方案:通过其他可信方式联系远程主机管理员,获取当前的密钥指纹;或暂时断开公共网络,连接到目标主机所在的私有局域网后再验证,避免在不可信网络中盲目操作。

六、安全最佳实践:规避后续同类问题

为减少"Host key verification failed"报错的发生,同时提升SSH通信的安全性,建议遵循以下最佳实践:

1. 给远程主机配置静态IP

若远程主机(如虚拟机、服务器)使用DHCP自动获取IP,建议手动配置静态IP,避免IP被重新分配给其他设备,导致密钥不匹配。

2. 记录可信主机的密钥指纹

首次连接远程主机时,将其密钥指纹记录在安全的地方(如本地加密文档),后续出现报错时,可快速比对验证,无需重复操作远程主机。

3. 禁用弱密钥算法,使用强密钥

远程主机端可配置SSH服务,禁用RSA(小于2048位)等弱密钥算法,仅启用ED25519、ECDSA等强密钥算法,提升安全性:

bash 复制代码
# 编辑SSH配置文件
vim /etc/ssh/sshd_config

# 添加如下配置,禁用弱算法
HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ecdsa-sha2-nistp256-cert-v01@openssh.com
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp256

# 重启SSH服务生效
systemctl restart sshd

4. 避免临时关闭严格密钥检查(不推荐)

部分用户为图方便,会在SSH/SCP命令中添加-o StrictHostKeyChecking=no参数,临时跳过密钥验证:

bash 复制代码
scp -o StrictHostKeyChecking=no Cwebscanner-master.zip kali@192.168.1.69:/home/kali/Downloads

该方式仅适用于本地测试环境(如虚拟机频繁重装),绝对禁止在生产环境或公共网络中使用,会直接暴露在中间人攻击风险中。

5. 定期更新SSH密钥

为提升安全性,建议定期(如每6个月)在远程主机端重置SSH密钥,并同步更新本地known_hosts文件中的记录。

七、总结

"Host key verification failed"报错并非故障,而是SSH协议的安全防护机制在生效。解决问题的关键是"先验证,再清除"------先通过可信渠道确认远程主机的真实性,排除中间人攻击风险,再清除本地的旧密钥记录,重新建立合法的密钥关联。

在实际操作中,切勿为了快速解决问题而跳过安全验证步骤;同时,通过配置静态IP、记录密钥指纹、使用强密钥算法等最佳实践,可有效减少同类报错的发生,保障远程通信的安全性。

相关推荐
七夜zippoe8 小时前
CANN Runtime任务描述序列化与持久化源码深度解码
大数据·运维·服务器·cann
盟接之桥8 小时前
盟接之桥说制造:引流品 × 利润品,全球电商平台高效产品组合策略(供讨论)
大数据·linux·服务器·网络·人工智能·制造
会员源码网8 小时前
理财源码开发:单语言深耕还是多语言融合?看完这篇不踩坑
网络·个人开发
米羊1219 小时前
已有安全措施确认(上)
大数据·网络
Fcy6489 小时前
Linux下 进程(一)(冯诺依曼体系、操作系统、进程基本概念与基本操作)
linux·运维·服务器·进程
袁袁袁袁满9 小时前
Linux怎么查看最新下载的文件
linux·运维·服务器
代码游侠10 小时前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
Harvey90310 小时前
通过 Helm 部署 Nginx 应用的完整标准化步骤
linux·运维·nginx·k8s
ManThink Technology10 小时前
如何使用EBHelper 简化EdgeBus的代码编写?
java·前端·网络
珠海西格电力科技11 小时前
微电网能量平衡理论的实现条件在不同场景下有哪些差异?
运维·服务器·网络·人工智能·云计算·智慧城市