Python Pysftp携带私钥连接SFTP服务器报认证失败问题求助
SFTP pysftp 认证失败排查方案
按优先级从高到低排查以下问题:
- 确认私钥格式转换正确
WinSCP默认使用的.ppk是Putty工具专属的私钥格式,直接修改后缀为.pem无法被pysftp的底层依赖paramiko识别,必须按标准流程转换:- 打开PuttyGen工具,加载你当前能正常在WinSCP使用的
.ppk私钥 - 点击顶部菜单栏
Conversions选项,选择Export OpenSSH key,不要选SSH.com格式的导出选项 - 保存导出的私钥文件,确认文件头为
-----BEGIN OPENSSH PRIVATE KEY-----或-----BEGIN RSA PRIVATE KEY-----才是符合要求的OpenSSH格式私钥
- 打开PuttyGen工具,加载你当前能正常在WinSCP使用的
- 修正私钥密码参数的传值错误
你给出的测试代码中,直接将账号登录密码传给了private_key_pass参数,这是最高发的错误点:password参数对应用户名的SFTP账号登录密码private_key_pass参数是私钥本身的加密密码,如果导出私钥时没有给私钥单独设置访问密码,这个参数不需要传,直接留空即可,不能直接传入账号登录密码
- 放弃使用停更的pysftp库,直接用paramiko连接
pysftp最后一次正式版本更新是2016年,已经停止维护多年,依赖的paramiko版本陈旧,存在大量新密钥格式、认证逻辑的兼容bug,直接使用paramiko编写连接代码兼容性更好,参考实现:
import paramiko hostname = "some_host" username = "user" password = "password" private_key_path = "私钥文件的绝对路径" # 如果私钥没有设置单独密码,这里赋值为None private_key_pass = None ssh = paramiko.SSHClient() # 测试环境可使用自动添加未知主机密钥策略,生产环境建议手动配置服务端主机公钥校验 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # RSA类型密钥用这行加载 private_key = paramiko.RSAKey.from_private_key_file(private_key_path, password=private_key_pass) # Ed25519类型密钥注释上面一行,改用下面这行加载 # private_key = paramiko.Ed25519Key.from_private_key_file(private_key_path, password=private_key_pass) ssh.connect(hostname=hostname, port=22, username=username, password=password, pkey=private_key) sftp = ssh.open_sftp() print("连接成功") print(sftp.listdir()) # 资源释放 sftp.close() ssh.close()
- 开启调试日志定位具体失败环节
如果调整后仍然报错,开启paramiko的DEBUG级别日志可以看到完整的认证交互流程,能明确区分是公钥校验被拒、密码错误还是认证顺序不匹配导致的失败,在代码开头添加如下配置即可输出详细日志:
import logging logging.basicConfig(level=logging.DEBUG)
- 其他常规检查项
- 私钥路径尽量传入绝对路径,不要使用相对路径,避免因脚本运行工作目录变化导致私钥读取异常
- 如果在Linux/macOS环境运行脚本,需要将私钥文件权限设置为
600,权限过宽会导致paramiko出于安全考虑拒绝读取该私钥 - 联系服务端管理员确认SFTP服务支持的认证方式,部分服务端会禁用密码认证、或者要求固定的认证顺序,老旧pysftp的默认认证顺序不符合要求时会直接被服务端拒绝
内容的提问来源于stack exchange,提问作者Vitalkaaa
相关产品推荐
相关产品推荐

