Ruby Net::SSH.start认证失败,但命令行SSH可正常连接
解决Net::SSH认证失败(ssh-rsa算法不被支持)的问题
问题场景
我在Ruby环境中用Net::SSH库远程连接目标机器执行命令,初始脚本如下:
require 'net/ssh' Net::SSH.start($IP, $USER, verbose: :debug) do |ssh| puts ssh.exec!("hostname") end
执行时报错:
ruby/gems/3.2.0/gems/net-ssh-7.2.3/lib/net/ssh.rb:275:in `start': Authentication failed for user root@$IP (Net::SSH::AuthenticationFailed)
但命令行执行ssh root@$IP或Ruby反引号执行该命令都能成功连接。查看目标机器/var/log/auth.log发现关键日志:
Aug 19 15:50:44 a$IP sshd[3385268]: userauth_pubkey: key type ssh-rsa not in PubkeyAcceptedAlgorithms [preauth]
本地SSH客户端必须添加以下配置才能正常登录,移除则失败:
Host * HostKeyAlgorithms +ssh-dss
尝试修改Net::SSH.start的配置参数:
Net::SSH.start($IP, $USER, host_key: ["ssh-dss"], append_all_supported_algorithms: true, non_interactive: true, verbose: :debug)
但仍然出现相同的认证失败错误。
问题分析
从日志和本地SSH配置能看出,目标机器的sshd服务不允许ssh-rsa算法,而Net::SSH默认会优先尝试ssh-rsa这类现代算法,导致认证直接被拒绝。之前设置的host_key参数是指定主机密钥验证的算法,但问题核心出在用户公钥的认证算法(对应sshd的PubkeyAcceptedAlgorithms),所以之前的参数配置没命中问题点。
解决方案
需要在Net::SSH的配置中同时指定允许的公钥认证算法和匹配的主机密钥算法,还要关闭默认追加算法的行为,避免优先尝试被拒绝的ssh-rsa。修改后的脚本如下:
require 'net/ssh' Net::SSH.start($IP, $USER, verbose: :debug, pubkey_algorithms: ["ssh-dss"], # 对应sshd的PubkeyAcceptedAlgorithms,指定认证用的公钥算法 host_key: ["ssh-dss"], # 和本地SSH配置保持一致的主机密钥算法 append_all_supported_algorithms: false # 禁止追加默认算法,避免优先尝试被拒绝的ssh-rsa ) do |ssh| puts ssh.exec!("hostname") end
关键参数说明
pubkey_algorithms: 直接对应目标机器sshd的PubkeyAcceptedAlgorithms配置,指定客户端用来完成身份认证的公钥算法,这里设置为ssh-dss匹配要求。host_key: 指定主机密钥验证阶段使用的算法,和本地SSH客户端配置保持统一。append_all_supported_algorithms: false: 关闭Net::SSH默认追加所有支持算法的行为,确保只会使用你指定的算法进行尝试。
如果问题依旧,可以把verbose改成:trace开启更详细的日志,查看Net::SSH实际尝试的算法顺序,确认是否正确使用了ssh-dss。
内容的提问来源于stack exchange,提问作者Bram
相关产品推荐
相关产品推荐

