密码没有输错,私钥也确实存在,SSH却在出现密码提示前就断开,并显示 Too many authentication failures。这类错误的重点通常不是服务器拒绝了正确密码,而是客户端在到达正确身份之前,已经提交了太多不匹配的密钥。
先控制客户端提供哪些身份,再考虑调整服务端上限。 直接放宽 MaxAuthTries 会扩大所有连接的认证尝试空间,却没有解决本机密钥过多或配置命中错误的问题。

先确认错误发生在哪个认证阶段
使用详细日志重新连接,并把目标主机、用户和端口写完整:
ssh -vvv -p 22 user@example.com
关注 Offering public key、Authentications that can continue 和最终断开位置。如果日志连续列出多把密钥,尚未出现目标私钥就被服务器断开,说明认证次数在客户端试错过程中耗尽。
如果已经看到目标密钥被接受,随后才失败,则要继续检查私钥签名、账号限制或二次认证。同一句报错不能替代完整调试日志,保存发生前的十几行才有判断价值。
查看ssh-agent当前装了多少密钥
列出代理中的身份:
ssh-add -l
ssh-add -L
第一条显示指纹,第二条输出公钥内容。桌面系统、开发工具和密码管理器可能同时向 ssh-agent 提供多把身份;即使命令里写了 -i,客户端仍可能继续尝试代理中的其他密钥。
不要在工单或聊天中公开完整私钥。公钥虽然不是秘密,也应结合指纹和用途管理,避免把生产、测试及个人账号的身份混在一起。
用一次性命令只提交指定密钥
先用最小范围命令验证目标密钥:
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_prod user@example.com
IdentitiesOnly=yes 会让OpenSSH只使用配置或命令行明确指定的身份,不再把代理提供的所有密钥逐个送给服务器。这通常是修复该错误风险最低、证据最清晰的方法。
若私钥带有对应证书,也要确认 CertificateFile 配置匹配。路径写错、文件权限过宽或目标用户名错误,会表现为指定密钥仍不被接受,不能继续归因于尝试次数。
为不同主机写独立配置
验证成功后,把规则写进 ~/.ssh/config,避免每次手工输入:
Host prod-web
HostName 203.0.113.10
User deploy
Port 22
IdentityFile ~/.ssh/id_ed25519_prod
IdentitiesOnly yes
以后使用 ssh prod-web 即可。OpenSSH按命令行、用户配置和系统配置读取参数,同一个选项通常采用首先获得的值,因此更具体的 Host 块应放在通配规则之前。
用下面的命令查看合并后的有效配置:
ssh -G prod-web | grep -Ei '^(hostname|user|port|identityfile|identitiesonly) '
不要只看配置文件内容,要看目标别名最终解析出的配置。 Include、通配 Host * 和开发工具生成的片段都可能改变实际结果。
临时整理代理而不影响其他终端
如果当前会话确实不需要代理里的旧密钥,可先记录指纹,再删除指定身份:
ssh-add -d ~/.ssh/id_ed25519_old
ssh-add -D 会清空代理中的全部身份,可能让其他仓库、跳板机和自动化任务同时失去登录能力。生产环境不要把清空代理当作默认动作。 更稳妥的方案是为目标主机设置 IdentitiesOnly yes,或启动隔离的代理会话进行验证。
检查服务端日志和MaxAuthTries
有服务器权限时,可读取同一时间窗口的认证日志:
sudo journalctl -u ssh --since "10 minutes ago"
sudo journalctl -u sshd --since "10 minutes ago"
不同发行版服务名和日志位置可能不同。日志能帮助确认来源地址、目标账号、失败次数以及是否触发其他安全策略。不要为了测试关闭Fail2ban、防火墙或公钥认证。
MaxAuthTries 控制每个连接允许的认证尝试次数。只有在客户端身份已经收敛、业务确有多阶段认证需求时,才评估修改服务端参数,并先执行 sshd -t 检查配置。盲目提高上限会增加暴力尝试空间,也掩盖客户端配置错误。
在新环境验证密钥配置
多台服务器共用同一个宽泛 Host * 规则时,密钥数量会随项目增长。可以为每个环境使用明确别名、独立密钥和最小权限账号,并在迁移前验证别名解析结果。
需要临时搭建对照服务器时,可在 萤光云 上复制SSH配置进行验证,也可以用按小时计费的 LightNode 检查不同客户端的登录行为。测试机只应放测试公钥,不要复制生产私钥。
修复后如何验收
重新执行 ssh -vvv,确认日志只提供预期身份,并在正确密钥处完成认证。随后分别测试交互登录、SCP或SFTP,以及依赖同一别名的部署脚本。
验收标准是连接不再提前断开、有效配置指向正确用户和密钥、其他主机登录未受影响。 仅把服务端上限调高后暂时能连,不算根因关闭。
常见问题
已经使用 -i,为什么还会尝试其他密钥?
默认情况下,代理提供的身份仍可能参与认证。增加 -o IdentitiesOnly=yes,再用调试日志确认实际提交顺序。
可以永久清空ssh-agent吗?
不建议把清空作为通用修复。代理可能同时服务Git、跳板机和其他终端,应优先为具体主机限制身份。
是否应该把MaxAuthTries改得很大?
通常不应该。先解决客户端提供过多密钥的问题;确有多阶段认证需求时,再按安全策略小幅调整并验证。
温馨提示
修改SSH客户端或服务端配置时,保留一个已登录的管理会话,并先在新终端验证。不要在唯一会话中直接重启sshd或批量删除密钥,否则一次拼写错误就可能造成远程锁定。


