pythonsftpparamiko

ConnectionResetError when creating paramiko SFTP connection using SSHClient but not Transport


I have successfully used this code to connect to a few different SFTP servers:

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, port=port, username=username, password=password)
sftp = ssh.open_sftp()

However, there is one other SFTP server that when I try to use that code gives an error ConnectionResetError: [WinError 10054] An existing connection was forcibly closed by the remote host. For that server (and I think the others as well), the following code successfully connects with no error:

transport = paramiko.Transport((hostname, port))
transport.connect(username=username, password=password)
sftp = paramiko.SFTPClient.from_transport(transport)

Why might the behavior be different / how would I figure out what's causing the error? I'd like to be able to use the same code for all the SFTP servers I connect to. Should I just always use the Transport connection, or is there a way to modify the SSHClient connection to make it work in this case?


Solution

  • The problem turns out to be a bug in paramiko, that paramiko is trying to authenticate with a key from an SSH key file and is ignoring the supplied password. The workaround is to pass look_for_keys=False to the SSHClient.connect method.

    The issue and workaround are described in paramiko GitHub Issue #391.

    I figured this out by setting the loglevel to DEBUG and comparing the two ways of connecting - when using the SSHClient, I saw these lines:

    Adding ssh-rsa host key for sftp.example.com: b'examplekey'
    Trying discovered key b'someotherkey' in C:\Users\myusername/.ssh/id_ed25519
    Authentication (publickey) failed.
    

    Whereas when using the Transport, I saw this line:

    Authentication (password) successful!
    

    Interestingly, for the other SFTP servers where I didn't get this error, the logs include both of those sets of lines, suggesting it's trying public-key authentication but then still trying the password afterward, and I don't know what causes the difference.