You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 15:42:03