第2章 抓包工具:Wireshark基础、tcpdump使用、抓包过滤规则、保存与分析pcap文件
做网络性能调优,说白了就是跟数据包打交道。你连包都抓不到、抓不准,后面分析重传、定位瓶颈就全是空谈。这一章,我把最常用的两个抓包工具——Wireshark和tcpdump,给你讲透。
我个人习惯是:生产环境用tcpdump,本地分析用Wireshark。为什么?生产服务器上通常没有图形界面,tcpdump轻量、不挑环境;而Wireshark的图形化分析能力,能让你一眼看出问题。
核心观点:抓包不是把网卡上的数据全拷下来就完事了。你得知道抓什么、怎么抓、抓完怎么看。这三步缺一步,后面分析重传就是瞎子摸象。
2.1 tcpdump:生产环境的首选
tcpdump是Linux系统上最经典的命令行抓包工具。它不依赖图形界面,资源占用极低,在嵌入式设备或高负载服务器上都能跑。我记得有一次线上延迟飙高,SSH都快连不上了,硬是靠tcpdump在终端里抓了几秒钟的包,才定位到是某个服务的SYN Flood攻击。
2.1.1 基础用法
先看几个最常用的命令。你不需要记住所有参数,但这几个必须刻在脑子里:
# 抓取eth0网卡上的所有流量
tcpdump -i eth0
# 只抓10个包,抓完自动退出
tcpdump -i eth0 -c 10
# 不进行DNS解析,显示IP地址(推荐)
tcpdump -i eth0 -n
# 显示更详细的信息(协议头细节)
tcpdump -i eth0 -v
# 保存到文件(后面分析用)
tcpdump -i eth0 -w capture.pcap
# 读取pcap文件
tcpdump -r capture.pcap
我的习惯:线上抓包时,我几乎必加 -n 参数。为什么?因为DNS解析会发起额外的网络请求,万一DNS挂了,tcpdump会卡住。而且解析出来的主机名往往没用,反而让输出变得杂乱。
2.1.2 过滤表达式
不设过滤直接抓包,就像在闹市区听所有人说话——你什么都听不清。tcpdump的过滤语法基于BPF(Berkeley Packet Filter),功能非常强大。
我常用的过滤规则:
| 过滤目标 | 表达式示例 | 说明 |
|---|---|---|
| 指定主机 | host 192.168.1.1 |
抓取与192.168.1.1通信的所有流量 |
| 指定端口 | port 80 |
只抓HTTP流量 |
| 指定协议 | tcp 或 udp |
只抓TCP或UDP包 |
| 源/目标 | src 10.0.0.1 / dst 10.0.0.2 |
指定数据流向 |
| 组合条件 | tcp and port 443 and host 10.0.0.1 |
多条件组合,用and/or/not连接 |
| 抓取SYN包 | tcp[tcpflags] & tcp-syn != 0 |
用于分析TCP连接建立 |
举个例子,你想抓取与服务器10.0.0.5之间、端口为443的所有TCP流量,并保存到文件:
tcpdump -i eth0 -n -w https_traffic.pcap tcp and host 10.0.0.5 and port 443
我曾经踩过的坑:有一次线上抓包,我忘了加 -n 参数,结果tcpdump疯狂做反向DNS查询,导致抓包进程本身就把CPU打满了。原本是想排查性能问题,结果自己制造了性能问题。从那以后,-n 就成了我的肌肉记忆。
2.2 Wireshark:图形化分析利器
tcpdump抓完包,生成的是pcap文件。这个文件怎么分析?用Wireshark。它能把二进制包解码成人类可读的协议字段,还能用颜色标记不同类型的包——重传包默认是黑色背景,一眼就能扫出来。
2.2.1 界面速览
Wireshark的界面分三个主要区域:
- 包列表区(上):显示每个包的序号、时间、源/目标IP、协议、长度、信息摘要。重传、重复ACK等异常包会特殊着色。
- 协议树区(中):选中一个包后,这里展示各层协议的字段细节。比如TCP头里的Sequence Number、Acknowledgment Number、Flags等。
- 原始字节区(下):以十六进制和ASCII形式显示包的原始数据。调试自定义协议时特别有用。
你想想看,如果让你在tcpdump的终端输出里找重传,几百行还能忍,几万行呢?Wireshark的图形化界面,说白了就是帮你把「大海捞针」变成「按图索骥」。
2.2.2 显示过滤规则
Wireshark的过滤规则比tcpdump更直观,而且支持自动补全。我常用的几个:
| 过滤目标 | 表达式 | 说明 |
|---|---|---|
| 只看重传包 | tcp.analysis.retransmission |
快速定位重传 |
| 只看重复ACK | tcp.analysis.duplicate_ack |
分析快速重传触发条件 |
| 只看零窗口 | tcp.analysis.zero_window |
接收端窗口耗尽 |
| 指定IP对 | ip.addr == 10.0.0.1 && ip.addr == 10.0.0.2 |
只看两个IP之间的流量 |
| 指定TCP流 | tcp.stream eq 0 |
只看某一条TCP连接 |
关键技巧:在Wireshark里,右键点击一个包,选择"Follow" → "TCP Stream",就能看到这条TCP连接完整的应用层数据交互。分析重传时,我经常先找到重传包,然后Follow这条流,看看重传前后发生了什么。
2.2.3 着色规则
Wireshark默认的着色规则已经够用,但你可以自定义。我个人习惯把重传包改成亮红色背景,这样在大量数据包中能瞬间定位。
设置路径:View → Coloring Rules。你可以新增一条规则,比如:
- 名称:My Retransmission
- 过滤条件:
tcp.analysis.retransmission - 前景色:白色
- 背景色:红色(#FF0000)
嗯,这里要注意:着色规则只影响显示,不影响过滤结果。你改了颜色,过滤出来的包还是那些包,只是看起来更醒目。
2.3 保存与分析pcap文件
抓包不是目的,分析才是。pcap文件是通用的抓包格式,tcpdump和Wireshark都能读写。我建议你养成一个习惯:所有线上抓包都保存为pcap文件,不要只在终端里看几眼就关掉。
为什么?因为线上问题往往不是当场就能分析完的。你抓完包,可能要先恢复服务,等有空了再慢慢看。而且pcap文件可以分享给同事,大家一起分析。
2.3.1 文件管理建议
- 命名规范:
日期_服务器IP_问题描述.pcap,比如20250315_10.0.0.5_http延迟.pcap - 控制文件大小:用
-C参数限制单个文件大小(单位MB),tcpdump会自动轮转:tcpdump -i eth0 -C 100 -w capture.pcap - 环形缓冲区:用
-W参数指定文件数量,防止磁盘写满:tcpdump -i eth0 -C 100 -W 5 -w capture.pcap
2.3.2 分析流程
拿到一个pcap文件,我一般按这个流程走:
- 先看统计概览:Wireshark里点 Statistics → Summary,看总包数、平均速率、丢包统计。
- 过滤重传:输入
tcp.analysis.retransmission,看重传包的数量和分布。 - 定位时间点:找到第一个重传包,看它前后的时间戳,判断是瞬时抖动还是持续问题。
- Follow TCP Stream:右键重传包,Follow这条流,看应用层数据交互是否正常。
- 检查窗口:用
tcp.analysis.window_update或tcp.analysis.zero_window看接收端窗口是否被耗尽。
我的经验:很多重传问题,其实在pcap文件里一眼就能看出来。比如你看到某个包的Sequence Number比前一个包小,那就是重传。或者看到连续三个重复ACK,那基本就是触发了快速重传。这些在Wireshark里都有明确的标记,你只需要知道去哪里看。
2.4 避坑指南
最后,分享几个我踩过的坑,你遇到了可以少走弯路:
- 抓包时间别太长:线上服务器流量大,抓10秒钟可能就生成几百MB文件。我一般先抓30秒看看情况,不够再加。
- 注意磁盘空间:有一次我忘了限制文件大小,结果tcpdump把根目录写满了,服务直接挂了。现在我用
-C和-W成了习惯。 - 不要在生产环境装Wireshark:Wireshark依赖的图形库和插件太多,容易引入安全风险。生产环境只用tcpdump,抓完包传到本地用Wireshark分析。
- 过滤规则先测试:复杂的BPF过滤规则,先用
-d参数看看编译后的伪代码,确认是你想要的:tcpdump -d tcp and port 80