使用Python Paramiko

时间:2019-06-27 00:38:22

标签: python ssh sftp paramiko pysftp

我正在尝试通过Python中的安全SFTP连接到服务器,但是我一直收到认证错误。我确定我有正确的详细信息,因为我可以通过WinSCP进行连接:

enter image description here

我还查看了Paramiko日志文件的输出,它说密码验证失败,但是我确定密码正确。

下面是我使用的代码,这些代码已从各种stackoverflow帖子中拼凑而成。有什么想法为什么它无法连接?

import paramiko
import pysftp
from base64 import decodebytes

host = '<my server address>'
port = 6671
user = '<my username>'
password = '<my password>'
private_key = '<location of my private key file>'
host_key_data = b"""<contains my host key data>"""
host_key = paramiko.RSAKey(data=decodebytes(host_key_data))
cnopts = pysftp.CnOpts()
cnopts.hostkeys.add(host, 'ssh-rsa', host_key)
pysftp.Connection(host, username=user, password=password, private_key=private_key, port=port, cnopts=cnopts)

日志文件的输出:

DEB [20190626-12:51:16.270] thr=4   paramiko.transport: Kex agreed: diffie-hellman-group-exchange-sha256
DEB [20190626-12:51:16.271] thr=4   paramiko.transport: HostKey agreed: ssh-rsa
DEB [20190626-12:51:16.272] thr=4   paramiko.transport: Cipher agreed: aes128-ctr
DEB [20190626-12:51:16.273] thr=4   paramiko.transport: MAC agreed: hmac-sha1
DEB [20190626-12:51:16.274] thr=4   paramiko.transport: Compression agreed: none
DEB [20190626-12:51:16.774] thr=4   paramiko.transport: Got server p (1024 bits)
DEB [20190626-12:51:17.029] thr=4   paramiko.transport: kex engine KexGexSHA256 specified hash_algo <built-in function openssl_sha256>
DEB [20190626-12:51:17.030] thr=4   paramiko.transport: Switch to new keys ...
DEB [20190626-12:51:17.032] thr=2   paramiko.transport: Host key verified (ssh-rsa)
DEB [20190626-12:51:17.032] thr=2   paramiko.transport: Attempting password auth...
DEB [20190626-12:51:17.531] thr=4   paramiko.transport: userauth is OK
INF [20190626-12:51:17.532] thr=4   paramiko.transport: Auth banner: b'FactSet File Transfer System (FTS)\n'
INF [20190626-12:51:17.767] thr=4   paramiko.transport: Authentication (password) failed.

使用WinSCP .NET程序集的VBA代码,该代码有效:

' Setup session options
Dim mySessionOptions As New SessionOptions
With mySessionOptions
    .Protocol = Protocol_Sftp
    .HostName = "<hostname>"
    .PortNumber = 6671
    .UserName = "<username>"
    .Password = "<password>"
    .SshHostKeyFingerprint = "ssh-rsa 2048 fingerprintkey"
    .SshPrivateKeyPath = "location of private key file"
End With  

1 个答案:

答案 0 :(得分:1)

  
! 2019-06-27 17:24:18.691 Authenticating with public key "factset-rsa-key-20170717" from agent
. 2019-06-27 17:24:18.756 Sending Pageant's response
! 2019-06-27 17:24:19.260 Further authentication required
. 2019-06-27 17:24:19.266 Further authentication required
. 2019-06-27 17:24:19.500 Prompt (5, SSH server: Password Authentication, Using keyboard-interactive authentication., Password: )
. 2019-06-27 17:24:19.505 Using stored password.

您正在WinSCP中使用两因素身份验证(按键和键盘交互)。

恐怕pysftp不支持两因素验证。

直接使用Paramiko,它支持多因素身份验证。 pysftp在内部使用Paramiko。

实施完整的键盘交互式身份验证可能比其他身份验证类型更为复杂。但是,由于服务器通常使用键盘交互身份验证来询问单个固定密码,因此某些SSH库为这种情况提供了快捷方式。 WinSCP .NET程序集也可以在VBA脚本中执行此操作(您指定Password,尽管WinSCP进行键盘交互式身份验证,而不是密码身份验证)。和Paramiko一样。如果您使用Paramiko SSHClient.connectpassword参数,则Paramiko将使用指定的密码来响应第一个键盘交互式身份验证提示。

ssh = paramiko.SSHClient()
# ... 
ssh.connect(host, username=user, port=port, password=password, key_filename=private_key)

您还必须验证服务器的主机密钥(与在pysftp和WinSCP中所做的相同)。
有关Paramiko解决方案,请参见Paramiko "Unknown Server"