诊断并解决 SSH 连接慢的方法
2016-10-14 16:05
218 查看
CentOS:
SSH远程登录的时候显示的信息如下:
而Debian使用同样的命令测试的结果为:
从上面可以看到,在CentOS中,系统使用了publickey,gssapi-keyex,gssapi-with-mic,和password来进行认证(上面颜色标记行,23行),而Debian此时则使用了Publickey和password两种。在连接CentOS的时候,在23行处花费了相当多的时间。我们在那里开始往下看,就能非常清楚的看到下面的信息:
除了这个方法还有其他方法么?这个自然是有的,CentOS其实就已经提供给我们一个解决方案了——使用ssh远程登录的时候禁用GSSAPI验证。当然,还有一个问题不得不注意,如果你的机器上启用了UseDNS的话,需要一并关闭,具体可参见最后的说明。
从错误可以看出应该是和主机域相关的问题——应该是无法确认IP对应的域,因此会出现这个问题。GSSAPI主要是基于Kerberos的,因此要解决这个问题也就变得要系统配置有Kerberos,这对于没有Kerberos的筒子们来说,配置个Kerberos就为了解决个登录延时问题,似乎不是个明智的决定——特别是在生产环境中!最小化满足需求才是王道。
禁用GSSAPI认证有两个方式:客户端和服务端
比较简单,影响的只有单个客户端用户,可以用下面的方法实现:
用上面的方法登录远程,即可实现禁用GSSAPIAuthentication。
如果你嫌麻烦,直接配置你ssh客户端的文件
这个修改方法是将所有这个机器上的用户都影响到了,如果你影响面不要那么的广泛,只要在指定的用户上实施禁用GSSAPIAuthentication的话,那么你可以在该用户的目录下,找到.ssh目录,在其下面添加
使用cat,直接将输入导出到文件中,这时候,你在使用ssh连接远程的目标主机时,就不会再使用GSSAPI认证了。
上面这些文件是在客户端,不是服务端的。也就是说,要修改这个文件,你的客户端也要是Linux才行。
如果你是在Windows下使用PuTTY这样的客户端工具,就不使用上面这个方法了,PuTTY下可以尝试在连接之前进行设置:
PuTTYConfiguration->Connection->SSH->Auth->GSSAPI->(取消勾选)AttemptGSSAPIauthentication(SSH-2only)
如果没有关闭PuTTY的GSSAPIAuthentication,你可以在连接的窗口右键(或:Ctrl+右键)查看日志,可以发现PuTTY会自动尝试GSSAPI连接的日志:
恩,上面基本上将客户端禁止GSSAPIAuthentication的方法罗列了一下。
注意:上面这些方法是比较通用的。
那么你也可以尝试下如下的客户端解决这个问题的方法:
添加远程主机的主机名到你本机的host文件中(Linux是
添加完毕之后,保存退出。
如果你没有配置Kerberos的话,仅配置这个hosts文件一样是不能解决问题的,在使用ssh登录的时候,你可以看到报错日志会类似下面这样:
这个错误我在刚开始的时候也犯了的,需要注意。
直接到/etc/ssh/sshd_config里面,将GSSAPIAuthenticationyes改为no即可了,同时也请注意,你可能也需要将UseDNS这个也修改成UseDNSno(这个要注意,每个系统的默认值不同,此处以CentOS6为例):
当禁用之后,我们需要重启SSH服务来保证新的配置文件被正确应用:
这个时候,再次使用SSH登录这个主机时,是不是感觉飞快了?
呼~终于完成了这篇长文,要一边捣腾一边弄出这些个文字,还是真是有点困难。不过,这样也就将问题捣腾的差不多了,希望看文章的你能够看的明白,欢迎讨论。
1.GSSAPI:GenericSecurityServicesApplicationProgramInterface,GSSAPI本身是一套API,由IETF标准化。其最主要也是著名的实现是基于Kerberos的。一般说到GSSAPI都暗指Kerberos实现。
2.UseDNS:是OpenSSH服务器上的一个DNS查找选项,而且默认还是打开的,在打开的状态下,每当客户端尝试连接OpenSSH服务器的时候,服务端就自动根据用户客户端的IP进行DNSPTR反向查询(IP反向解析才会有记录),查询出IP对应的Hostname,之后在根据客户端的Hostname进行DNS正向A记录查询。通过这个查询,验证IP是否和连接的客户端IP一致。但绝大部分我们的机器是动态获取IP的,也就是说,这个选项对于这种情况根本就没用——即使是普通静态IP服务器,只要没有做IP反向解析,也难以适用。如果你符合这些情况,建议关闭UseDNS以提高SSH远程登录时候的认证速度。
ssh-vssh_test@192.168.128.137
SSH远程登录的时候显示的信息如下:
OpenSSH_6.0p1Debian-4,OpenSSL1.0.1e11Feb2013
...Somesensitiveinformation...
debug1:Remoteprotocolversion2.0,remotesoftwareversionOpenSSH_5.3
debug1:match:OpenSSH_5.3patOpenSSH_5*
debug1:Enablingcompatibilitymodeforprotocol2.0
debug1:LocalversionstringSSH-2.0-OpenSSH_6.0p1Debian-4
debug1:SSH2_MSG_KEXINITsent
debug1:SSH2_MSG_KEXINITreceived
debug1:kex:server->clientaes128-ctrhmac-md5none
debug1:kex:client->serveraes128-ctrhmac-md5none
debug1:SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192)sent
debug1:expectingSSH2_MSG_KEX_DH_GEX_GROUP
debug1:SSH2_MSG_KEX_DH_GEX_INITsent
debug1:expectingSSH2_MSG_KEX_DH_GEX_REPLY
...Somesensitiveinformation...
debug1:ssh_rsa_verify:signaturecorrect
debug1:SSH2_MSG_NEWKEYSsent
debug1:expectingSSH2_MSG_NEWKEYS
debug1:SSH2_MSG_NEWKEYSreceived
debug1:Roamingnotallowedbyserver
debug1:SSH2_MSG_SERVICE_REQUESTsent
debug1:SSH2_MSG_SERVICE_ACCEPTreceived
debug1:Authenticationsthatcancontinue:publickey,gssapi-keyex,gssapi-with-mic,password
debug1:Nextauthenticationmethod:gssapi-keyex
debug1:NovalidKeyexchangecontext
debug1:Nextauthenticationmethod:gssapi-with-mic
debug1:UnspecifiedGSSfailure.Minorcodemayprovidemoreinformation
Cannotdeterminerealmfornumerichostaddress
debug1:UnspecifiedGSSfailure.Minorcodemayprovidemoreinformation
Cannotdeterminerealmfornumerichostaddress
debug1:UnspecifiedGSSfailure.Minorcodemayprovidemoreinformation
debug1:UnspecifiedGSSfailure.Minorcodemayprovidemoreinformation
Cannotdeterminerealmfornumerichostaddress
debug1:Nextauthenticationmethod:publickey
debug1:Tryingprivatekey:/home/mitchellchu/.ssh/id_rsa
debug1:Tryingprivatekey:/home/mitchellchu/.ssh/id_dsa
debug1:Tryingprivatekey:/home/mitchellchu/.ssh/id_ecdsa
debug1:Nextauthenticationmethod:password
而Debian使用同样的命令测试的结果为:
OpenSSH_6.0p1Debian-4,OpenSSL1.0.1e11Feb2013
...Somesensitiveinformation...
debug1:Remoteprotocolversion2.0,remotesoftwareversionOpenSSH_6.0p1Debian-4
debug1:match:OpenSSH_6.0p1Debian-4patOpenSSH*
debug1:Enablingcompatibilitymodeforprotocol2.0
debug1:LocalversionstringSSH-2.0-OpenSSH_6.0p1Debian-4
debug1:SSH2_MSG_KEXINITsent
debug1:SSH2_MSG_KEXINITreceived
debug1:kex:server->clientaes128-ctrhmac-md5none
debug1:kex:client->serveraes128-ctrhmac-md5none
debug1:sendingSSH2_MSG_KEX_ECDH_INIT
debug1:expectingSSH2_MSG_KEX_ECDH_REPLY
...Somesensitiveinformation...
debug1:ssh_ecdsa_verify:signaturecorrect
debug1:SSH2_MSG_NEWKEYSsent
debug1:expectingSSH2_MSG_NEWKEYS
debug1:SSH2_MSG_NEWKEYSreceived
debug1:Roamingnotallowedbyserver
debug1:SSH2_MSG_SERVICE_REQUESTsent
debug1:SSH2_MSG_SERVICE_ACCEPTreceived
debug1:Authenticationsthatcancontinue:publickey,password
debug1:Nextauthenticationmethod:publickey
debug1:Tryingprivatekey:/home/mitchellchu/.ssh/id_rsa
debug1:Tryingprivatekey:/home/mitchellchu/.ssh/id_dsa
debug1:Tryingprivatekey:/home/mitchellchu/.ssh/id_ecdsa
debug1:Nextauthenticationmethod:password
从上面可以看到,在CentOS中,系统使用了publickey,gssapi-keyex,gssapi-with-mic,和password来进行认证(上面颜色标记行,23行),而Debian此时则使用了Publickey和password两种。在连接CentOS的时候,在23行处花费了相当多的时间。我们在那里开始往下看,就能非常清楚的看到下面的信息:
#下面使用的是GSSAPI-KEYEX来进行验证
debug1:Nextauthenticationmethod:gssapi-keyex
#但是报错:没有可用的Key来交换信息
debug1:NovalidKeyexchangecontext
#系统接着又使用下一个验证方法:GSSAPI-WITH-MIC
debug1:Nextauthenticationmethod:gssapi-with-mic
#但遗憾的是,GSSAPI-WITH-MIC方法也失败。
#原因:不能确定数字主机地址的域
debug1:UnspecifiedGSSfailure.Minorcodemayprovidemoreinformation
Cannotdeterminerealmfornumerichostaddress
debug1:UnspecifiedGSSfailure.Minorcodemayprovidemoreinformation
Cannotdeterminerealmfornumerichostaddress
debug1:UnspecifiedGSSfailure.Minorcodemayprovidemoreinformation
debug1:UnspecifiedGSSfailure.Minorcodemayprovidemoreinformation
Cannotdeterminerealmfornumerichostaddress
#在尝试几次后,SSH认证终于放弃了这种验证。进入下一个验证:Publickey
debug1:Nextauthenticationmethod:publickey
除了这个方法还有其他方法么?这个自然是有的,CentOS其实就已经提供给我们一个解决方案了——使用ssh远程登录的时候禁用GSSAPI验证。当然,还有一个问题不得不注意,如果你的机器上启用了UseDNS的话,需要一并关闭,具体可参见最后的说明。
从错误可以看出应该是和主机域相关的问题——应该是无法确认IP对应的域,因此会出现这个问题。GSSAPI主要是基于Kerberos的,因此要解决这个问题也就变得要系统配置有Kerberos,这对于没有Kerberos的筒子们来说,配置个Kerberos就为了解决个登录延时问题,似乎不是个明智的决定——特别是在生产环境中!最小化满足需求才是王道。
下面先放出处理GSSAPI的方法
禁用GSSAPI认证有两个方式:客户端和服务端
1.客户端禁用
比较简单,影响的只有单个客户端用户,可以用下面的方法实现:ssh-oGSSAPIAuthentication=noyour-server-username@serverIP
用上面的方法登录远程,即可实现禁用GSSAPIAuthentication。
如果你嫌麻烦,直接配置你ssh客户端的文件
/etc/ssh/ssh_config来达到永久解决这个问题:
vi/etc/ssh/ssh_config
###找到ssh_config文件里面的GSSAPIAuthenticationyes这行
###修改为GSSAPIAuthenticationno
###保存ssh_config文件并退出
这个修改方法是将所有这个机器上的用户都影响到了,如果你影响面不要那么的广泛,只要在指定的用户上实施禁用GSSAPIAuthentication的话,那么你可以在该用户的目录下,找到.ssh目录,在其下面添加
config文件,并在文件内添加上面这句,如果没有这个文件,你也可以直接这么做:
cat>>~/.ssh/config<<EOF
GSSAPIAuthenticationno
EOF
使用cat,直接将输入导出到文件中,这时候,你在使用ssh连接远程的目标主机时,就不会再使用GSSAPI认证了。
上面这些文件是在客户端,不是服务端的。也就是说,要修改这个文件,你的客户端也要是Linux才行。
如果你是在Windows下使用PuTTY这样的客户端工具,就不使用上面这个方法了,PuTTY下可以尝试在连接之前进行设置:
PuTTYConfiguration->Connection->SSH->Auth->GSSAPI->(取消勾选)AttemptGSSAPIauthentication(SSH-2only)
如果没有关闭PuTTY的GSSAPIAuthentication,你可以在连接的窗口右键(或:Ctrl+右键)查看日志,可以发现PuTTY会自动尝试GSSAPI连接的日志:
2014-05-1823:46:54UsingSSPIfromSECUR32.DLL
2014-05-1823:46:54AttemptingGSSAPIauthentication
2014-05-1823:46:54GSSAPIauthenticationrequestrefused
恩,上面基本上将客户端禁止GSSAPIAuthentication的方法罗列了一下。
注意:上面这些方法是比较通用的。
2、如果你已经配置了Kerberos的情况下
那么你也可以尝试下如下的客户端解决这个问题的方法:添加远程主机的主机名到你本机的host文件中(Linux是
/etc/hosts,Windows是
系统盘:\Windows\System32\drivers\etc\hosts)。Linux和Windows下都可以添加下面这行。
###注意:下面这样的IP-Addr要替换成你的远程机器的IP地址,HostName,自然是主机名
IP-AddrHostName
添加完毕之后,保存退出。
如果你没有配置Kerberos的话,仅配置这个hosts文件一样是不能解决问题的,在使用ssh登录的时候,你可以看到报错日志会类似下面这样:
debug1:Authenticationsthatcancontinue:publickey,gssapi-keyex,gssapi-with-mi
debug1:Nextauthenticationmethod:gssapi-keyex
debug1:NovalidKeyexchangecontext
debug1:Nextauthenticationmethod:gssapi-with-mic
debug1:UnspecifiedGSSfailure.Minorcodemayprovidemoreinformation
Credentialscachefile'/tmp/krb5cc_0'notfound
debug1:UnspecifiedGSSfailure.Minorcodemayprovidemoreinformation
Credentialscachefile'/tmp/krb5cc_0'notfound
debug1:UnspecifiedGSSfailure.Minorcodemayprovidemoreinformation
debug1:UnspecifiedGSSfailure.Minorcodemayprovidemoreinformation
Credentialscachefile'/tmp/krb5cc_0'notfound
debug1:Nextauthenticationmethod:publickey
这个错误我在刚开始的时候也犯了的,需要注意。
3、服务端禁用GSSAPIAuthentication。
直接到/etc/ssh/sshd_config里面,将GSSAPIAuthenticationyes改为no即可了,同时也请注意,你可能也需要将UseDNS这个也修改成UseDNSno(这个要注意,每个系统的默认值不同,此处以CentOS6为例):sudovi/etc/ssh/sshd_config
###普通用户权限不够,需要root权限
###找到GSSAPIAuthenticationyes,修改为
###GSSAPIAuthenticationno
###注意,这里你也需要将UseDNS修改为no,CentOS默认是yes,即使这行已被注释,你也需要加上
###UseDNSno
###有看到人说UseDNSyes不需要修改为UseDNSno,Mitchell测试下来是需要的。
###保存文件,退出
当禁用之后,我们需要重启SSH服务来保证新的配置文件被正确应用:
servicesshdrestart
这个时候,再次使用SSH登录这个主机时,是不是感觉飞快了?
呼~终于完成了这篇长文,要一边捣腾一边弄出这些个文字,还是真是有点困难。不过,这样也就将问题捣腾的差不多了,希望看文章的你能够看的明白,欢迎讨论。
说明:
1.GSSAPI:GenericSecurityServicesApplicationProgramInterface,GSSAPI本身是一套API,由IETF标准化。其最主要也是著名的实现是基于Kerberos的。一般说到GSSAPI都暗指Kerberos实现。2.UseDNS:是OpenSSH服务器上的一个DNS查找选项,而且默认还是打开的,在打开的状态下,每当客户端尝试连接OpenSSH服务器的时候,服务端就自动根据用户客户端的IP进行DNSPTR反向查询(IP反向解析才会有记录),查询出IP对应的Hostname,之后在根据客户端的Hostname进行DNS正向A记录查询。通过这个查询,验证IP是否和连接的客户端IP一致。但绝大部分我们的机器是动态获取IP的,也就是说,这个选项对于这种情况根本就没用——即使是普通静态IP服务器,只要没有做IP反向解析,也难以适用。如果你符合这些情况,建议关闭UseDNS以提高SSH远程登录时候的认证速度。
相关文章推荐
- 解决ssh连接慢(有时候等半分钟才出现密码输入提示)的方法
- ssh 或 putty 连接linux报错解决方法
- 解决ssh连接慢(有时候等半分钟才出现密码输入提示)的方法
- ssh建立连接缓慢的解决方法
- 电脑无法连接网络并诊断提示DNS服务器未响应的解决方法
- raspberry pi新系统SSH连接被拒绝的解决方法
- SSH连接时出现Host key verification failed的原因及解决方法
- Xshell用ssh连接ubuntu掉线解决方法
- WinXP SSH连接不上虚拟机的解决方法 .
- Linux 远程ssh连接出现:REMOTE HOST IDENTIFICATION HAS CHANGED解决方法
- CentOS6.5 ssh远程连接缓慢解决方法
- 树莓派新系统SSH连接被拒绝的解决方法
- SSH连接本地虚拟机失败解决方法
- Ubuntu终端ssh连接服务器慢的解决方法
- SSH连接Debian出现延迟的解决方法
- SSH连接时出现Host key verification failed的原因及解决方法
- WinXP SSH连接不上虚拟机的解决方法
- SSH连接失败,报错Host key verification failed——原理和解决方法
- WinXP SSH连接不上虚拟机的解决方法
- SSH连接不上Linux的解决方法