ssh偶发性登录卡死之谜
现象
今天遇到一个非常诡异的 ssh 登陆失败的情况,:
- 通过 ssh 登陆某主机(假设为user@Server)经常卡死,但经过多次尝试偶尔会出现登陆成功的情况。
- 尝试用 ssh 登陆该主机的其他用户(tmpusr@Server),经常能成功,但是多次尝试会出现偶尔登陆卡死的情况。
- 使用 ssh -vvv user@Server 尝试调试,发现能够正常登陆,而且每次都能登陆成功。
排查过程
- 使用
strace -yo /tmp/ssh.log ssh user@server
追踪系统调用情况,发现卡在了read socket
上了,也就是在等待Server
回复内容一直没等待。 使用
netstat
观察 Client 端的网络链接情况netstat -tuanpe |grep ssh
结果为
(Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp 0 1 10.7.2.3:60078 10.8.24.17:22 SYN_SENT 5000 152156234 4772/ssh
连接状态 SYN_SENT 为 TCP 建立链接三次握手的第一步,表示已经发了SYN信号给Server,但并未收到Server回复的SYN ACK
使用
netstat
观察 Server 端的网络链接情况netstat -an |grep 'ServerIP.22'|grep 'ClientIP'
结果为
tcp4 0 0 ServerIP.22 ClientIP.60078 SYN_RCVD
连接状态 SYN_RCVD 为 TCP 建立链接三次握手的第二步,表示 Server 确实已经收到了 Client 发来的SYN信号,且回复了SYN ACK
- 通过步骤2和3,我们可以推测出 ssh 登陆卡死的原因是 Server 回复的 SYN ACK 没有发送到 Client 端,导致 TCP 链接无法创建起来。
使用 ping 大包的方式检测网络质量
ping -s 65508 ClientIP
结果为
65515 bytes from ClientIP: icmp_seq=0 ttl=63 time=0 ms 65515 bytes from ClientIP: icmp_seq=1 ttl=63 time=0 ms 65515 bytes from ClientIP: icmp_seq=2 ttl=63 time=0 ms 65515 bytes from ClientIP: icmp_seq=3 ttl=63 time=0 ms 65515 bytes from ClientIP: icmp_seq=4 ttl=63 time=0 ms 65515 bytes from ClientIP: icmp_seq=5 ttl=63 time=0 ms
可以判断网络质量并不差
检查Server端的路由配置
netstat -r
结果为
Routing tables Destination Gateway Flags Refs Use If Exp Groups Route Tree for Protocol Family 2 (Internet): default XX.XX.XX.XX UG 3 2048482 en0 - - ClientNet YY.YY.YY.YY UG 2 181966 en2 - - => ClientNet YY.YY.YY.YY UG 1 178100 en0 - -
很惊奇的发现发送到 Client所在网络的路由配了两个,分别使用
en2
和en0
两个网卡- 检查这两个网卡的IP配置发现只有
en2
这个网卡是与网关相通的,而en0
这个网卡并不通。
解决方法
删除多余的错误路由配置后恢复正常。
sudo route del ClientNet dev en0
疑问
虽说问题解决了,但还有些奇怪的现象无法解释:
- 为什么登陆
user◎Server
的成功率低,而登陆tmpusr@Server
的成功率高呢? ssh -vvv user@Server
与ssh user@Server
的登陆过程有什么不同,为什么加了调试项就能正常登陆呢?
希望能有大佬能给出原因。