直接用 tcpdump 过滤 RST 报文的核心是使用 BPF 表达式 tcp[tcpflags] & (tcp-rst) != 0,结合源IP、ACK标志及前后报文上下文判断RST来源(本机/对端)与原因(拒连、乱序、进程强退等),并辅以ss、netstat等命令交叉验证。

直接用 tcpdump 过滤 RST 报文,核心是利用 TCP 标志位(TCP Flags)的 BPF 表达式匹配。RST 是 TCP 控制标志之一,抓取的关键不是“有没有”,而是“怎么写对表达式”并结合上下文判断来源和原因。
基础 RST 抓包命令
执行以下命令即可捕获所有含 RST 标志的 TCP 包:
-
sudo tcpdump -i any 'tcp[tcpflags] & (tcp-rst) != 0' -nn -vv:监听所有接口,显示详细信息,不解析主机名和端口名 - 加
-c 20可限制抓 20 个后自动退出,避免刷屏;加-w rst.pcap可保存为文件供 Wireshark 深度分析 - 若只关注某端口(如 8080),追加条件:
and port 8080 - 若只抓目的端口为 8080 的 RST:
and dst port 8080,更精准定位服务端响应
区分 RST 来源:看源 IP 和 ACK 标志
RST 本身不带错误码,但它的组合特征暴露了行为意图:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 源 IP 是本机 + 不带 ACK(即纯 RST):通常是内核在收到 SYN 到无监听端口时主动拒连,比如服务未启动
- 源 IP 是本机 + 带 ACK(即 RST+ACK):属于 active RST,常见于应用调用
close()时有未读数据、设置了SO_LINGER=0,或系统内存紧张触发tcp_send_active_reset() - 源 IP 是对端 + 带 ACK:说明对方响应了你某个异常报文(如乱序、超窗口、FIN 后又发数据)
- 源 IP 是对端 + 不带 ACK:极少见,可能为协议栈异常或中间设备伪造
结合前后报文确认异常模式
单个 RST 很难定因,需回溯几秒内的通信链路:
- RST 前出现大量重传(Retransmission):网络丢包严重,对端超时后放弃连接
- RST 紧接在 FIN 之后(甚至与 FIN 同一时间戳):进程被
kill -9强杀,四次挥手未完成就由内核代发 RST 清理 - RST 出现在连续零窗口(win 0)通告之后:接收方应用卡死或未消费缓冲区,发送方最终放弃
- RST 出现在本地已发 FIN 后仍收到数据:说明对端未按规范处理关闭状态,或应用层未等待 ACK 就退出
辅助验证当前连接状态
抓包同时运行以下命令交叉印证:
-
ss -tn state established '( dport = :8080 )':确认目标端口是否真有 ESTABLISHED 连接,排除“假连”干扰 -
ss -tn state time-wait | wc -l:检查 TIME_WAIT 连接数是否过高,可能导致新连接被 RST(端口耗尽) -
netstat -s | grep -i "reset":查看内核统计中 RST 发送/接收总数,判断是偶发还是高频事件 -
dmesg | grep -i "orphan\|out of memory\|tcp_mem":排查是否因内存不足或孤儿套接字过多触发内核强制 RST

















