【问题标题】:Connecting ssh client with Paramiko using Python to dell idrac fails keyboard-interactive authentication使用 Python 将 ssh 客户端与 Paramiko 连接到 Dell idrac 失败键盘交互式身份验证
【发布时间】:2021-03-23 21:00:03
【问题描述】:

因此,戴尔在他们的新 iDRAC 固件中更改了一些内容,他们在您登录后需要键盘交互式身份验证,而我无法再使用 Paramiko 登录。

https://www.dell.com/community/Systems-Management-General/iDRAC8-2-70-70-70-SSH-keyboard-interactive-authentication/td-p/7427565

有人在论坛里贴了一个代码sn-p来修补Paramiko client.py 我在connect函数中添加了以下内容

if password is not None:
            try:
                self._transport.auth_password(username, password)
                return
                self._log(DEBUG, "trying password")
                allowed_types = self._transport.auth_password(username, password)
                if not allowed_types:
                    return
            except SSHException as e:
                saved_exception = e
elif two_factor:
            if 'keyboard-interactive' in allowed_types:
                try:
                    self._log(DEBUG, "trying interactive")
                    self._transport.auth_interactive_dumb(username)
                    return
                except SSHException as e:
                    saved_exception = e

但仍然出现同样的错误。这是我正在使用的 ssh 连接功能。

def connectSSH(my_file, user_name, password):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ip = str(my_file.split(',')[0]).strip()
    try:
        ssh.connect(ip, 22, user_name, password, look_for_keys=False)
        return ssh
    except:
        with open(f'{ip}.txt', 'a') as f:
            f.writelines(ip + '\t COULDN\'T CONNECT\n')

当我在空闲状态下运行它时,它会连接但显示正在等待身份验证

ssh.get_transport()

这是我得到的回溯

Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    stdin, stdout, stderr = ssh.exec_command('racadm getsysinfo')
  File "C:\Users\kevinc\AppData\Local\Programs\Python\Python38-32\lib\site-packages\paramiko\client.py", line 508, in exec_command
    chan = self._transport.open_session(timeout=timeout)
  File "C:\Users\kevinc\AppData\Local\Programs\Python\Python38-32\lib\site-packages\paramiko\transport.py", line 875, in open_session
    return self.open_channel(
  File "C:\Users\kevinc\AppData\Local\Programs\Python\Python38-32\lib\site-packages\paramiko\transport.py", line 1006, in open_channel
    raise e
  File "C:\Users\kevinc\AppData\Local\Programs\Python\Python38-32\lib\site-packages\paramiko\transport.py", line 2055, in run
    ptype, m = self.packetizer.read_message()
  File "C:\Users\kevinc\AppData\Local\Programs\Python\Python38-32\lib\site-packages\paramiko\packet.py", line 459, in read_message
    header = self.read_all(self.__block_size_in, check_rekey=True)
  File "C:\Users\kevinc\AppData\Local\Programs\Python\Python38-32\lib\site-packages\paramiko\packet.py", line 303, in read_all
    raise EOFError()
EOFError

任何帮助表示赞赏

谢谢

【问题讨论】:

    标签: python ssh paramiko


    【解决方案1】:

    nvm 我发现它不知道有一种方法可以向连接发送虚假条目,无需编辑 client.py 文件

    如果有人需要,这是我的连接方法 **编辑 注意到如果它是旧版本并且不需要进一步的身份验证,它将失败,所以我进行了检查

    def connectSSH(my_file, user_name, password):
        ip = str(my_file.split(',')[0]).strip()
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            ssh.connect(ip, 22, user_name, password)
            key_auth = str(ssh.get_transport())
            if 'awaiting auth' in key_auth:
                (ssh.get_transport()).auth_interactive_dumb(user_name)
            return ssh
        except:
            with open(f'{ip}.txt', 'a') as f:
                f.writelines(ip + '\t COULDN\'T CONNECT\n')
    

    【讨论】:

      【解决方案2】:

      我遇到了类似的问题:尝试登录 Dell iDRAC 的使用 Paramiko 的 Python 代码停止使用简单的用户名/密码身份验证。我正在针对 iDRAC 控制器版本 9 运行我的 Python/Paramiko --> iDRAC 代码,发现现在需要键盘交互式身份验证。

      下面的代码与原始发布者的代码类似,显示了使用用户名/密码身份验证登录 iDRAC 9 控制器的工作示例:

      import paramiko
      import logging
      
      logging.basicConfig(level=logging.DEBUG)
      logger = logging.getLogger('ssh_test_app')
      logging.getLogger("paramiko").setLevel(logging.DEBUG)
      
      host = '10.255.1.2'
      password = 'mypw'
      username = 'myuser'
      port = 22
      
      client = paramiko.SSHClient()
      
      client.load_system_host_keys()
      client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
      
      retval = 0
      
      cmd = 'racadm getsysinfo'
      
      try:
          client.connect(host, port=port, username=username, password=password, allow_agent=False, look_for_keys=False)
          transport = client.get_transport()
      
          if not transport.is_authenticated():
              transport.auth_interactive_dumb(username)
      
          if transport.is_authenticated():
              logger.info('transport is authenticated')
              _stdin, stdout, stderr = client.exec_command(cmd)
              res = stdout.read()
              logger.info('Command {0}:\n{1}'.format(cmd, res))
          else:
              logger.error('transport is not authenticated')
      
      except paramiko.AuthenticationException:
          logger.error('paramiko.AuthenticationException')
          retval = 1
      
      except paramiko.BadHostKeyException:
          logger.error('paramiko.BadHostKeyException')
          retval = 1
      
      except paramiko.SSHException:
          logger.error('paramiko.SSHException')
          retval = 1
      
      finally:
          transport.close()
      
      logger.info('Exiting at end of script: exit code {0}'.format(retval))
      
      exit(retval)
      

      【讨论】:

        【解决方案3】:

        我们对其进行了修改,它适用于新旧戴尔固件

        `
           from paramiko import SSHClient, WarningPolicy
           def sshConnect(hostname, username, password):
               client = SSHClient()
               client.set_missing_host_key_policy(WarningPolicy())
               client.connect(hostname=hostname, username=username, password=password)
               transport = client.get_transport()
               status = transport.is_authenticated()
               if not status:
                   client.get_transport()).auth_interactive_dumb(username)
                stdin, stdout, stderr = client.exec_command("racadm getsysinfo")
                res = stdout.read()
                return res
        `
        

        【讨论】:

        • 你修改了什么?你是怎么修改的?你的答案表明其他答案没有什么?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-09
        • 2015-06-13
        • 1970-01-01
        • 2019-06-27
        • 2020-08-15
        • 2017-12-10
        相关资源
        最近更新 更多