Paramiko 认证异常问题
我在用Paramiko(版本1.7.6-2)这个ssh客户端连接一个设备时遇到了问题:
$ 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.
>>>
但是当我从命令行使用ssh时,一切都正常:
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.
#
有没有人遇到过类似的情况?
编辑 1
这是ssh命令的详细输出:
:~$ 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
编辑 2
这是带有调试信息的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, 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.
>>>
11 个回答
关于这个问题,我想我遇到了和waffleman一样的情况,主要是在一个受限的网络环境中。
关于在Transport
对象上使用auth_none
的提示对我来说很有帮助,但我对如何实现这一点有点困惑。问题是,至少到现在为止,我无法在SSHClient
对象连接之前获取它的Transport
对象,但它根本就无法连接...
所以如果这对其他人有用,我的解决方法如下。我只是重写了_auth
方法。
好吧,这个方法有点脆弱,因为_auth
是一个私有的东西。我其他的选择其实还是手动创建Transport
和Channel
对象,但目前我觉得把这些都隐藏在内部会更好。
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)
这其实是个很老的问题,但我刚遇到同样的错误,觉得把以下信息列出来会有帮助:
- 我使用的是paramiko 2.9.1和python>=3.6,确保你的paramiko版本在2.9.0及以上。
- 用命令
ssh <hostname>
可以正常工作。 - 下面的代码会报错:
AuthenticationException: Authentication failed.
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
session = client.connect("<hostname>")
根据这里的内容 https://github.com/paramiko/paramiko/issues/1984,我知道这是一个与认证算法有关的bug。
你需要在connect()中添加一个 disabled_algorithms
参数,具体可以查看这里的文档: https://www.paramiko.org/changelog.html#2.9.0
不过,2.9.0的更新日志中对disabled_algorithms有个拼写错误,应该是:
client.connect("<hostname>", disabled_algorithms={'pubkeys': ['rsa-sha2-256', 'rsa-sha2-512']})
而不是:
client.connect("<hostname>", disabled_algorithms={'keys': ['rsa-sha2-256', 'rsa-sha2-512']})
最后,一切顺利。
附注:
我在其他主机上遇到了错误 Unable to agree on a pubkey algorithm for signing a 'ssh-rsa' key!
,可能把paramiko降到2.9.0以下会是个更好的选择。
远程设备上的ssh服务器拒绝了你的身份验证。确保你使用的是正确的密钥,公钥已经放在authorized_keys
文件里,.ssh
目录的权限设置正确,authorized_keys
的权限也正确,并且设备没有其他的访问限制。如果没有服务器的日志,很难判断发生了什么问题。
[编辑] 我刚刚回顾了一下你的输出,你正在使用None
身份验证。这种方式通常是不允许的,它是用来确定服务器允许哪些身份验证方法的。你的服务器可能在使用基于主机的身份验证(或者根本没有身份验证!)。
由于auth_none()
很少被使用,所以在SSHClient
类中无法访问,你需要直接使用Transport
。
transport.auth_none('root')