使用Paramiko/ssh2-sftp-client连接SFTP失败,CLI/GUI正常
SFTP连接报错:Negotiation failed 问题排查与解决
问题详情
- 用Python Paramiko、JavaScript ssh2-sftp-client连接8001端口的SFTP服务器时,触发报错
SSHException: Negotiation failed - FileZilla、Windows/Linux原生sftp命令行工具均可正常连接该服务器
- 查看Windows的known_hosts文件,目标主机
[xxx.xxxxxxx.com]:8001支持ecdsa-sha2-nistp384和ssh-rsa两种密钥算法 - 已尝试添加
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()),问题未解决 - 无服务器权限,仅持有账号、密码、主机及端口信息,曾怀疑需申请IP白名单(但同一主机的FileZilla可正常连接,排除此可能)
- pysftp调试日志显示服务器返回断开码11:
Client software or version not permitted
解决方法
从日志里的Client software or version not permitted就能看出来,服务器端限制了允许连接的客户端软件/版本,这才是核心问题,和IP白名单没关系。下面是针对不同语言的修复方案:
1. Python Paramiko 修复
Paramiko默认的客户端标识可能被服务器拦截,手动修改成FileZilla或原生sftp的标识,同时指定服务器支持的密钥算法:
import paramiko host = "xxx.xxxxxxx.com" port = 8001 username = "your-username" password = "your-password" ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 先创建Transport对象,修改客户端版本(模拟FileZilla,可抓包获取真实版本号) transport = paramiko.Transport((host, port)) transport.local_version = b"SSH-2.0-FileZilla_3.66.0" # 指定服务器支持的密钥交换和主机密钥算法 transport.set_kex_algo_list(['ecdh-sha2-nistp384', 'diffie-hellman-group-exchange-sha256']) transport.set_hostkey_algo_list(['ecdsa-sha2-nistp384', 'ssh-rsa']) # 发起连接 transport.connect(username=username, password=password) ssh._transport = transport # 后续执行SFTP操作 sftp = ssh.open_sftp() # 示例:上传文件 sftp.put("local-file.txt", "remote-file.txt") sftp.close() ssh.close()
2. JavaScript ssh2-sftp-client 修复
同样需要修改客户端版本标识,匹配服务器允许的客户端类型:
const Client = require('ssh2-sftp-client'); const sftp = new Client(); const config = { host: 'xxx.xxxxxxx.com', port: 8001, username: 'your-username', password: 'your-password', // 模拟FileZilla的客户端版本号 clientVersion: 'SSH-2.0-FileZilla_3.66.0' }; sftp.connect(config) .then(() => { // 示例:上传文件 return sftp.put('./local-file.txt', '/remote-path/remote-file.txt'); }) .then(() => { console.log('文件上传成功'); return sftp.end(); }) .catch(err => { console.error('连接或操作失败:', err); sftp.end(); });
注意事项
- 最好抓包FileZilla的SSH握手过程,获取它真实发送的
client_version字符串,替换到代码里,成功率更高 - 如果修改版本标识后仍失败,可调整密钥算法列表,只保留服务器支持的ecdsa-sha2-nistp384和ssh-rsa
内容的提问来源于stack exchange,提问作者Dan Alex
相关产品推荐
相关产品推荐

