jgriffo1
jgriffo1

Reputation: 103

Paramiko SFTP will not authenticate with correct username and password but GUI SFTP client success with keyboard-interactive authentication

I have some Python code that works with one SFTP host, but when I change the configuration to another SFTP host, along with the username and password, it fails to connect. You are going to have to trust me that the host, port, username and password are exactly correct and that I can connect manually from FileZilla from the same PC.

If I put a debug on the last line, I can see the following value for transport:

<paramiko.Transport at 0x88f0b400 (cipher aes128-ctr, 128 bits) (connected; awaiting auth)>

When I run to completion, it fails on the last line with a generic "EOFError", which is of course because I can't authenticate the transport.

What am I doing wrong?

import configparser
import paramiko


def main():
    config = configparser.ConfigParser()
    config.read('pullICEHistory.ini')
    sftp_config = config['ICEFTPHost']
    host = sftp_config['host']
    port = int(sftp_config['port'])
    username = sftp_config['username']
    password = sftp_config['password']
    download_path = sftp_config['download_path']
    transport = paramiko.Transport((host, port))
    transport.connect(username=username, password=password, hostkey=None)
    sftp = paramiko.SFTPClient.from_transport(transport)


if __name__ == '__main__':
    main()

Here is the Paramiko log:

DEB [20210813-08:50:54.497] thr=1   paramiko.transport: starting thread (client mode): 0x5c153df0
DEB [20210813-08:50:54.497] thr=1   paramiko.transport: Local version/idstring: SSH-2.0-paramiko_2.7.2
DEB [20210813-08:50:54.504] thr=1   paramiko.transport: Remote version/idstring: SSH-2.0-Server
INF [20210813-08:50:54.504] thr=1   paramiko.transport: Connected (version 2.0, client Server)
DEB [20210813-08:50:54.512] thr=1   paramiko.transport: kex algos:['ecdh-sha2-nistp521', 'ecdh-sha2-nistp384', 'ecdh-sha2-nistp256', 'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group-exchange-sha1', 'diffie-hellman-group18-sha512', 'diffie-hellman-group17-sha512', 'diffie-hellman-group16-sha512', 'diffie-hellman-group15-sha512', 'diffie-hellman-group14-sha256', 'diffie-hellman-group14-sha1', 'diffie-hellman-group1-sha1'] server key:['ecdsa-sha2-nistp256', 'ssh-rsa'] client encrypt:['blowfish-cbc', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'arcfour256', 'arcfour128', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] server encrypt:['blowfish-cbc', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'arcfour256', 'arcfour128', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] client mac:['hmac-md5', 'hmac-sha1', 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1-96', 'hmac-md5-96'] server mac:['hmac-md5', 'hmac-sha1', 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1-96', 'hmac-md5-96'] client compress:['none'] server compress:['none'] client lang:[''] server lang:[''] kex follows?False
DEB [20210813-08:50:54.513] thr=1   paramiko.transport: Kex agreed: ecdh-sha2-nistp256
DEB [20210813-08:50:54.513] thr=1   paramiko.transport: HostKey agreed: ecdsa-sha2-nistp256
DEB [20210813-08:50:54.513] thr=1   paramiko.transport: Cipher agreed: aes128-ctr
DEB [20210813-08:50:54.513] thr=1   paramiko.transport: MAC agreed: hmac-sha2-256
DEB [20210813-08:50:54.513] thr=1   paramiko.transport: Compression agreed: none
DEB [20210813-08:50:54.523] thr=1   paramiko.transport: kex engine KexNistp256 specified hash_algo <built-in function openssl_sha256>
DEB [20210813-08:50:54.531] thr=1   paramiko.transport: Switch to new keys ...
DEB [20210813-08:50:54.531] thr=2   paramiko.transport: Attempting password auth...
DEB [20210813-08:50:54.539] thr=1   paramiko.transport: userauth is OK
INF [20210813-08:50:54.749] thr=1   paramiko.transport: Authentication continues...
DEB [20210813-08:50:54.749] thr=1   paramiko.transport: Methods: ['keyboard-interactive']
DEB [20210813-08:50:54.750] thr=2   paramiko.transport: [chan 0] Max packet in: 32768 bytes
DEB [20210813-08:50:54.758] thr=1   paramiko.transport: EOF in transport thread

Here is the verbose log from FileZilla with the hostname and username redacted:

Trace:  CControlSocket::SendNextCommand()
Trace:  CSftpConnectOpData::Send() in state 0
Status: Connecting to sftp.icedatavault.icedataservices.com...
Trace:  Going to execute C:\Program Files\FileZilla FTP Client\fzsftp.exe
Response:   fzSftp started, protocol_version=11
Trace:  CSftpConnectOpData::ParseResponse() in state 0
Trace:  CControlSocket::SendNextCommand()
Trace:  CSftpConnectOpData::Send() in state 3
Command:    open "***@***.com" 22
Trace:  Looking up host "sftp.***.com" for SSH connection
Trace:  Connecting to ***.***.***.*** port 22
Trace:  We claim version: SSH-2.0-FileZilla_3.55.0
Trace:  Connected to ***.***.***.***
Trace:  Remote version: SSH-2.0-Server
Trace:  Using SSH protocol version 2
Trace:  Doing ECDH key exchange with curve nistp256 and hash SHA-256 (unaccelerated)
Trace:  Server also has ssh-rsa host key, but we don't know it
Trace:  Host key fingerprint is:
Trace:  ecdsa-sha2-nistp256 256 SHA256:1ZH9bMfa6PSeIJBAvO4wg3SIiTizufzlB/z7b4qeQfA
Trace:  Initialised AES-256 SDCTR (AES-NI accelerated) outbound encryption
Trace:  Initialised HMAC-SHA-256 (unaccelerated) outbound MAC algorithm
Trace:  Initialised AES-256 SDCTR (AES-NI accelerated) inbound encryption
Trace:  Initialised HMAC-SHA-256 (unaccelerated) inbound MAC algorithm
Status: Using username "***". 
Trace:  Attempting keyboard-interactive authentication
Command:    Pass: ********
Trace:  Access granted
Trace:  Opening main session channel
Trace:  Opened main channel
Trace:  Started a shell/command
Status: Connected to sftp-consumer.***.com
Trace:  Remote working directory is /
Trace:  CSftpConnectOpData::ParseResponse() in state 3
Trace:  CControlSocket::ResetOperation(0)
Trace:  CSftpConnectOpData::Reset(0) in state 3
Trace:  CControlSocket::SendNextCommand()
Trace:  CSftpListOpData::Send() in state 0
Status: Retrieving directory listing...
Trace:  CSftpChangeDirOpData::Send() in state 0
Trace:  CSftpChangeDirOpData::Send() in state 1
Command:    pwd
Response:   Current directory is: "/"
Trace:  CSftpChangeDirOpData::ParseResponse() in state 1
Trace:  CControlSocket::ResetOperation(0)
Trace:  CSftpChangeDirOpData::Reset(0) in state 1
Trace:  CSftpListOpData::SubcommandResult(0) in state 1
Trace:  CControlSocket::SendNextCommand()
Trace:  CSftpListOpData::Send() in state 2
Trace:  CControlSocket::ResetOperation(0)
Trace:  CSftpListOpData::Reset(0) in state 2
Status: Directory listing of "/" successful

Edit: Here are the Paramiko logs when using SSHClient():

DEB [20210813-10:48:43.523] thr=1   paramiko.transport: starting thread (client mode): 0x6917bd90
DEB [20210813-10:48:43.524] thr=1   paramiko.transport: Local version/idstring: SSH-2.0-paramiko_2.7.2
DEB [20210813-10:48:43.532] thr=1   paramiko.transport: Remote version/idstring: SSH-2.0-Server
INF [20210813-10:48:43.532] thr=1   paramiko.transport: Connected (version 2.0, client Server)
DEB [20210813-10:48:43.540] thr=1   paramiko.transport: kex algos:['ecdh-sha2-nistp521', 'ecdh-sha2-nistp384', 'ecdh-sha2-nistp256', 'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group-exchange-sha1', 'diffie-hellman-group18-sha512', 'diffie-hellman-group17-sha512', 'diffie-hellman-group16-sha512', 'diffie-hellman-group15-sha512', 'diffie-hellman-group14-sha256', 'diffie-hellman-group14-sha1', 'diffie-hellman-group1-sha1'] server key:['ecdsa-sha2-nistp256', 'ssh-rsa'] client encrypt:['blowfish-cbc', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'arcfour256', 'arcfour128', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] server encrypt:['blowfish-cbc', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'arcfour256', 'arcfour128', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] client mac:['hmac-md5', 'hmac-sha1', 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1-96', 'hmac-md5-96'] server mac:['hmac-md5', 'hmac-sha1', 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1-96', 'hmac-md5-96'] client compress:['none'] server compress:['none'] client lang:[''] server lang:[''] kex follows?False
DEB [20210813-10:48:43.541] thr=1   paramiko.transport: Kex agreed: ecdh-sha2-nistp256
DEB [20210813-10:48:43.541] thr=1   paramiko.transport: HostKey agreed: ecdsa-sha2-nistp256
DEB [20210813-10:48:43.541] thr=1   paramiko.transport: Cipher agreed: aes128-ctr
DEB [20210813-10:48:43.541] thr=1   paramiko.transport: MAC agreed: hmac-sha2-256
DEB [20210813-10:48:43.541] thr=1   paramiko.transport: Compression agreed: none
DEB [20210813-10:48:43.554] thr=1   paramiko.transport: kex engine KexNistp256 specified hash_algo <built-in function openssl_sha256>
DEB [20210813-10:48:43.562] thr=1   paramiko.transport: Switch to new keys ...
DEB [20210813-10:48:43.563] thr=2   paramiko.transport: Adding ecdsa-sha2-nistp256 host key for sftp.icedatavault.icedataservices.com: b'a01d678327cf500d704d970aacf24049'
DEB [20210813-10:48:43.580] thr=1   paramiko.transport: userauth is OK
INF [20210813-10:48:43.926] thr=1   paramiko.transport: Authentication continues...
DEB [20210813-10:48:43.926] thr=1   paramiko.transport: Methods: ['keyboard-interactive']
DEB [20210813-10:48:43.937] thr=3   paramiko.transport: starting thread (client mode): 0x6917bd00
DEB [20210813-10:48:43.938] thr=3   paramiko.transport: Local version/idstring: SSH-2.0-paramiko_2.7.2
DEB [20210813-10:48:43.945] thr=3   paramiko.transport: Remote version/idstring: SSH-2.0-Server
INF [20210813-10:48:43.945] thr=3   paramiko.transport: Connected (version 2.0, client Server)
DEB [20210813-10:48:43.954] thr=3   paramiko.transport: kex algos:['ecdh-sha2-nistp521', 'ecdh-sha2-nistp384', 'ecdh-sha2-nistp256', 'diffie-hellman-group-exchange-sha256', 'diffie-hellman-group-exchange-sha1', 'diffie-hellman-group18-sha512', 'diffie-hellman-group17-sha512', 'diffie-hellman-group16-sha512', 'diffie-hellman-group15-sha512', 'diffie-hellman-group14-sha256', 'diffie-hellman-group14-sha1', 'diffie-hellman-group1-sha1'] server key:['ecdsa-sha2-nistp256', 'ssh-rsa'] client encrypt:['blowfish-cbc', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'arcfour256', 'arcfour128', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] server encrypt:['blowfish-cbc', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr', 'arcfour256', 'arcfour128', 'aes128-cbc', '3des-cbc', 'aes192-cbc', 'aes256-cbc'] client mac:['hmac-md5', 'hmac-sha1', 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1-96', 'hmac-md5-96'] server mac:['hmac-md5', 'hmac-sha1', 'hmac-sha2-256', 'hmac-sha2-512', 'hmac-sha1-96', 'hmac-md5-96'] client compress:['none'] server compress:['none'] client lang:[''] server lang:[''] kex follows?False
DEB [20210813-10:48:43.954] thr=3   paramiko.transport: Kex agreed: ecdh-sha2-nistp256
DEB [20210813-10:48:43.954] thr=3   paramiko.transport: HostKey agreed: ecdsa-sha2-nistp256
DEB [20210813-10:48:43.954] thr=3   paramiko.transport: Cipher agreed: aes128-ctr
DEB [20210813-10:48:43.954] thr=3   paramiko.transport: MAC agreed: hmac-sha2-256
DEB [20210813-10:48:43.954] thr=3   paramiko.transport: Compression agreed: none
DEB [20210813-10:48:43.965] thr=3   paramiko.transport: kex engine KexNistp256 specified hash_algo <built-in function openssl_sha256>
DEB [20210813-10:48:43.972] thr=3   paramiko.transport: Switch to new keys ...
DEB [20210813-10:48:43.972] thr=2   paramiko.transport: Attempting password auth...
DEB [20210813-10:48:43.981] thr=3   paramiko.transport: userauth is OK
INF [20210813-10:48:44.266] thr=3   paramiko.transport: Authentication continues...
DEB [20210813-10:48:44.266] thr=3   paramiko.transport: Methods: ['keyboard-interactive']
DEB [20210813-10:48:44.267] thr=2   paramiko.transport: [chan 0] Max packet in: 32768 bytes
DEB [20210813-10:48:44.275] thr=3   paramiko.transport: EOF in transport thread
DEB [20210813-10:48:44.277] thr=1   paramiko.transport: EOF in transport thread

Upvotes: 1

Views: 2123

Answers (1)

Martin Prikryl
Martin Prikryl

Reputation: 202534

It seems that your server supports only keyboard-interactive authentication. While you are using password authentication in your Python/Paramiko code.

Try using the high-level Paramiko API, the SSHClient. It automatically uses your password for keyboard-interactive authentication.

ssh = paramiko.SSHClient()
ssh.connect(host, port=port, username=username, password=password)

Also the SSHClient correctly validates your server's host key, what the low-level Transport API does not (what is a security flaw).


It turned out that the above does not work either, as the server behaves strangely.

This workaround worked:
Paramiko/Python: Keyboard interactive authentication

Upvotes: 1

Related Questions