You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Paramiko中的BadHostKeyException异常?

解决Paramiko BadHostKeyException异常问题

问题描述

你编写了如下代码连接Linux主机执行命令,即使添加了WarningPolicy和AutoAddPolicy,仍遇到BadHostKeyException异常:

print("---CCCCCCCCCCCCC---",commands)
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.WarningPolicy)
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(ipAddress, port=22, username=sshUser, password=sshPassword)
self.logger.info("executeOnRemoteShell - Created SSH connection to " + ipAddress)
stdin, stdout, stderr = client.exec_command(commands)
result = str(stdout.readlines()[0].rstrip())

完整错误信息:

paramiko.ssh_exception.BadHostKeyException: Host key for server '45.32.23.23' does not match: got 'AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGcWA6JnHBbVIGsdC+USD2GOxWNy+R8hiiFiLse75rs1JRTWN8i3ol3yZ4OhFhQl4upZ7f5/scFzw4DqoMrhRIE=', expected 'AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJSELS2mT8SED8I7QFf5YkkvD5n4LCHUkX4ykeemwuqGHOBVHixQMBtKWF9lFuKFhKOCNsifRPK1FfkT23glapI

原因分析

  • client.load_system_host_keys()会加载本地~/.ssh/known_hosts文件中的记录,目标IP的旧密钥已存在,但和当前服务器返回的密钥不匹配。
  • AutoAddPolicy只处理首次连接、本地无该主机密钥记录的场景,无法解决已有密钥不匹配的问题。
  • 你连续两次调用set_missing_host_key_policy,后一次的AutoAddPolicy()会覆盖前一次的WarningPolicy,导致前者完全无效。

解决方法


方法一:手动更新本地密钥记录(推荐,安全)

找到本地的~/.ssh/known_hosts文件,删除包含45.32.23.23的那一行,重新运行代码后,AutoAddPolicy会自动将新主机密钥添加到文件中。

方法二:代码自动处理密钥冲突(适合自动化场景)

如果需要代码自动处理旧密钥冲突,可以先移除本地存储的旧密钥再重试连接:

print("---CCCCCCCCCCCCC---", commands)
client = paramiko.SSHClient()
# 加载系统主机密钥(不需要可注释)
client.load_system_host_keys()
# 仅设置一次缺失密钥策略
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())

try:
    client.connect(ipAddress, port=22, username=sshUser, password=sshPassword)
except paramiko.BadHostKeyException:
    # 移除本地存储的目标IP旧密钥
    host_keys = client.get_host_keys()
    if ipAddress in host_keys:
        del host_keys[ipAddress]
        host_keys.save(client._system_host_keys_path)
    # 重试连接
    client.connect(ipAddress, port=22, username=sshUser, password=sshPassword)

self.logger.info("executeOnRemoteShell - Created SSH connection to " + ipAddress)
stdin, stdout, stderr = client.exec_command(commands)
result = str(stdout.readlines()[0].rstrip())

方法三:跳过密钥验证(仅测试环境用,不安全)

测试环境下可临时跳过主机密钥验证,但生产环境绝对禁止使用:

print("---CCCCCCCCCCCCC---", commands)
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接时禁用主机密钥检查(风险极高)
client.connect(ipAddress, port=22, username=sshUser, password=sshPassword, hostkey=None)

self.logger.info("executeOnRemoteShell - Created SSH connection to " + ipAddress)
stdin, stdout, stderr = client.exec_command(commands)
result = str(stdout.readlines()[0].rstrip())

内容的提问来源于stack exchange,提问作者mac

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 22:09:55