Ping 延迟正常,并不代表 SSH 登录的每一步都正常。SSH 从建立 TCP 连接到出现命令提示符,还要经过版本交换、密钥协商、主机密钥验证、用户认证、PAM 会话和 Shell 初始化。任何一段等待都可能被用户感知为登录慢。
这类问题最容易走错的方向,是看到 Ping 正常就反复重启 sshd,或者未经验证直接关闭 DNS 与认证功能。
我更习惯先记录停顿发生的位置,再决定应该改客户端、服务端还是网络。

先把慢拆成可以计时的阶段
第一次测试不要只凭感觉。客户端执行:
time ssh -vvv user@server-ip
OpenSSH 手册说明,-v 用于调试连接、认证和配置问题,最多可以叠加三次获得更详细的输出。调试信息可能包含用户名、路径、主机地址和密钥类型,分享日志前应做脱敏。
观察终端在哪一行停顿最久,并记录大致秒数。可以把现象分成四段:
| 停顿位置 | 优先检查方向 |
|---|---|
| 连接建立前 | 地址、端口、丢包、防火墙 |
| 版本或密钥协商阶段 | 算法、MTU、链路质量、服务端负载 |
| 认证阶段 | 密钥数量、认证方式、PAM、外部目录 |
| 认证成功后才出现提示符 | Shell启动文件、家目录、挂载、登录脚本 |
这张表只是定位入口,不是根据一行日志直接下结论。接下来要结合服务端同一时间的记录验证。
TCP连接快不代表链路完全正常
先测 TCP 端口建立时间:
time nc -vz server-ip 22
没有 nc 时可以使用:
curl -v telnet://server-ip:22
如果 TCP 建立本身就慢,而 Ping 正常,可能是 22 端口被限速、路径存在丢包、IPv6 与 IPv4 选择不同,或者安全设备对新连接检查较久。用域名连接时,还应分别测试解析结果中的地址。
不要通过连续高频连接做压力测试。更稳妥的方法是在相同客户端、相同网络下分别测试几次,并从另一条正常网络做对照。若只有某一运营商或某个地区慢,问题更接近链路;所有来源都慢,才优先看服务端。
在多地区业务里,我会先保留同一套系统配置做对照,避免把线路与配置问题混在一起。萤光云提供多个可选地区,适合按业务位置选择长期部署;LightNode 支持小时计费和多个数据中心,做同配置短期对照时比较方便。这里的关键不是换一家就一定解决,而是对照测试只能改变一个变量,系统镜像、SSH配置和测试时间尽量保持一致。
从调试日志判断认证阶段
如果日志很快到达身份验证,但在尝试多个密钥时等待,先查看客户端代理里加载了多少密钥:
ssh-add -l
可以临时指定目标密钥并限制只使用该身份:
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 user@server-ip
如果这样明显变快,说明之前可能依次尝试了多个无关密钥。修复应写入对应主机的客户端配置,而不是删除其他项目仍在使用的密钥。
若停顿发生在密码、双因素或 PAM 阶段,应同步查看服务端认证日志。Ubuntu、Debian 常见:
sudo journalctl -u ssh --since '10 minutes ago'
sudo tail -n 100 /var/log/auth.log
Rocky Linux、AlmaLinux 常见:
sudo journalctl -u sshd --since '10 minutes ago'
sudo tail -n 100 /var/log/secure
日志文件位置会随系统和日志配置变化,以当前系统实际记录为准。
DNS只在有证据时检查
反向 DNS 经常被当成 SSH 慢的默认答案,但不能只凭经验修改。先检查服务端在连接时是否发起了反向查询,以及目标地址的 DNS 响应是否超时。
可以从服务端针对客户端 IP 做一次受控查询:
time getent hosts client-ip
如果这里稳定卡住,同时 sshd 日志与抓包也显示 DNS 等待,再核对 /etc/resolv.conf、本地解析服务和 sshd 当前配置。不同版本的 OpenSSH 默认值可能不同,修改前使用:
sshd -T | grep usedns
sshd -T 能显示生效配置,比只看配置文件里的某一行更可靠。即使决定调整,也要先运行:
sudo sshd -t
语法通过后再重新加载服务,并保持当前 SSH 会话不要关闭,直到新窗口验证登录成功。
认证成功后仍卡住要查会话环境
调试日志如果已经显示认证成功,随后很久才出现提示符,问题通常不再是网络或密钥。可以绕开交互式 Shell 做一个最小命令:
time ssh user@server-ip /usr/bin/true
若最小命令很快,交互登录却慢,重点检查用户的 .bashrc、.profile、欢迎信息脚本和终端初始化。登录脚本中访问失效的网络目录、运行耗时命令或等待外部接口,都会拖慢提示符出现。
如果最小命令也慢,还要检查 PAM、家目录权限、NFS 挂载、用户目录服务以及系统负载。查看当前进程与 I/O:
uptime
vmstat 1 5
不要直接清空用户启动文件。可以先为可疑命令增加计时,或用最小配置启动一个测试 Shell,确定具体语句后再修改。
服务端调试有明确边界
OpenSSH 服务端支持提高日志级别,但官方手册提醒,DEBUG 级别会记录更敏感的信息,不适合长期保留。生产服务器优先使用现有认证日志和客户端 -vvv,只有证据不足时才在维护窗口临时增加日志。
修改 sshd_config 前应备份文件,执行 sshd -t,并保留已登录的管理会话。远程环境里直接重启 sshd 是高风险操作,一旦配置错误或防火墙规则同时变化,可能失去服务器入口。
如果需要更深的服务端调试,可以在备用端口启动独立的测试 sshd,而不是影响现有 22 端口。该操作涉及密钥、权限和防火墙,应由熟悉当前系统的人执行。
修改后如何验收
修复后使用同一客户端、同一网络和同一账号重复三次,记录 TCP 建立、认证完成和提示符出现的时间。首次连接可能受 DNS、密钥缓存或磁盘缓存影响,所以不要只测一次。
随后从另一条网络复测,确认改善不是单一网络的偶然变化。服务端日志中不应继续出现超时、重复认证或外部目录查询错误,系统负载也应处于正常范围。
最终证据应该形成闭环:ssh -vvv 中原来的停顿消失,服务端对应阶段不再报错,交互登录和最小命令都达到稳定时间。只有这三项同时成立,才能说明根因已经处理,而不是重启后暂时变快。


