Python Paramiko SFTP场景下如何捕获主机/用户名错误异常
问题原因分析
BadHostKeyException捕获不生效的原因:该异常仅在本地存储的远程主机公钥与当前连接返回的公钥不匹配时触发,和主机地址错误、用户名错误场景无关,因此无法捕获你当前遇到的报错。- 你当前收到的
socket.gaierror: [Errno -2] Name or service not known是主机地址填写错误、无法被DNS/本地hosts解析时触发的系统级网络异常。 - 用户名错误/SSH密钥认证失败的场景,Paramiko会抛出专属的
paramiko.AuthenticationException异常。
精准捕获的实现方案
如果觉得直接捕获socket.gaierror范围太宽,可以通过判断异常错误码的方式,仅匹配主机解析失败的场景,同时补充认证失败的异常捕获即可区分两类错误,修改后的代码示例如下:
import socket import paramiko def connSFTP(config,logger_info,logger_error,resetConnSFTP,logger_error_mail,reset): try: k = paramiko.RSAKey.from_private_key_file(config.ssh_key_filepath) c = paramiko.SSHClient() c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) c.connect( hostname = config.host, username = config.username, pkey = k ) sftp = c.open_sftp() logger_info.info('Connected with '+ config.host) return sftp # 主机地址解析错误捕获 except socket.gaierror as err: # Errno -2 对应Name or service not known,仅匹配主机填写错误场景 if err.args[0] == -2: print(f'主机地址填写错误,无法解析:{str(err)}') else: # 其他类型的gaierror可按需处理或向上抛出 raise # 用户名/密钥认证错误捕获 except paramiko.AuthenticationException as err: print(f'用户名或SSH密钥错误,认证失败:{str(err)}') # 原有的主机密钥不匹配异常保留 except paramiko.BadHostKeyException as err: print(f'主机公钥不匹配,连接存在风险:{str(err)}') # 可按需补充其他常见连接异常 except ConnectionRefusedError: print('远程主机SSH端口未开放,连接被拒绝') except socket.timeout: print('连接超时,请检查主机地址、网络是否正常')
内容的提问来源于stack exchange,提问作者Mahmoud Abdulkarim
相关产品推荐
相关产品推荐

