Двухфакторная (клавиатурная и клавиатурно-интерактивная) аутентификация на SFTP-сервере с использованием Python Paramiko - PullRequest
1 голос
/ 27 июня 2019

Я пытаюсь подключиться к серверу через безопасный SFTP в Python, но у меня продолжают появляться ошибки аутентификации.Я уверен, что у меня есть правильные данные, так как я могу подключиться через 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.

Код VBA с использованием сборки WinSCP .NET, которая работает:

' 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 Ответ

1 голос
/ 27 июня 2019
! 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 выполняет аутентификацию с помощью клавиатуры, а не парольную аутентификацию). И Парамико делает то же самое. Если вы используете аргумент password Paramiko SSHClient.connect, Paramiko ответит на первое приглашение аутентификации с интерактивной клавиатурой с указанным паролем.

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

Вам также нужно будет проверить ключ хоста сервера (так же, как вы делаете это в pysftp и WinSCP).
Для решения Paramiko см. Paramiko "Неизвестный сервер" .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...