Password authentication in Python Paramiko fails, but same credentials work in SSH/SFTP client
Your server is using a keyboard-interactive authentication, not a simple password authentication.
Normally Paramiko is smart enough to fallback to the keyboard-interactive authentication, when the password authentication fails and the keyboard-interactive prompt has one field only (likely a password).
The problem is that your server behaves, as if the password authentication succeeded.
You can explicitly make Paramiko try the keyboard-interactive authentication using this code:
def handler(title, instructions, fields):
if len(fields) > 1:
raise SSHException("Expecting one field only.")
return [password]
transport = paramiko.Transport('example.com')
transport.connect(username='myuser')
transport.auth_interactive(username, handler)
Paramiko SFTP will not authenticate with correct username and password but GUI SFTP client success with keyboard-interactive authentication
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
Connect with Python Paramiko to SSH server that in addition to password prompt requires submitting an keyboard interactive banner with Enter key
Your server seems to issue two keyboard-interactive authentication challenges
- First, a prompt for a password
- Second, a banner with no prompts.
So you will have to do something like this:
def handler(title, instructions, fields):
if len(fields) == 1:
return [password]
else:
return []
transport = paramiko.Transport('example.com')
transport.connect(username='myuser')
transport.auth_password(username, password)
transport.auth_interactive(username, handler)
Some references:
- Paramiko/Python: Keyboard interactive authentication
- SSH with 2FA in Python Using Paramiko
- Multi-factor authentication (password and key) with Paramiko
Further, as you have find out, you need to escape the \
in the username.
Passwordless SSH connection with Paramiko fails where as with SSH works
Your ssh
connection works, because it uses a private key from ~/.ssh/id_rsa_c2c
(as configured in ssh_config
). The .ssh
folder and ssh_config
file serve as a configuration for OpenSSH toolset (ssh
in this case). You cannot expect that other SSH clients/libraries will use OpenSSH configuration files. They won't, in general.
If you want to use public key authentication with Paramiko, use key_filename
argument of SSHClient.connect
.
See also How to ssh connect through python Paramiko with ppk public key.
Though Paramiko, in particular, would use a key file, if it had a common name like id_rsa
, id_dsa
, etc. See Force password authentication (ignore keys in .ssh folder) in Paramiko in Python for exactly opposite problem.
Obligatory warning: Do not use AutoAddPolicy
, unless you do not care about security. You are losing a protection against MITM attacks this way.
For a correct solution, see Paramiko "Unknown Server".
Paramiko AuthenticationException issue
The ssh server on the remote device denied your authentication. Make sure you're using the correct key, the public key is present in authorized_keys
, .ssh
directory permissions are correct, authorized_keys
permissions are correct, and the device doesn't have any other access restrictions. It hard to say what's going on without logs from the server.
[EDIT] I just looked back through your output, you are authenticating using None
authentication. This usually isn't ever permitted, and is used to determine what auth methods are allowed by the server. It's possible your server is using host based authentication (or none at all!).
Since auth_none()
is rarely used, it's not accessible from the SSHClient
class, so you will need to use Transport
directly.
transport.auth_none('root')
Related Topics
Python Library 'Unittest': Generate Multiple Tests Programmatically
How Is Tuple Implemented in Cpython
Safe Way to Parse User-Supplied Mathematical Formula in Python
Can a Decorator of an Instance Method Access the Class
Is There a Multi-Dimensional Version of Arange/Linspace in Numpy
How to Split/Partition a Dataset into Training and Test Datasets For, E.G., Cross Validation
Output Pyodbc Cursor Results as Python Dictionary
How to Run Python Script on Terminal
How to Force/Ensure Class Attributes Are a Specific Type
Best Way to Parse a Url Query String
Finding Moving Average from Data Points in Python
Iterate Over Individual Bytes in Python 3
How to Straighten a Rotated Rectangle Area of an Image Using Opencv in Python