SSH登录速度慢得要死?我花了三天终于找到元凶

2ae3c74cb8038c4059c35ab9e99917d9

上周五下班前,运维老大突然给我派了个活:去排查一下为啥公司的CentOS服务器SSH登录慢得跟蜗牛爬似的。我当时心想,这能有多慢?结果一连上去,我傻眼了。

输完用户名之后,光标在那闪啊闪啊闪,足足等了快40秒才蹦出来让我输密码。这要是平时也就算了,关键是那天晚上线上出问题,急着要上服务器处理,结果光等登录就快一分钟,差点没把人急死。

更诡异的是,同样的操作,连公司另一台Debian服务器就贼快,敲完用户名1秒钟就能输密码。这就奇怪了,难道CentOS天生有毛病?

先说说我是怎么发现问题的

周末在家闲着没事,我就琢磨这事儿。既然Debian快CentOS慢,那肯定是配置上有区别。于是我决定用调试模式看看SSH连接过程到底在干啥。

先测CentOS这台慢的:

ssh -v test_user@192.168.1.100

敲完这个命令,终端哗啦啦输出一堆日志。我盯着屏幕看,前面一切正常,到了认证那块突然就卡住了。日志里出现了这几行:

debug1: Next authentication method: gssapi-keyex
debug1: No valid Key exchange context
debug1: Next authentication method: gssapi-with-mic
debug1: Unspecified GSS failure. Minor code may provide more information
Cannot determine realm for numeric host address

然后就是反复重试,每次都报错”Cannot determine realm for numeric host address”,一直折腾了半分钟才放弃,进入下一个认证方式。

再看Debian这台快的:

用同样的命令测试,日志里压根就没出现gssapi相关的内容,直接就是publickey和password两种认证方式,刷刷刷就过去了。

看到这我就明白了,问题出在GSSAPI认证上。

GSSAPI是个啥玩意儿?

说实话我之前也不太懂这东西。查了半天资料才搞清楚,GSSAPI全称Generic Security Services Application Program Interface,听着挺高大上,其实就是个安全认证的接口标准,最常见的实现是基于Kerberos的。

简单说,它是用来做企业级身份认证的。在大公司里,如果部署了Kerberos这套系统,SSH登录时就能用统一的账号密码,不用每台机器单独管理用户。

但问题是:

我们公司压根就没部署Kerberos!

CentOS默认开启了GSSAPI认证,SSH登录时会先尝试这种方式。可是没有Kerberos服务器,这个认证注定要失败。系统就在那傻等,反复尝试,直到超时才罢休。这30多秒的延迟就是这么来的。

解决办法其实很简单

知道了原因,处理起来就容易了。核心思路就是:既然用不上GSSAPI,那就把它关了呗。

有两个方向可以操作:客户端关或者服务端关。

方法一:客户端临时禁用

如果你只是偶尔连某台服务器,懒得改配置,可以在命令行加个参数:

ssh -o GSSAPIAuthentication=no root@192.168.1.100

这样这次连接就不会尝试GSSAPI了,速度立马上来。

但每次都要敲这么长的命令也挺烦的,所以我一般会在客户端配置文件里改:

sudo vim /etc/ssh/ssh_config

找到这一行:

#GSSAPIAuthentication yes

把注释去掉,改成no:

GSSAPIAuthentication no

保存退出,以后从这台机器连任何服务器都不会再尝试GSSAPI了。

如果你只想影响当前用户,不想影响别人,可以改用户目录下的配置:

mkdir -p ~/.ssh
vim ~/.ssh/config

在文件里加上这一行就行:

GSSAPIAuthentication no

方法二:Windows下用PuTTY的处理

公司好多同事用Windows,装的是PuTTY。这个也能改,打开PuTTY的配置界面:

Connection → SSH → Auth → GSSAPI

把”Attempt GSSAPI authentication”前面的勾去掉就行了。

记得保存Session,不然下次还得重新设置。

方法三:服务端一劳永逸

客户端改的话,每个人都得改一遍,太麻烦。我觉得最省事的办法是直接在服务器上关掉。

登录到那台慢的CentOS服务器,编辑SSH配置:

sudo vim /etc/ssh/sshd_config

找到这两行(可能被注释了):

#GSSAPIAuthentication yes
#UseDNS yes

改成:

GSSAPIAuthentication no
UseDNS no

这里特别注意UseDNS这一项!

我一开始只改了GSSAPI,发现还是慢。后来查日志才发现SSH还会尝试反向DNS查询,根据客户端IP去查主机名,又是一轮超时等待。

UseDNS这个选项在CentOS上默认是yes,即使注释掉也是yes。所以必须显式写上no才能关掉。

改完之后重启SSH服务:

sudo systemctl restart sshd
# 或者老版本系统用
sudo service sshd restart

测试一下效果:

我改完配置后再连这台服务器,从敲命令到输密码,1秒钟不到!之前那种等到怀疑人生的感觉彻底没了。

还碰到个特殊情况

有个同事按我说的改完之后,发现还是慢。我远程帮他看了一眼,发现他们办公室的网络环境比较复杂,有多层NAT,导致SSH连接时还有别的问题。

后来我给他加了几个参数:

vim ~/.ssh/config

加上这些:

Host *
    GSSAPIAuthentication no
    ServerAliveInterval 60
    ServerAliveCountMax 3
    TCPKeepAlive yes

ServerAliveInterval这个参数的作用是每隔60秒发个心跳包,防止长时间无操作被路由器断开。这样即使登录慢点,至少不会莫名其妙掉线。

为什么Debian就不慢?

后来我对比了一下两个系统的默认配置,发现Debian的sshd_config里:

GSSAPIAuthentication no
UseDNS no

这两项默认就是no,所以人家压根不存在这个问题。

CentOS可能是为了企业级应用考虑,默认开启了这些功能。但对于我们这种没有Kerberos环境的普通用户来说,反而成了累赘。

总结一下踩坑经验

  1. SSH登录慢,第一步先用-v参数看日志,别瞎猜。日志会明确告诉你卡在哪个环节。
  2. GSSAPI和UseDNS是两个常见的坑,遇到登录慢基本就是这俩搞的鬼。
  3. 客户端和服务端都可以改,看你的权限和需求。有root权限就改服务端,一劳永逸;没权限就改客户端,也能解决问题。
  4. 改完配置记得重启SSH服务,不然不生效。我见过有人改完配置就去测试,发现没用就说我瞎扯,其实是没重启服务。
  5. 备份配置文件! 改之前先备份一份,万一改错了还能恢复:
    sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
    

写在最后

这次排查SSH慢的问题,前前后后折腾了三天。虽然最终解决方案就是改两行配置,但这个过程让我对SSH的认证机制有了更深的理解。

有时候遇到问题不要急着去百度”SSH慢怎么办”,那些文章千篇一律,抄来抄去。自己动手用-v参数看看日志,往往能更快找到症结所在。

最后提醒一句:生产环境改配置一定要慎重,最好先在测试机器上验证一遍,确认没问题再推广。别问我怎么知道的,上次我一个同事直接在生产环境改SSH配置,结果配错了,所有人都连不上服务器,最后只能让机房的人去现场处理,那叫一个尴尬。

好了,就说这么多,希望能帮到遇到同样问题的你。有啥问题欢迎留言讨论!

原创文章,作者:余初云,如若转载,请注明出处:https://blog.jidcy.com/dynamicip/vpsbh/1208.html

Like (0)
Previous 2025年12月15日 下午2:57
Next 2025年12月15日 下午3:45

相关推荐