ssh登录非常慢
通过ssh登陆一台linux主机非常慢,基本上每次都在10s以上
1 | [root@localhost ~]# time ssh 192.168.146.104 |
通过ssh -vvv查看建立链接的过程中详细日志,找出最慢的地方出现在哪里
[root@localhost ~]# ssh -vvv 192.168.146.104 OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013 debug1: Reading configuration data /etc/ssh/ssh_config debug1: Applying options for * debug2: ssh_connect: needpriv 0 debug1: Connecting to 192.168.146.104 [192.168.146.104] port 22. debug1: Connection established. <<== 说明发起的连接已经建立成功 debug1: permanently_set_uid: 0/0 debug1: identity file /root/.ssh/identity type -1 debug1: identity file /root/.ssh/identity-cert type -1 ... debug1: Local version string SSH-2.0-OpenSSH_5.3 debug2: fd 3 setting O_NONBLOCK debug1: SSH2_MSG_KEXINIT sent debug3: Wrote 960 bytes for a total of 981 debug1: SSH2_MSG_KEXINIT received ... debug2: mac_setup: found hmac-sha1 debug1: kex: server->client aes128-ctr hmac-sha1 none debug2: mac_setup: found hmac-sha1 debug1: kex: client->server aes128-ctr hmac-sha1 none debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<2048<8192) sent debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP debug3: Wrote 24 bytes for a total of 1005 debug2: dh_gen_key: priv key bits set: 170/320 debug2: bits set: 1026/2048 debug1: SSH2_MSG_KEX_DH_GEX_INIT sent debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY debug3: Wrote 272 bytes for a total of 1277 debug3: check_host_in_hostfile: host 192.168.146.104 filename /root/.ssh/known_hosts debug3: check_host_in_hostfile: host 192.168.146.104 filename /root/.ssh/known_hosts debug3: check_host_in_hostfile: match line 6 debug1: Host '192.168.146.104' is known and matches the RSA host key. debug1: Found key in /root/.ssh/known_hosts:6 debug2: bits set: 1032/2048 debug1: ssh_rsa_verify: signature correct debug2: kex_derive_keys debug2: set_newkeys: mode 1 debug1: SSH2_MSG_NEWKEYS sent debug1: expecting SSH2_MSG_NEWKEYS debug3: Wrote 16 bytes for a total of 1293 debug2: set_newkeys: mode 0 debug1: SSH2_MSG_NEWKEYS received debug1: SSH2_MSG_SERVICE_REQUEST sent debug3: Wrote 52 bytes for a total of 1345 debug2: service_accept: ssh-userauth debug1: SSH2_MSG_SERVICE_ACCEPT received debug2: key: /root/.ssh/identity ((nil)) debug2: key: /root/.ssh/id_rsa ((nil)) debug2: key: /root/.ssh/id_dsa ((nil)) debug2: key: /root/.ssh/id_ecdsa ((nil)) debug3: Wrote 68 bytes for a total of 1413 <<==这一步完后大概等了10s debug1: Authentications that can continue: publickey,password debug3: start over, passed a different list publickey,password debug3: preferred gssapi-keyex,gssapi-with-mic,publickey,keyboard-interactive,password debug3: authmethod_lookup publickey ...
所以通过上面的ssh详细日志可以得出
- tcp连接是成功建立的
- ssh的握手连接是持续进行send和received的
- SSH2_MSG_SERVICE_REQUEST在发送一个68bytes的包时等待了10s
所以在建立链接成功以后,等待了服务端返回某种响应,看起来不像是网络问题,而更可能是服务端的sshd服务的问题。
查看服务端的进程
1 | [root@testyum .ssh]# ps -ef --sort start_time | grep [s]shd |
这里服务端sshd进程是正常运行的,监听端口是22,而当客户端发起ssh连接的过程中,新增了两个进程accepted和net
1 | [root@testyum .ssh]# ps -ef --sort start_time | grep [s]shd |
到这里可以判断服务端也确实建立了连接,置于为什么需要10s,可以用strace命令来进行进一步的分析。
-r
: 打印每个系统调用开始的时间戳-T
: 打印每个系统调用花费的时间-f
: 跟踪和记录子进程-p
: 关联pid并跟踪
1 | strace -o /tmp/1.trc -r -T -f -p 46596 |
将得到的结果根据消耗时间进行排序,找出消耗时间最长的系统调用
1 | [root@testyum ~]# sort -nrk 2 /tmp/1.trc | head |
poll([{fd=4, events=POLLOUT}], 1, 0) = 1
这个系统调用等待了5s,这里可以知道它是在读取文件4fd=4
转过头去从原始trace里去找到descriptor #4是指向的什么,这里通过关键字socket
,connect
,= 4 <
等去搜索
1 | 50382 0.000081 socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 4 <0.000017> |
这个socket()已经创建了一个internet socket(AF_INET),根据SOCK_DGRAM
判断是一个UDP socket,下面的conect ()根据建立的socket去访问192.168.0.1的53端口,因为udp的无状态性质,所以并不会去检查目标主机是否存在和是否响应,所以connect()调用很快就完成了。
我去ping 192.168.0.1这个地址发现无法ping通,通过搜索知道53端口是DNS服务
1 | [root@testyum ~]# grep " 53/" /etc/services |
当发起ssh连接时,sshd服务会去访问DNS服务器,通过nslookup这个ip
1 | [root@testyum ~]# nslookup 192.168.0.1 |
超过10s后,直接报错了,检查服务端的dns配置
1 | [root@testyum ~]# cat /etc/resolv.conf |
这个ip设置的有问题,修改成正确的以后重试
1 | [root@localhost ~]# time ssh 192.168.146.104 |
另外也可以直接修改sshd_config的配置,注释掉UseDNS yes