使用Python将ssh客户端与Paramiko连接到dell idrac时,键盘交互式身份验证失败

2024-10-01 13:34:29 发布

您现在位置:Python中文网/ 问答频道 /正文

因此,dell在其新idrac固件中更改了一些内容,即在您登录后需要键盘交互身份验证,而我无法再使用Paramiko登录

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

有人在论坛上发布了一段代码片段来修补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() <;0xe43670处的paramiko.传输(密码aes128 ctr,128位)(已连接;等待验证)>

这是我得到的线索

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

谢谢你的帮助

谢谢


Tags: inpyselfparamikolocallinepasswordusers
3条回答

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')

我们修改了它,它适用于旧的和新的戴尔固件

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

我有一个类似的问题:使用Paramiko尝试登录Dell iDRAC的Python代码停止使用简单的用户名/密码身份验证。我正在运行Python/Paramiko>;针对iDRAC控制器版本9的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)

相关问题 更多 >