ssh 登录要等十秒才出密码提示:UseDNS、GSSAPI 与 PAM 三段排查
用 ssh 连一台内网机器,敲完命令光标就停在那里,五六秒甚至十几秒后才跳出 Password 提示;登录进去以后操作一切正常,ping 和端口探测也很快。这类「连得上但建立会话慢」的问题基本不在带宽上,而在会话建立阶段的三个环节:服务端反向 DNS、GSSAPI 协商、PAM 认证链。按顺序拆开看,通常十分钟内就能定位。
第一步:先确认慢在哪一段
在客户端跑 ssh -vvv user@host,看两个关键落点。如果停在 SSH2_MSG_KEXINIT sent 之后迟迟收不到 remote software version,说明慢在 banner 交换,服务端在做与本次连接无关的准备工作;如果能走到 Authentications that can continue 之后才卡住,说明慢在认证阶段。前者优先怀疑 UseDNS,后者优先怀疑 GSSAPI 和 PAM。先分清段落,再谈改配置。
第二步:UseDNS 与反向解析超时
sshd 配置里 UseDNS 为 yes 时,服务端会拿客户端源 IP 去查 PTR 记录,查到之后还会正向验证一次。如果客户端在 NAT 后面,或者内网 DNS 根本没有对应的反向区,这个查询会一直等到解析器超时,常见五秒或十秒,取决于 resolv.conf 里的 timeout 和 attempts。
验证办法有两个:在服务端对新连接期间抓 53 端口,看有没有来自 sshd 的反向查询;或者直接把 sshd_config 里的 UseDNS 改成 no,先执行 sshd -t 校验语法,再 systemctl reload sshd,然后对比登录耗时。前后差出好几秒,基本就能确认。
但别急着关。UseDNS 关掉只影响日志里记录的主机名和 HostbasedAuthentication。如果确实靠 PAM 或 hosts.allow 做基于域名的访问控制,正确做法是补齐 PTR 记录,或者在 Match Address 里限定来源网段,而不是简单关闭。
第三步:GSSAPI 协商等不到 KDC
服务端 GSSAPIAuthentication 为 yes 时,客户端会先尝试 GSSAPI 认证,去找 KDC 或 SPNEGO 服务。机器不在域里,或者 Kerberos 配置指向一个不可达的 KDC,客户端就会一直等到自己超时,才回落到公钥或密码认证。特征是从认证阶段才开始慢,ssh -vvv 里能看到 Unspecified GSS failure 之类的行。
处置可以只在客户端做,不影响其他使用者:在 ~/.ssh/config 里加 GSSAPIAuthentication no。如果整批机器都用不到 GSSAPI,再在服务端关闭并 reload。
第四步:PAM 链路里的外部依赖
前两项都排除后,看 PAM。sshd 的认证是一条模块链,任何一环去连外部服务都可能拖慢整个会话:pam_systemd 在容器或精简系统里找不到 systemd 会重试;pam_sss(SSSD)在 LDAP 或 AD 后端不通时按超时重试;pam_faillock 在锁文件所在目录 IO 慢时同样会卡住。定位方法是服务端对新连接做 strace -f -tt -p $(pidof sshd),看它停在哪个 connect 或 read 上;同时看 journalctl -u sshd 最近几十行有没有 PAM 报错。
收尾:改配置前先自检
sshd 的改动务必先 sshd -t,再用 reload 而不是 restart。reload 不会断开已经登录的会话,改错了还有退路。改完用 time ssh -o BatchMode=yes host true 连续测三次,确认是稳定变快,而不是某次恰好不慢。
把「十秒」拆成三段之后,问题通常只剩一个原因。最怕的是一上来就换 DNS、改网络,把三个独立环节混在一起,最后既没定位也没解决。
- 点赞
- 收藏
- 关注作者
评论(0)