Paramiko 身份验证失败,显示“同意‘rsa-sha2-512’公钥算法”(以及 sshd 日志中的“不支持的公钥算法:rsa-sha2-512”)

2024-10-28 08:37:00
admin
原创
64
摘要:问题描述:我有一个在 CentOS Linux 7.7 上运行的 Python 3 应用程序,用于对远程主机执行 SSH 命令。它运行正常,但今天我在对“新”远程服务器(基于 RHEL 6.10 的服务器)执行命令时遇到了一个奇怪的错误:遇到 RSA 密钥,预期为 OPENSSH 密钥从系统 shell 执行...

问题描述:

我有一个在 CentOS Linux 7.7 上运行的 Python 3 应用程序,用于对远程主机执行 SSH 命令。它运行正常,但今天我在对“新”远程服务器(基于 RHEL 6.10 的服务器)执行命令时遇到了一个奇怪的错误:

遇到 RSA 密钥,预期为 OPENSSH 密钥

从系统 shell 执行相同的命令(当然使用相同的私钥)完全可以正常工作。

在远程服务器上,我发现/var/log/secure当使用 Python(使用 Paramiko)从源服务器建立 SSH 连接并发出命令时,sshd 会抱怨不支持的公钥算法:

userauth_pubkey:不支持的公钥算法:rsa-sha2-512

请注意,具有更高版本 RHEL/CentOS(如 7.x)的目标服务器不会遇到此问题。

看起来 Paramiko 在与远程服务器协商时选择/提供了错误的算法,而相反,SSH shell 在这个“旧”目标服务器的上下文中正确地执行了协商。如何让 Python 程序按预期工作?

Python 代码

import paramiko
import logging

ssh_user = "my_user"
ssh_keypath = "/path/to/.ssh/my_key.rsa"
server = "server.tld"

ssh_client = paramiko.SSHClient()
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
ssh_client.connect(server,port=22,username=ssh_user, key_filename=ssh_keypath)  

# SSH command
cmd = "echo TEST : $(hostname)"

stdin, stdout, stderr = ssh_client.exec_command(cmd, get_pty=True)
exit_code = stdout.channel.recv_exit_status() 

cmd_raw_output = stdout.readlines()
out = "".join(cmd_raw_output)
out_msg = out.strip()  

# Ouput (logger code omitted)
logger.debug(out_msg)

if ssh_client is not None:
    ssh_client.close()

等效的 Shell 命令

ssh -i /path/to/.ssh/my_key.rsa my_user@server.tld "echo TEST : $(hostname)"   

Paramiko 日志(调试)

DEB [YYYYmmdd-HH:MM:30.475] thr=1   paramiko.transport: starting thread (client mode): 0xf6054ac8
DEB [YYYYmmdd-HH:MM:30.476] thr=1   paramiko.transport: Local version/idstring: SSH-2.0-paramiko_2.9.1
DEB [YYYYmmdd-HH:MM:30.490] thr=1   paramiko.transport: Remote version/idstring: SSH-2.0-OpenSSH_5.3
INF [YYYYmmdd-HH:MM:30.490] thr=1   paramiko.transport: Connected (version 2.0, client OpenSSH_5.3)
DEB [YYYYmmdd-HH:MM:30.498] thr=1   paramiko.transport: === Key exchange possibilities ===
DEB [YYYYmmdd-HH:MM:30.498] thr=1   paramiko.transport: kex algos: diffie-hellman-group-exchange-sha256, diffie-hellman-group-exchange-sha1, diffie-hellman-group14-sha1, diffie-hellman-group1-sha1
DEB [YYYYmmdd-HH:MM:30.498] thr=1   paramiko.transport: server key: ssh-rsa, ssh-dss
DEB [YYYYmmdd-HH:MM:30.498] thr=1   paramiko.transport: client encrypt: aes128-ctr, aes192-ctr, aes256-ctr, arcfour256, arcfour128, aes128-cbc, 3des-cbc, blowfish-cbc, cast128-cbc, aes192-cbc, aes256-cbc, arcfour, rijndael-cbc@lysator.liu.se
DEB [YYYYmmdd-HH:MM:30.498] thr=1   paramiko.transport: server encrypt: aes128-ctr, aes192-ctr, aes256-ctr, arcfour256, arcfour128, aes128-cbc, 3des-cbc, blowfish-cbc, cast128-cbc, aes192-cbc, aes256-cbc, arcfour, rijndael-cbc@lysator.liu.se
DEB [YYYYmmdd-HH:MM:30.499] thr=1   paramiko.transport: client mac: hmac-md5, hmac-sha1, umac-64@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-ripemd160, hmac-ripemd160@openssh.com, hmac-sha1-96, hmac-md5-96
DEB [YYYYmmdd-HH:MM:30.499] thr=1   paramiko.transport: server mac: hmac-md5, hmac-sha1, umac-64@openssh.com, hmac-sha2-256, hmac-sha2-512, hmac-ripemd160, hmac-ripemd160@openssh.com, hmac-sha1-96, hmac-md5-96
DEB [YYYYmmdd-HH:MM:30.499] thr=1   paramiko.transport: client compress: none, zlib@openssh.com
DEB [YYYYmmdd-HH:MM:30.499] thr=1   paramiko.transport: server compress: none, zlib@openssh.com
DEB [YYYYmmdd-HH:MM:30.499] thr=1   paramiko.transport: client lang: <none>
DEB [YYYYmmdd-HH:MM:30.499] thr=1   paramiko.transport: server lang: <none>.
DEB [YYYYmmdd-HH:MM:30.499] thr=1   paramiko.transport: kex follows: False
DEB [YYYYmmdd-HH:MM:30.500] thr=1   paramiko.transport: === Key exchange agreements ===
DEB [YYYYmmdd-HH:MM:30.500] thr=1   paramiko.transport: Kex: diffie-hellman-group-exchange-sha256
DEB [YYYYmmdd-HH:MM:30.500] thr=1   paramiko.transport: HostKey: ssh-rsa
DEB [YYYYmmdd-HH:MM:30.500] thr=1   paramiko.transport: Cipher: aes128-ctr
DEB [YYYYmmdd-HH:MM:30.500] thr=1   paramiko.transport: MAC: hmac-sha2-256
DEB [YYYYmmdd-HH:MM:30.501] thr=1   paramiko.transport: Compression: none
DEB [YYYYmmdd-HH:MM:30.501] thr=1   paramiko.transport: === End of kex handshake ===
DEB [YYYYmmdd-HH:MM:30.548] thr=1   paramiko.transport: Got server p (2048 bits)
DEB [YYYYmmdd-HH:MM:30.666] thr=1   paramiko.transport: kex engine KexGexSHA256 specified hash_algo <built-in function openssl_sha256>
DEB [YYYYmmdd-HH:MM:30.667] thr=1   paramiko.transport: Switch to new keys ...
DEB [YYYYmmdd-HH:MM:30.669] thr=2   paramiko.transport: Adding ssh-rsa host key for server.tld: b'caea********************.'
DEB [YYYYmmdd-HH:MM:30.674] thr=2   paramiko.transport: Trying discovered key b'b49c********************' in /path/to/.ssh/my_key.rsa
DEB [YYYYmmdd-HH:MM:30.722] thr=1   paramiko.transport: userauth is OK
DEB [YYYYmmdd-HH:MM:30.722] thr=1   paramiko.transport: Finalizing pubkey algorithm for key of type 'ssh-rsa'
DEB [YYYYmmdd-HH:MM:30.722] thr=1   paramiko.transport: Our pubkey algorithm list: ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-rsa']
DEB [YYYYmmdd-HH:MM:30.723] thr=1   paramiko.transport: Server-side algorithm list: ['']
DEB [YYYYmmdd-HH:MM:30.723] thr=1   paramiko.transport: Agreed upon 'rsa-sha2-512' pubkey algorithm
INF [YYYYmmdd-HH:MM:30.735] thr=1   paramiko.transport: Authentication (publickey) failed.
DEB [YYYYmmdd-HH:MM:30.739] thr=2   paramiko.transport: Trying SSH agent key b'9d37********************'
DEB [YYYYmmdd-HH:MM:30.747] thr=1   paramiko.transport: userauth is OK.
DEB [YYYYmmdd-HH:MM:30.748] thr=1   paramiko.transport: Finalizing pubkey algorithm for key of type 'ssh-rsa'
DEB [YYYYmmdd-HH:MM:30.748] thr=1   paramiko.transport: Our pubkey algorithm list: ['rsa-sha2-512', 'rsa-sha2-256', 'ssh-rsa']
DEB [YYYYmmdd-HH:MM:30.748] thr=1   paramiko.transport: Server-side algorithm list: ['']
DEB [YYYYmmdd-HH:MM:30.748] thr=1   paramiko.transport: Agreed upon 'rsa-sha2-512' pubkey algorithm
INF [YYYYmmdd-HH:MM:30.868] thr=1   paramiko.transport: Authentication (publickey) failed...

Shell 命令日志

OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 58: Applying options for *
debug2: resolving "server.tld" port 22
debug2: ssh_connect_direct: needpriv 0
debug1: Connecting to server.tld [server.tld] port 22.
debug1: Connection established.
debug1: permanently_set_uid: 0/0
debug1: key_load_public: No such file or directory
debug1: identity file /path/to/.ssh/my_key.rsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /path/to/.ssh/my_key.rsa-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_7.4
debug1: Remote protocol version 2.0, remote software version OpenSSH_5.3
debug1: match: OpenSSH_5.3 pat OpenSSH_5* compat 0x0c000000
debug2: fd 3 setting O_NONBLOCK
debug1: Authenticating to server.tld:22 as 'my_user'
debug3: hostkeys_foreach: reading file "/path/to/.ssh/known_hosts"
debug3: record_hostkey: found key type RSA in file /path/to/.ssh/known_hosts:82
debug3: load_hostkeys: loaded 1 keys from server.tld
debug3: order_hostkeyalgs: prefer hostkeyalgs: ssh-rsa-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256,ssh-rsa
debug3: send packet: type 20
debug1: SSH2_MSG_KEXINIT sent
debug3: receive packet: type 20
debug1: SSH2_MSG_KEXINIT received
debug2: local client KEXINIT proposal
debug2: KEX algorithms: curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha256,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1,ext-info-c
debug2: host key algorithms: ssh-rsa-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256,ssh-rsa,ecdsa-sha2-nistp256-cert-v01@openssh.com,ecdsa-sha2-nistp384-cert-v01@openssh.com,ecdsa-sha2-nistp521-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,ssh-dss-cert-v01@openssh.com,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,ssh-dss
debug2: ciphers ctos: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc
debug2: ciphers stoc: chacha20-poly1305@openssh.com,aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes128-cbc,aes192-cbc,aes256-cbc
debug2: MACs ctos: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
debug2: MACs stoc: umac-64-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,hmac-sha1-etm@openssh.com,umac-64@openssh.com,umac-128@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-sha1
debug2: compression ctos: none,zlib@openssh.com,zlib
debug2: compression stoc: none,zlib@openssh.com,zlib
debug2: languages ctos:
debug2: languages stoc:
debug2: first_kex_follows 0
debug2: reserved 0
debug2: peer server KEXINIT proposal
debug2: KEX algorithms: diffie-hellman-group-exchange-sha256,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
debug2: host key algorithms: ssh-rsa,ssh-dss
debug2: ciphers ctos: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
debug2: ciphers stoc: aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se
debug2: MACs ctos: hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: MACs stoc: hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-sha2-256,hmac-sha2-512,hmac-ripemd160,hmac-ripemd160@openssh.com,hmac-sha1-96,hmac-md5-96
debug2: compression ctos: none,zlib@openssh.com
debug2: compression stoc: none,zlib@openssh.com
debug2: languages ctos:
debug2: languages stoc:
debug2: first_kex_follows 0
debug2: reserved 0
debug1: kex: algorithm: diffie-hellman-group-exchange-sha256
debug1: kex: host key algorithm: ssh-rsa
debug1: kex: server->client cipher: aes128-ctr MAC: umac-64@openssh.com compression: none
debug1: kex: client->server cipher: aes128-ctr MAC: umac-64@openssh.com compression: none
debug1: kex: diffie-hellman-group-exchange-sha256 need=16 dh_need=16
debug1: kex: diffie-hellman-group-exchange-sha256 need=16 dh_need=16
debug3: send packet: type 34
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<3072<8192) sent
debug3: receive packet: type 31
debug1: got SSH2_MSG_KEX_DH_GEX_GROUP
debug2: bits set: 1502/3072
debug3: send packet: type 32
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug3: receive packet: type 33
debug1: got SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Server host key: ssh-.:**************************************************
debug3: hostkeys_foreach: reading file "/path/to/.ssh/known_hosts"
debug3: record_hostkey: found key type RSA in file /path/to/.ssh/known_hosts:8..2
debug3: load_hostkeys: loaded 1 keys from server.tld
debug1: Host 'server.tld' is known and matches the RSA host key.
debug1: Found key in /path/to/.ssh/known_hosts:82
debug2: bits set: 1562/3072
debug3: send packet: type 21
debug2: set_newkeys: mode 1
debug1: rekey after 4294967296 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug3: receive packet: type 21
debug1: SSH2_MSG_NEWKEYS received
debug2: set_newkeys: mode 0
debug1: rekey after 4294967296 blocks
debug2: key: <foo> (0x55bcf6d1d320), agent
debug2: key: /path/to/.ssh/my_key.rsa ((nil)), explicit
debug3: send packet: type 5
debug3: receive packet: type 6
debug2: service_accept: ssh-userauth
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug3: send packet: type 50
debug3: receive packet: type 51
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug3: start over, passed a different list publickey,gssapi-keyex,gssapi-with-mic,password
debug3: preferred gssapi-keyex,gssapi-with-mic,publickey,keyboard-interactive,password
debug3: authmethod_lookup gssapi-keyex
debug3: remaining preferred: gssapi-with-mic,publickey,keyboard-interactive,password
debug3: authmethod_is_enabled gssapi-keyex
debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
debug2: we did not send a packet, disable method
debug3: authmethod_lookup gssapi-with-mic
debug3: remaining preferred: publickey,keyboard-interactive,password
debug3: authmethod_is_enabled gssapi-with-mic
debug1: Next authentication method: gssapi-with-mic
debug1: Unspecified GSS failure.  Minor code may provide more information
No Kerberos credentials available (default cache: KEYRING:persistent:0)

debug1: Unspecified GSS failure.  Minor code may provide more information
No Kerberos credentials available (default cache: KEYRING:persistent:0)

debug2: we did not send a packet, disable method
debug3: authmethod_lookup publickey
debug3: remaining preferred: keyboard-interactive,password
debug3: authmethod_is_enabled publickey
debug1: Next authentication method: publickey
debug1: Offering RSA public key: <foo>
debug3: send_pubkey_test
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
debug3: receive packet: type 51
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug1: Trying private key: /path/to/.ssh/my_key.rsa
debug3: sign_and_send_pubkey: RSA SHA256:**********************************
debug3: send packet: type 50
debug2: we sent a publickey packet, wait for reply
debug3: receive packet: type 52
debug1: Authentication succeeded (publickey).
Authenticated to server.tld ([server.tld]:22).
debug1: channel 0: new [client-session]
debug3: ssh_session2_open: channel_new: 0
debug2: channel 0: send open
debug3: send packet: type 90
debug1: Requesting no-more-sessions@openssh.com
debug3: send packet: type 80
debug1: Entering interactive session.
debug1: pledge: network
debug3: receive packet: type 91
debug2: callback start
debug2: fd 3 setting TCP_NODELAY
debug3: ssh_packet_set_tos: set IP_TOS 0x08
debug2: client_session2_setup: id 0
debug1: Sending environment.
debug3: Ignored env XDG_SESSION_ID
debug3: Ignored env HOSTNAME
debug3: Ignored env SELINUX_ROLE_REQUESTED
debug3: Ignored env TERM
debug3: Ignored env SHELL
debug3: Ignored env HISTSIZE
debug3: Ignored env SSH_CLIENT
debug3: Ignored env SELINUX_USE_CURRENT_RANGE
debug3: Ignored env SSH_TTY
debug3: Ignored env CDPATH
debug3: Ignored env USER
debug3: Ignored env LS_COLORS
debug3: Ignored env SSH_AUTH_SOCK
debug3: Ignored env MAIL
debug3: Ignored env PATH
debug3: Ignored env PWD
debug1: Sending env LANG = xx_XX.UTF-8
debug2: channel 0: request env confirm 0
debug3: send packet: type 98
debug3: Ignored env SELINUX_LEVEL_REQUESTED
debug3: Ignored env HISTCONTROL
debug3: Ignored env SHLVL
debug3: Ignored env HOME
debug3: Ignored env LOGNAME
debug3: Ignored env SSH_CONNECTION
debug3: Ignored env LESSOPEN
debug3: Ignored env XDG_RUNTIME_DIR
debug3: Ignored env _
debug1: Sending command: echo TEST : $(hostname)
debug2: channel 0: request exec confirm 1
debug3: send packet: type 98
debug2: callback done
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug2: channel 0: rcvd adjust 2097152
debug3: receive packet: type 99
debug2: channel_input_status_confirm: type 99 id 0
debug2: exec request accepted on channel 0
TEST : server.tld
debug3: receive packet: type 96
debug2: channel 0: rcvd eof
debug2: channel 0: output open -> drain
debug2: channel 0: obuf empty
debug2: channel 0: close_write
debug2: channel 0: output drain -> closed
debug3: receive packet: type 98
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug3: receive packet: type 98
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
debug2: channel 0: rcvd eow
debug2: channel 0: close_read
debug2: channel 0: input open -> closed
debug3: receive packet: type 97
debug2: channel 0: rcvd close
debug3: channel 0: will not send data after close
debug2: channel 0: almost dead
debug2: channel 0: gc: notify user
debug2: channel 0: gc: user detached
debug2: channel 0: send close
debug3: send packet: type 97
debug2: channel 0: is dead
debug2: channel 0: garbage collecting
debug1: channel 0: free: client-session, nchannels 1
debug3: channel 0: status: The following connections are open:
  #0 client-session (t4 r0 i3/0 o3/0 fd -1/-1 cc -1)

debug3: send packet: type 1
Transferred: sent 3264, received 2656 bytes, in 0.0 seconds.
Bytes per second: sent 92349.8, received 75147.4
debug1: Exit status 0
.

解决方案 1:

在我看来,这是 Paramiko 的一个错误。它无法正确处理server-sig-algs服务器端缺少扩展的情况。

rsa-sha2-*尝试在 Paramiko 端完全禁用:

ssh_client.connect(
  server, username=ssh_user, key_filename=ssh_keypath,
  disabled_algorithms=dict(pubkeys=["rsa-sha2-512", "rsa-sha2-256"]))

(请注意,无需指定port=22,因为这是默认设置)

我发现了相关的 Paramiko 问题:

从 paramiko 2.9.x 客户端到 dropbear 服务器的 RSA 密钥认证失败

虽然它引用了Paramiko 2.9.0 更改日志,但这似乎暗示该行为是故意的:

当服务器未发送 时server-sig-algs,Paramiko 将尝试上述列表中的第一个算法。因此,连接到旧服务器的客户端应使用disabled_algorithms来关闭 SHA2。


从2.9.2开始,Paramiko 会说:

DEB [20220113-14:46:13.882] thr=1 paramiko.transport:服务器未发送 server-sig-algs 列表;默认采用我们的第一个首选算法('rsa-sha2-512')

DEB [20220113-14:46:13.882] thr=1 paramiko.transport:注意:如果您的服务器不支持该算法或其他算法,您可以使用'disabled_algorithms' SSHClient/Transport init kwarg 来禁用它们!


强制性警告:请勿使用–这样做会让您失去针对MITM 攻击的AutoAddPolicy保护。有关正确解决方案,请参阅Paramiko“未知服务器”


您等待命令完成并读取其输出的代码也有缺陷。请参阅等待使用 Python Paramiko 执行的命令完成。对于大多数目的而言,这get_pty=True也不是一个好主意。

解决方案 2:

添加此内容后您好:

ssh_client.connect(
  server, username=ssh_user, key_filename=ssh_keypath,
  disabled_algorithms=dict(pubkeys=["rsa-sha2-512", "rsa-sha2-256"]))

我收到以下错误:

Our pubkey algorithm list: ['ssh-rsa']
Server did not send a server-sig-algs list; defaulting to our first preferred algo ('ssh-rsa')
NOTE: you may use the 'disabled_algorithms' SSHClient/Transport init kwarg to disable that or other algorithms if your server does not support them!

我通过添加以下内容修复了此问题:

 client.connect(hostname=self.hostname_sfp,
                           username=self.user_sftp,
                           password=self.password_sftp,
                           port=self.port_sftp,
                           disabled_algorithms=dict(pubkeys=["rsa-sha2-512", "rsa-sha2-256"]),
                           allow_agent=False,
                           look_for_keys=False
                           )

解决方案 3:

这是 paramiko 的一个已知 RSA 身份验证问题。

如果您不想陷入实施 paramiko 更改的复杂性。请尝试降级到 2.8.1 版本的 paramiko,它应该可以立即解决您的问题。
要安装 paramiko 2.8.1:

 pip install 'paramiko<=2.8.1'

解决方案 4:

这解决了一个问题,但导致其他仅使用禁用算法的服务器出现另一个问题。以下情况导致“无法就签署 ssh-rsa 的公钥算法达成一致”

DISABLED_ALGORITHMS = {'keys': ['rsa-sha2-256', 'rsa-sha2-512'], 'pubkeys':['rsa-sha2-512', 'rsa-sha2-256']}

因此,我最终将 ssh-rsa 移至首选列表,这样当没有返回 server-sig-algs 时,2.9.0+ 版本将默认使用 ssh-rsa。“服务器未发送 server-sig-algs 列表”

from packaging import version
if version.parse(paramiko.__version__) > version.parse("2.8.1") and version.parse(paramiko.__version__) <= version.parse("2.12.0"):
    print(f"Paramiko Version:{paramiko.__version__}")
    _preferred_pubkeys = (
    "ssh-ed25519",
    "ecdsa-sha2-nistp256",
    "ecdsa-sha2-nistp384",
    "ecdsa-sha2-nistp521",
    "ssh-rsa",
    "rsa-sha2-512",
    "rsa-sha2-256",
    "ssh-dss",
    )
    
    print(f"Patching _preferred_pubkeys {paramiko.transport.Transport._preferred_pubkeys} with {_preferred_pubkeys}")
    paramiko.transport.Transport._preferred_pubkeys = _preferred_pubkeys

解决方案 5:

https://stackoverflow.com/a/74349827/48167的想法略有不同
(如果不直接使用 paramiko 而是由我使用的库使用的库使用,则它非常有用,因此直接配置 paramiko 会很困难;-))

我重写了它以“更安全” - 不是盲目地覆盖密钥类型列表,而是通过将任何 rsa-sha2-... 项移到 ssh-rsa 后面来重新组织我找到的列表:

import paramiko.transport
if hasattr(paramiko.transport.Transport, '_preferred_pubkeys'):
    pk = paramiko.transport.Transport._preferred_pubkeys
    ssh_rsa_pos = pk.index('ssh-rsa')
    if ssh_rsa_pos >= 0:
        fixed_pk = [
            x for x in pk[:ssh_rsa_pos]
            if not x.startswith('rsa-sha2-')
        ] + [
            pk[ssh_rsa_pos]
        ] + [
            x for x in pk[:ssh_rsa_pos]
            if x.startswith('rsa-sha2-')
        ] + list(pk[ssh_rsa_pos + 1:])
        paramiko.transport.Transport._preferred_pubkeys = tuple(fixed_pk)

解决方案 6:

我最终使用以下代码来避免为其他连接禁用这些算法。我们有一个 Airflow 环境,其中数百个 DAG 使用一个通用运算符)

try:
    ssh.connect(ip, **args)
except paramiko.ssh_exception.AuthenticationException:
    ssh.connect(ip, 
                disabled_algorithms=dict(keys=['rsa-sha2-256', 'rsa-sha2-512'],
                                         pubkeys=["rsa-sha2-512","rsa-sha2-256"]), 
                **args)

编辑:请阅读@Martin Prikryl 关于使用此方法的安全问题的评论。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用