Net::SSH仅支持3次认证尝试,OpenSSH无此限制问题排查
问题:Net::SSH仅3次认证尝试即失败,OpenSSH可正常连接
使用Ruby的Net::SSH连接SSH服务器(服务器配置MaxAuthTries=6)时,仅尝试3次认证就抛出disconnected: Too many authentication failures (2) (Net::SSH::Disconnect)异常,但OpenSSH命令行客户端能正常连接。
核心原因:SSH Agent中存储了4个身份,Net::SSH会优先尝试Agent中的密钥,且在3次失败后就触发服务器的认证次数限制;而OpenSSH会尝试完Agent中的所有密钥后,再使用配置文件指定的密钥完成认证。禁用Agent后Net::SSH可正常连接。
环境配置
$ ssh-add -l 2048 SHA256:fMBMXD1mpUpM/vmVcjaXDvdIvPy4GCCdG5lc8ga1cLU /home/odeda/.ssh/id_rsa (RSA) 3072 SHA256:nfsiFP9APVl6oOK5htpldBmknVTDt1lCLvuHpTaaAao odeda@vesho (RSA) 2048 SHA256:t3+SY5Ru+tJ3r/HE7qIW4fnXswQ16btCiIadVGa2XPM odeda@jior (RSA) 1024 SHA256:EKBzRjDE6twnRLlIT3IHEfu08tVXCSK1henMHB+s+p8 (DSA) $ grep example.com ~/.ssh/config -A1 Host *.example.com IdentityFile ~/.ssh/my_example_identity.pem
解决方案
1. 强制指定目标密钥,跳过Agent自动尝试
在Net::SSH启动参数中明确指定要使用的密钥,并禁用Agent身份加载,确保只尝试配置文件中的密钥:
bundle exec ruby -rnet/ssh -e 'Net::SSH.start("server.example.com","ubuntu",{ host_name:"3.456.789.12", verify_host_key: :never, user_known_hosts_file: "/dev/null", non_interactive: true, keys: ["/home/odeda/.ssh/my_example_identity.pem"], use_agent: false }) do |ssh| puts "Connected"; puts ssh.exec! "echo Hello"; ssh.loop(3); end'
2. 调整密钥尝试顺序,优先使用配置文件密钥
如果需要保留Agent功能,但希望优先尝试指定密钥,可先加载目标密钥,再让Net::SSH尝试Agent中的身份:
bundle exec ruby -rnet/ssh -e ' target_key = Net::SSH::KeyFactory.load_private_key("/home/odeda/.ssh/my_example_identity.pem") Net::SSH.start("server.example.com","ubuntu",{ host_name:"3.456.789.12", verify_host_key: :never, user_known_hosts_file: "/dev/null", non_interactive: true, keys: [target_key], use_agent: true }) do |ssh| puts "Connected"; puts ssh.exec! "echo Hello"; ssh.loop(3); end'
3. 临时禁用SSH Agent(已验证有效)
通过环境变量临时清空SSH_AUTH_SOCK,让Net::SSH自动使用配置文件中的密钥:
SSH_AUTH_SOCK= bundle exec ruby -rnet/ssh -e 'Net::SSH.start("server.example.com","ubuntu",{ host_name:"3.456.789.12", verify_host_key: :never, user_known_hosts_file: "/dev/null", non_interactive: true}) do |ssh| puts "Connected"; puts ssh.exec! "echo Hello"; ssh.loop(3); end'
行为差异原因
- OpenSSH:默认会先遍历Agent中的所有身份,即使多个失败,仍会继续尝试配置文件指定的密钥,直到达到服务器
MaxAuthTries限制。 - Net::SSH:默认按顺序尝试Agent中的每个身份,每个失败的尝试都会消耗服务器的AuthTries计数。当3个RSA密钥失败后,服务器剩余允许次数不足,直接断开连接,导致Net::SSH没有机会尝试配置文件中的密钥。
- 服务器
MaxAuthTries=6是指累计失败认证尝试的总数,Net::SSH的Agent身份尝试每次都算一次失败,叠加后触发超限。
内容的提问来源于stack exchange,提问作者Guss
相关产品推荐
相关产品推荐

