主机密钥解决的是身份问题
SSH 登录时,客户端除了认证自己,还要反过来认证对端:服务端会给出一对主机密钥的公钥,客户端把它记在本地文件里,下次连接时比对。这个机制防的是中间人冒充——如果每次连接都无条件接受对方密钥,加密隧道就只保护了内容,没保护对象。指纹冲突提示是这套机制的正常产物,问题在于它是设备更换引起的,还是有人在中间伪装。
基本信息
| 适用对象 | OpenSSH 客户端与服务端 |
|---|---|
| 本地记录 | 用户目录下的已知主机记录文件 |
| 指纹算法 | 默认使用较短的摘要算法,部分系统仍保留旧算法 |
| 校验时机 | 每次连接前与本地记录比对 |
| 处置前提 | 先确认变更来源,再决定是否更新记录 |
指纹冲突的常见来源
- 系统重装或恢复出厂:主机密钥被重新生成,指纹自然改变
- 手工替换密钥算法:从旧算法换成更现代的算法,指纹随之变化
- 地址被复用:老设备下线后地址分配给了新设备,记录里仍留着旧指纹
- 负载均衡后端不一致:同一地址由多台后端轮转应答,指纹在多个值之间跳动
- 云主机重建:释放后重新创建实例,地址相同但密钥是新生成的
- 跳板机之后的目标变动:某一跳的设备更换,报错却指向最后一跳
核对与更新指纹
核对与更新指纹
ssh-keyscan -t ed25519 host 2>/dev/null | ssh-keygen -lf - # 取对端当前公钥指纹
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub # 在服务端本机核对(需 root)
ssh-keygen -F host # 查本地记录里该主机已保存的条目
ssh-keygen -R host # 确认变更来源后,移除旧记录再重新确认
ssh -o StrictHostKeyChecking=yes -o BatchMode=yes user@host # 自动化里强制校验,失败即报错提示与处置
| 提示 | 含义 | 处置 |
|---|---|---|
| 首次连接询问是否信任 | 本地没有记录 | 通过独立渠道核对指纹后再接受 |
| 识别信息已变更 | 本地记录与对端不符 | 先查变更来源,再移除旧记录 |
| 地址解析到多台设备 | 同一名字对应多个后端 | 改为逐台固定身份或改用签名主机密钥 |
| 自动化任务直接失败 | 严格校验下无法交互确认 | 预置可信记录或用集中签发的方案 |
核对指纹要通过独立渠道:从控制台、带外管理或配置管理系统中取得服务端的实际指纹,再与扫描结果比对。用同一条网络路径取指纹再自我比对,等于没有校验。
为了省事永久关闭严格校验,会让后续所有连接都失去身份保证,也失去发现设备被替换的唯一线索。自动化场景应当用预置记录或集中签发的方案解决,而不是关闭校验。