27

I am having a problem connecting to a device with a Paramiko (version 1.7.6-2) ssh client:

$ python
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import paramiko
>>> ssh = paramiko.SSHClient()
>>> ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
>>> ssh.connect("123.0.0.1", username="root", password=None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/pymodules/python2.6/paramiko/client.py", line 327, in connect
    self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys)
  File "/usr/lib/pymodules/python2.6/paramiko/client.py", line 481, in _auth
    raise saved_exception
paramiko.AuthenticationException: Authentication failed.
>>> 

When I use ssh from the command line, it works fine:

ssh root@123.0.0.1


BusyBox v1.12.1 (2010-11-03 13:18:46 EDT) built-in shell (ash)
Enter 'help' for a list of built-in commands.

# 

Anyone seen this before?

Edit 1

Here is the verbose output of the ssh command:

:~$ ssh -v root@123.0.0.1
OpenSSH_5.3p1 Debian-3ubuntu4, OpenSSL 0.9.8k 25 Mar 2009
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Applying options for *
debug1: Connecting to 123.0.0.1 [123.0.0.1] port 22.
debug1: Connection established.
debug1: identity file /home/waffleman/.ssh/identity type -1
debug1: identity file /home/waffleman/.ssh/id_rsa type -1
debug1: identity file /home/waffleman/.ssh/id_dsa type -1
debug1: Remote protocol version 2.0, remote software version OpenSSH_5.1
debug1: match: OpenSSH_5.1 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.3p1 Debian-3ubuntu4
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Host '123.0.0.1' is known and matches the RSA host key.
debug1: Found key in /home/waffleman/.ssh/known_hosts:3
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentication succeeded (none).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = en_US.utf8

Edit 2 Here is the python output with debug output:

Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import paramiko, os
>>> paramiko.common.logging.basicConfig(level=paramiko.common.DEBUG)
>>> ssh = paramiko.SSHClient()
>>> ssh.load_system_host_keys()
>>> ssh.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
>>> ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
>>> ssh.connect("123.0.0.1", username='root', password=None)
DEBUG:paramiko.transport:starting thread (client mode): 0x928756cL
INFO:paramiko.transport:Connected (version 2.0, client OpenSSH_5.1)
DEBUG:paramiko.transport:kex algos:['diffie-hellman-group-exchange-sha256', 'diffie-hellman-group-exchange-sha1', 'diffie-hellman-group14-sha1', 'diffie-hellman-group1-sha1'] server key:['ssh-rsa', 'ssh-dss'] client encrypt:['aes128-cbc', '3des-cbc', 'blowfish-cbc', 'cast128-cbc', 'arcfour128', 'arcfour256', 'arcfour', 'aes192-cbc', 'aes256-cbc', 'rijndael-cbc@lysator.liu.se', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr'] server encrypt:['aes128-cbc', '3des-cbc', 'blowfish-cbc', 'cast128-cbc', 'arcfour128', 'arcfour256', 'arcfour', 'aes192-cbc', 'aes256-cbc', 'rijndael-cbc@lysator.liu.se', 'aes128-ctr', 'aes192-ctr', 'aes256-ctr'] client mac:['hmac-md5', 'hmac-sha1', 'umac-64@openssh.com', 'hmac-ripemd160', 'hmac-ripemd160@openssh.com', 'hmac-sha1-96', 'hmac-md5-96'] server mac:['hmac-md5', 'hmac-sha1', 'umac-64@openssh.com', 'hmac-ripemd160', 'hmac-ripemd160@openssh.com', 'hmac-sha1-96', 'hmac-md5-96'] client compress:['none', 'zlib@openssh.com'] server compress:['none', 'zlib@openssh.com'] client lang:[''] server lang:[''] kex follows?False
DEBUG:paramiko.transport:Ciphers agreed: local=aes128-ctr, remote=aes128-ctr
DEBUG:paramiko.transport:using kex diffie-hellman-group1-sha1; server key type ssh-rsa; cipher: local aes128-ctr, remote aes128-ctr; mac: local hmac-sha1, remote hmac-sha1; compression: local none, remote none
DEBUG:paramiko.transport:Switch to new keys ...
DEBUG:paramiko.transport:Trying discovered key b945197b1de1207d9aa0663f01888c3c in /home/waffleman/.ssh/id_rsa
DEBUG:paramiko.transport:userauth is OK
INFO:paramiko.transport:Authentication (publickey) failed.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/pymodules/python2.6/paramiko/client.py", line 327, in connect
    self._auth(username, password, pkey, key_filenames, allow_agent, look_for_keys)
  File "/usr/lib/pymodules/python2.6/paramiko/client.py", line 481, in _auth
    raise saved_exception
paramiko.AuthenticationException: Authentication failed.
>>> 
tshepang
  • 12,111
  • 21
  • 91
  • 136
waffleman
  • 4,159
  • 10
  • 39
  • 63

11 Answers11

25

It's really a old and remote issue, but I just got the same error and I think It'll be helpful to list the following info:

  1. I'm using paramiko 2.9.1 and python>=3.6, make sure your paramiko>=2.9.0
  2. cmd ssh <hostname> works fine
  3. Code below get error: AuthenticationException: Authentication failed.
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
session = client.connect("<hostname>")

From here https://github.com/paramiko/paramiko/issues/1984, I know this is a bug related to auth algorithms.

You'll need to add a disabled_algorithms param in connect(), see docs here: https://www.paramiko.org/changelog.html#2.9.0

But the changelog of 2.9.0 has a typo for disabled_algorithms, it should be:

client.connect("<hostname>", disabled_algorithms={'pubkeys': ['rsa-sha2-256', 'rsa-sha2-512']})

instead of:

client.connect("<hostname>", disabled_algorithms={'keys': ['rsa-sha2-256', 'rsa-sha2-512']})

Finally, all goes well.

Ps: Just got error Unable to agree on a pubkey algorithm for signing a 'ssh-rsa' key! for other hosts, may be downgrade paramiko below 2.9.0 is a better way.

realcp1018
  • 399
  • 1
  • 3
  • 9
  • Thanks so much! I've been pulling my hair out trying to figure out why my Paramiko code works on Linux but not on my Mac. Adding the 'disabled_algorithms' value you give above solved the problem for me. Whew...I'd been through tones of googles. Glad I happened upon this one before I gave up. – CryptoFool Aug 30 '22 at 14:26
  • Plus one - disabled_algorithms fixed my problem!! – user Aug 03 '23 at 00:24
11

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') 
jww
  • 97,681
  • 90
  • 411
  • 885
JimB
  • 104,193
  • 13
  • 262
  • 255
  • Hi @waffleman , I was also gating same problem .. so I put transport.auth_none('root') line in code but now getting error as .. NameError: name 'transport' is not defined – Sachin Doiphode Oct 25 '11 at 18:02
  • @Spike: Did you declare transport? transport = ssh.get_transport() – waffleman Nov 16 '11 at 19:41
  • @JimB- nice catch. My host was allowing me in from the command line with no password, even when I used `ssh -i $HOME/.ssh/id_rsa command`, but it was only when I noticed that I wasn't actually using the keys that I was able to fix the problem. `ssh -v` said, `debug1: Authentication succeeded (gssapi-with-mic).` (this is AD, I believe). I copied my authorized_keys file to the host and paramiko works. – Mike S Apr 23 '15 at 16:08
6

As a very late follow-up on this matter, I believe I was running into the same issue as waffleman, in a context of a confined network.

The hint about using auth_none on the Transport object turned out quite helpful, but I found myself a little puzzled as to how to implement that. Thing is, as of today at least, I can't get the Transport object of an SSHClient object until it has connected; but it won't connect in the first place...

So In case this is useful to others, my work around is below. I just override the _auth method.

OK, this is fragile, as _auth is a private thing. My other alternatives were - actually still are - to manually create the Transport and Channel objects, but for the time being I feel like I'm much better off with all this still under the hood.

from paramiko import SSHClient, BadAuthenticationType

class SSHClient_try_noauth(SSHClient):

    def _auth(self, username, *args):
        try:
            self._transport.auth_none(username)
        except BadAuthenticationType:
            super()._auth(username, *args)
frans
  • 8,868
  • 11
  • 58
  • 132
user5417363
  • 91
  • 2
  • 5
3

Make sure that the permissions on the public and private key files (and possibly the containing folder) are set to very restrictive (i.e. chmod 600 id_rsa). It turns out this is required (by the Operating System?) to use the files as ssh keys. Found this out from my helpful colleague :) Also make sure that you are using the correct username for the given ssh key.

1

There could be different reasons on server side (sshd where you're connecting to), so it might be hard to debug on client side.

For example, tail -f /var/log/secure :

Oct 9 15:50:26 pc1udatahgw04 sshd[27501]: Authentication refused: bad ownership or modes for directory /home/testuser

If you run ls -lad /home/testuser to see permissions, you'll see for example in our case:

$ ls -lad /home/testuser
drwxrwxr-x 16 testuser  testgroup 57344 Oct  9 15:23 /home/testuser

Notice second w bit. Home directory was opened up for group writes. sshd refuses key based authentication in this case.

Again, check sshd log on server side. There could be other issues like already mentioned

  • /home/user/.ssh directory is too open
  • /home/user/.ssh/id_rsa file is too open
  • /home/user/.ssh/id_rsa.pub file is too open
  • /home/user/.ssh/id_ecdsa file is too open
  • /home/user/.ssh/id_ecdsa.pub file is too open

etc..

Tagar
  • 13,911
  • 6
  • 95
  • 110
1

I got this error :

paramiko.ssh_exception.AuthenticationException: Authentication failed: transport shut down or saw EOF

but solve when I add this parameter look_for_keys=False

ssh.connect(hostname='hostname',port=port,username='user',password='password',look_for_keys=False)

awanpro
  • 11
  • 1
0

paramiko's SSHClient has load_system_host_keys method which you could use to load user specific set of keys. As example in the docs explain, it needs to be run before connecting to a server.

SilentGhost
  • 307,395
  • 66
  • 306
  • 293
0

venv installation also makes global files

Installing paramiko in a venv installs files both in the venv and in the global environment. Using paramiko in that venv only does not seem to work.

In codium / vscode, be in a folder that has no access to the venv and then use paramiko in the base environment. If you uninstall it from the venv, the base environment does not run paramiko anymore.

From all of this it seems best to install paramiko only in the base environment so that it is available for any venv as well.

Details

installation in the venv leads to global files as well

In my case, this error only popped up when I was in a virtual environment (venv) or when I was in a folder that contained a venv as well, but with Python interpreter of the base environment activated:

>>> ssh.connect(host, port=port, username=user, key_filename=key_filepath)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/MY_USER/Documents/MY_PROJECT/MY_VENV/lib/python3.8/site-packages/paramiko/client.py", line 435, in connect
    self._auth(
  File "/home/MY_USER/Documents/MY_PROJECT/MY_VENV/lib/python3.8/site-packages/paramiko/client.py", line 766, in _auth
    raise saved_exception
  File "/home/MY_USER/Documents/MY_PROJECT/MY_VENV/lib/python3.8/site-packages/paramiko/client.py", line 742, in _auth
    self._transport.auth_publickey(username, key)
  File "/home/MY_USER/Documents/MY_PROJECT/MY_VENV/lib/python3.8/site-packages/paramiko/transport.py", line 1634, in auth_publickey
    return self.auth_handler.wait_for_response(my_event)
  File "/home/MY_USER/Documents/MY_PROJECT/MY_VENV/lib/python3.8/site-packages/paramiko/auth_handler.py", line 258, in wait_for_response
    raise e
paramiko.ssh_exception.AuthenticationException: Authentication failed.

The script below worked only when I loaded whatever folder as the project folder in my code editor that did not have a venv with an installed Paramiko in it.

from os import getenv
import paramiko
from dotenv import load_dotenv

load_dotenv(MY_FULL_PATH, override=True)

ssh = paramiko.SSHClient()
# ssh.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
host = getenv("MY_HOST")
port = getenv("MY_PORT")
user = getenv("MY_USER")
key_filepath = getenv("MY_SSH_KEY_FILEPATH")
ssh.connect(host, port=port, username=user, key_filename=key_filepath)
sftp = ssh.open_sftp()
sftp.put(MY_FILEPATH1, MY_FILEPATH2)

As soon as there is a venv with installed Paramiko in the project folder, Paramiko seems to use the venv by default, and that error pops up even if you choose the base environment as the interpreter instead.

I can only guess that this is a problem that occurs when Paramiko is installed both in the base environment and in the venv, as in my case, although I installed it only in the venv.

uninstall from the base env

When I tried uninstalling it from the base environment, it did not find any files:

pip3 uninstall paramiko
Found existing installation: paramiko 2.6.0
Not uninstalling paramiko at /usr/lib/python3/dist-packages, outside environment /usr
Can't uninstall 'paramiko'. No files were found to uninstall.

Still, I find it at ./lib/python3/dist-packages/ when searching grep -lR paramiko /usr. And I have it also in two venvs. My guess is that Paramiko cannot deal with an installation in a venv since it is still successfully used when you are not in the venv. If you are in a folder with access to the venv that actually has it installed, it does not work unless you uninstall it again (tested). The venv that causes the errors is a completely new setup because I had problems installing Paramiko in another existing venv. The solution was to uninstall it from the venv, then I can use the venv and get Paramiko from the global installation, probably because the global installation is dominated by the venv installation which is then again wrongly interwined with the global installation.

uninstall from the venv

When I uninstalled it from the venv, paramiko was not found in the base environment anymore.

I also see that using Paramiko in a venv needs some extra steps if you want to run a command in a venv, perhaps that explains that Paramiko is generally a global installation? See Set up virtualenv with Paramiko SSH.

Any further ideas welcome.

questionto42
  • 7,175
  • 4
  • 57
  • 90
0

you may need to check log in server, try to excute tail -f /var/log/auth.log then you may find the reason why server refuses your connection. If server shows like this userauth_pubkey: unsupported public key algorithm: rsa-sha2-512 [preauth], then you can add transport.server_extensions = {'server-sig-algs': 'ssh-rsa'} after you initialize your transport

Mirror
  • 41
  • 2
0

Remember, RSA is deprecated in Ubuntu 22.04. you should change your algorithm to id_ed25519. Then probably you need to clean up your known_hosts and copy your public key to the remote server once again.

0

I get similar error, when the server uses AD authentication. I think this is a bug of paramiko. I have learned that I have to set ssh keys before use paramiko.

anibal
  • 9
  • 1