【问题标题】:Paramiko AuthenticationException issueParamiko AuthenticationException 问题
【发布时间】:2011-05-07 07:43:59
【问题描述】:

我在使用 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.
>>> 

【问题讨论】:

  • 我试过这个连接到运行嵌入式 linux 的 QNAP TS-409。工作正常。
  • 我想你可以通过ssh root@123.0.0.1 来查看 ssh 是如何连接的。
  • 执行"ssh -v root@123.0.0.1" 看看SSH是使用公钥认证还是其他认证方式?
  • 看来这就是你的答案 --> stackoverflow.com/questions/14274566/…

标签: python ssh paramiko


【解决方案1】:

paramiko's SSHClient 具有 load_system_host_keys 方法,您可以使用该方法加载用户特定的密钥集。正如文档中的示例所解释的,它需要在连接到服务器之前运行。

【讨论】:

  • 不走运。我还尝试删除 known_hosts 以查看是否有任何效果。
【解决方案2】:

远程设备上的 ssh 服务器拒绝了您的身份验证。确保您使用了正确的密钥,公钥存在于authorized_keys.ssh 目录权限正确,authorized_keys 权限正确,并且设备没有任何其他访问限制。如果没有来自服务器的日志,很难说发生了什么。

[编辑] 我刚刚回顾了您的输出,您正在使用None 身份验证进行身份验证。这通常是不允许的,用于确定服务器允许哪些身份验证方法。您的服务器可能正在使用基于主机的身份验证(或根本没有!)。

由于auth_none() 很少使用,因此无法从SSHClient 类访问,因此您需要直接使用Transport

transport.auth_none('root') 

【讨论】:

  • 嗨@waffleman,我也遇到了同样的问题..所以我将transport.auth_none('root') 行放入代码中,但现在出现错误为.. NameError: name 'transport' is not defined
  • @Spike:你申报运输了吗?传输 = ssh.get_transport()
  • @JimB- 不错。我的主机允许我在没有密码的情况下从命令行进入,即使我使用了ssh -i $HOME/.ssh/id_rsa command,但只有当我注意到我实际上并没有使用密钥时,我才能解决问题。 ssh -v 说,debug1: Authentication succeeded (gssapi-with-mic).(我相信这是 AD)。我将我的 authorized_keys 文件复制到主机和 paramiko 工作。
【解决方案3】:

当服务器使用 AD 身份验证时,我收到类似的错误。我认为这是 paramiko 的错误。我了解到我必须在使用 paramiko 之前设置 ssh 密钥。

【讨论】:

    【解决方案4】:

    确保对公钥和私钥文件(以及可能包含的文件夹)的权限设置为非常严格(即 chmod 600 id_rsa)。事实证明这是(操作系统要求的?)将文件用作 ssh 密钥。从我乐于助人的同事那里找到了这个:) 还要确保为给定的 ssh 密钥使用正确的用户名。

    【讨论】:

      【解决方案5】:

      作为对此事的非常晚的后续行动,我相信我在受限网络的情况下遇到了与 waffleman 相同的问题。

      关于在Transport 对象上使用auth_none 的提示非常有用,但我发现自己对如何实现它感到有些困惑。问题是,至少在今天,我无法获得 Transport 对象的 SSHClient 对象,直到它已连接;但它一开始就无法连接...

      因此,如果这对其他人有用,我的解决方法如下。我只是覆盖了_auth 方法。

      好的,这很脆弱,因为_auth 是私人的东西。我的其他选择是 - 实际上仍然是 - 手动创建 TransportChannel 对象,但目前我觉得这一切仍然在引擎盖下我感觉好多了。

      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)
      

      【讨论】:

        【解决方案6】:

        服务器端(你连接的sshd)可能有不同的原因,所以在客户端可能很难调试。

        例如,tail -f /var/log/secure

        10 月 9 日 15:50:26 pc1udatahgw04 sshd[27501]:身份验证被拒绝:错误 目录 /home/testuser 的所有权或模式

        如果你运行ls -lad /home/testuser 来查看权限,你会看到例如我们的例子:

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

        注意第二个w 位。为组写入打开了主目录。 sshd 在这种情况下拒绝基于密钥的身份验证。

        再次检查 server 端的 sshd 日志。可能还有其他问题,例如已经提到的

        • /home/user/.ssh 目录太开放了
        • /home/user/.ssh/id_rsa 文件太开放了
        • /home/user/.ssh/id_rsa.pub 文件太开放了
        • /home/user/.ssh/id_ecdsa 文件太开放了
        • /home/user/.ssh/id_ecdsa.pub 文件太开放了

        等等。

        【讨论】:

          【解决方案7】:

          venv 安装也会生成全局文件

          在 venv 中安装 paramiko 会在 venv 和全局环境中安装文件。仅在该 venv 中使用 paramiko 似乎不起作用。

          在 codium / vscode 中,位于无法访问 venv 的文件夹中,然后在基础环境中使用 paramiko。如果你从 venv 卸载它,基础环境不再运行 paramiko。

          从这一切看来,最好在基础环境中安装 paramiko,以便它也可用于任何 venv。

          详情

          在 venv 中安装也会导致全局文件

          在我的情况下,仅当我在虚拟环境 (venv) 中或在包含 venv 的文件夹中时才会弹出此错误,但基础环境的 Python 解释器已激活:

          >>> 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.
          

          只有当我在我的代码编辑器中加载任何文件夹作为项目文件夹时,下面的脚本才有效,该文件夹中没有安装 Paramiko 的 venv。

          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)
          

          只要项目文件夹中有一个安装了 Paramiko 的 venv,Paramiko 似乎默认使用 venv,并且弹出该错误 即使您选择基本环境作为解释器 .

          我只能猜测这是在基础环境和 venv 中都安装 Paramiko 时出现的问题,就像我的情况一样,尽管我在 venv 中仅安装了它

          从基础环境中卸载

          当我尝试从基础环境中卸载它时,它没有找到任何文件:

          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.
          

          不过,我在搜索 grep -lR paramiko /usr 时在 ./lib/python3/dist-packages/ 找到它。我也有两个 venvs。我的猜测是 Paramiko 无法处理 venv 中的安装,因为当您不在 venv 中时它仍然可以成功使用。如果您位于可以访问实际安装了它的 venv 的文件夹中,除非您再次卸载它(经过测试),否则它不起作用。导致错误的 venv 是一个全新的设置,因为我在另一个现有的 venv 中安装 Paramiko 时遇到了问题。解决方案是从 venv 卸载它,然后我可以使用 venv 并从全局安装中获取 Paramiko,可能是因为全局安装由 venv 安装主导,然后再次错误地与全局安装交织在一起。

          从 venv 卸载

          当我从 venv 卸载它时,在基础环境中找不到 paramiko。

          我还看到,如果您想在 venv 中运行命令,在 venv 中使用 Paramiko 需要一些额外的步骤,也许这解释了 Paramiko 通常是全局安装?见Set up virtualenv with Paramiko SSH

          欢迎任何进一步的想法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-05-23
            • 1970-01-01
            • 2021-05-13
            • 2017-03-26
            • 2014-12-26
            相关资源
            最近更新 更多