我正在尝试使用代码而不仅仅是 GUI 和命令行工具将文件移动到 8001 端口的 SFTP 服务器中。 FileZilla、sftp CLI 在 Windows 和 Linux 中工作得很好。 但不知何故,我编写的Python代码或Java脚本代码无法连接。
paramiko - SSHException:协商失败。
当我在使用 FileZilla 初始登录期间查看 Windows 中保存公共主机密钥的
known_hosts
文件时,我看到正在为主机 [xxx.xxxxxxx.com]:8001 创建 ecdsa-sha2-nistp384 密钥。同一主机还有一个 ssh-rsa 密钥。
我尝试了各种方法来使用 Stack Overflow 进行故障排除 添加了
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
我无法访问 SFTP 服务器。他们只给了我用户名、密码、主机和端口。
我应该要求他们按照此处的建议将我的 IP 列入白名单吗?
尝试使用 SFTP 连接时出现“无法使用用户名和密码进行身份验证”
因为这类似于我能够与 FileZilla 和所有其他工具连接但不能与代码或脚本连接的情况。
但我不明白其背后的逻辑(因为我是初学者),因为我从我的电脑上使用 FileZilla 并且完全能够连接。
Paramiko 代码==>
import paramiko
from paramiko import client, sftp_client
host = "xxx.xxxxxx.com"
port = 8001
user = "xxxx"
password = "xxxxxxxx"
class SFTP:
sftp: sftp_client.SFTPClient
ssh: client.SSHClient
host: str
user: str
password: str
def __init__(self, host: str, user: str, password: str):
self.host = host
self.user = user
self.password = password
def __enter__(self) -> sftp_client.SFTPClient:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(self.host,8001, username=self.user, password=self.password)
self.ssh = ssh
sftp = ssh.open_sftp()
self.sftp = sftp
return sftp
def __exit__(self, exc, _, __) -> bool:
if exc is None:
self.sftp.close()
self.ssh.close()
return True
raise exc
with SFTP(host, user, password) as sftp:
print("Connected to SFTP")
输出:
SSHException Traceback (most recent call last)
Cell In[5], line 1
----> 1 with SFTP(host, user, password) as sftp:
2 print("Connected to SFTP")
Cell In[4], line 24, in SFTP.__enter__(self)
22 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
23 # print(ssh.load_host_keys().keys())
---> 24 ssh.connect(self.host,8001, username=self.user, password=self.password)
25 self.ssh = ssh
27 sftp = ssh.open_sftp()
File ~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\paramiko\client.py:451, in SSHClient.connect(self, hostname, port, username, password, pkey, key_filename, timeout, allow_agent, look_for_keys, compress, sock, gss_auth, gss_kex, gss_deleg_creds, gss_host, banner_timeout, auth_timeout, channel_timeout, gss_trust_dns, passphrase, disabled_algorithms, transport_factory, auth_strategy)
448 other_types = [x for x in sec_opts.key_types if x != keytype]
449 sec_opts.key_types = [keytype] + other_types
--> 451 t.start_client(timeout=timeout)
453 # If GSS-API Key Exchange is performed we are not required to check the
454 # host key, because the host is authenticated via GSS-API / SSPI as
455 # well as our client.
456 if not self._transport.gss_kex_used:
File ~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\LocalCache\local-packages\Python310\site-packages\paramiko\transport.py:723, in Transport.start_client(self, event, timeout)
721 if e is not None:
722 raise e
...
725 timeout is not None and time.time() >= max_time
726 ):
727 break
SSHException: Negotiation failed.
我尝试了 pysftp 代码
Paramiko/pysftp 连接失败,并显示“协商失败/无效 DH 值”,但是 GUI 和 sftp 可以连接
要获得相同的协商失败,
pysftp.CnOpts
日志输出为
DEB [20230914-09:57:50.277] thr=1 paramiko.transport: starting thread (client mode): 0x10143f70
DEB [20230914-09:57:50.281] thr=1 paramiko.transport: Local version/idstring: SSH-2.0-paramiko_3.3.1
DEB [20230914-09:57:50.290] thr=1 paramiko.transport: Remote version/idstring: SSH-2.0-8.43 FlowSsh: Bitvise SSH Server (WinSSHD) 8.43
INF [20230914-09:57:50.290] thr=1 paramiko.transport: Connected (version 2.0, client 8.43)
INF [20230914-09:57:50.293] thr=1 paramiko.transport: Disconnect (code 11): Client software or version not permitted.
这来自服务器:
客户端软件或版本不允许
我们无法帮助您。您必须请求服务器管理员允许您的客户端(Paramiko)。
您当然可以使用
Transport.local_version
伪造不同的“版本字符串”(默认为 SSH-2.0-paramiko_<version>
)。