直接看fin和rst包的源ip即可判断断连发起方:fin来自服务器→sshd主动关闭;来自客户端→本地退出;来自中间设备(如10.0.1.1)→防火墙/nat回收连接;rst无fin则多为中间设备强制中断。

直接看 FIN 和 RST 包的源 IP,就能快速判断是哪一方主动断开或中间设备干预。
聚焦 SSH 或其他 TCP 服务的断连分析
抓包前先复现问题:保持连接空闲几分钟,等它自然断开。断开后立即检查,或提前运行命令持续监听。推荐用:
tcpdump -i any 'host 192.168.1.100 and port 22' -w ssh_break.pcap -G 300
-
192.168.1.100换成你的服务器 IP -
-G 300表示每 5 分钟生成一个新文件,避免漏掉断连前的关键包
如需实时观察细节,加参数输出毫秒级时间戳和 TCP 标志位:
tcpdump -i any -nn -vv -ttt 'host 192.168.1.100 and port 22'
重点识别 FIN 与 RST 包的发起方
TCP 断连本质是连接终止,关键就看两类包:
-
FIN 包:表示“我准备关了”
- 来自服务器 IP → sshd 进程或内核主动关闭
- 来自客户端 IP → 本地终端退出或 SSH 客户端中断
- 来自中间设备(如 10.0.1.1)→ 防火墙、NAT、负载均衡器回收空闲连接
-
RST 包:表示“我不认这个连接了”
- 紧跟 FIN 后出现 → 属正常四次挥手收尾
- 没有 FIN 就突然出现 → 中间设备丢弃保活探测后强行中断,或对端进程已崩溃
用 Wireshark 打开 .pcap 文件,过滤:
tcp.flags.fin == 1 or tcp.flags.reset == 1
按时间排序,查最后几个包的 Source IP 和 Info 字段,基本能锁定断点位置。
配合 ss 命令验证连接状态变化
在服务器上同步运行:
ss -ti dst :22 # 客户端视角(从服务端看客户端) # 或 ss -ti src :22 # 服务端视角(本机发起的连接)
关注字段:
-
lastrcv:最后一次收到数据的时间 -
lastsnd:最后一次发送数据的时间 -
retrans:重传次数是否上升 -
rto:超时时间是否异常增大
如果 lastrcv 停滞超过 300 秒,而抓包里又没看到客户端发来的保活包,说明心跳失效——可能是客户端未启用 ServerAliveInterval,或被中间设备拦截。
排除保活机制是否真正生效
在客户端机器上单独抓保活探测包(排除 FIN/RST 干扰):
tcpdump -i any -nn 'tcp port 22 and (tcp[tcpflags] & (tcp-fin|tcp-rst)) == 0 and greater 64' -w client_keepalive.pcap
SSH 保活包通常为小数据包(如 \0),但部分实现会填充到 64 字节以上;该命令只抓大于 64 字节且非断连标志的包,更易识别真实心跳。
不复杂但容易忽略











