被问过无数次"接口偶发超时,日志干干净净,怎么查",最后基本都是靠一次 Wireshark 抓包把问题钉死的——要么是链路上有 TCP 重传,要么是服务端处理慢到客户端先超时了,要么根本就是 DNS 慢。Wireshark 就是个把网卡上流过的每一个比特摊开给你看的工具:它能告诉你两台机器之间到底聊了什么、谁先沉默、谁在重发、每个人等了多久。这篇东西写给两类人:一类是刚装好 Wireshark、打开界面看着满屏包不知道从哪下手的初学者;另一类是已经会抓包、但总在"筛不出来""字节看不全""一开就卡住"这些细节上栽跟头的老手。下面写的内容都围绕实际操作展开,装完就能用,遇到坑能照着排查。
1. 装好之后先别急着点开始:搞清 Wireshark 到底能看到什么
很多新手第一天就卡在一个错误的预期上——以为装上 Wireshark 就能看到整个办公室的网络。它看到的范围,取决于你把网线插在什么位置、网卡处于什么模式,这一点必须先想明白,否则后面所有分析都是在错误的前提上打转。
1.1 抓包的物理边界:一块网卡能看到多少
普通交换式以太网里,你的网卡默认只收到两类帧:发给自己的(单播)、广播和多播。所以在一台普通办公电脑上抓包,你只能看到这台机器的收发流量,看不到同事之间的对话。要看到更多,只有几个办法:把交换机某个口配成镜像口、在两条链路之间串一个支持汇聚的设备、或者用支持监听模式的无线网卡抓空口。我见过有同事抓了半天只有自己机器的包,然后怀疑 Wireshark 坏了,其实这是网络结构决定的正常现象。
还有一种常见误解是"抓包会不会影响网速"。抓包本身是被动复制,不会拦包、不会改包、不会发成代理,正常情况下对业务透明。真正影响性能的是抓包文件的写入速度和界面渲染:高流量场景下如果还开着实时刷新和着色,UI 线程会跟不上内核收包的节奏,最后表现成底部状态栏那行Dropped:的数字一直往上涨——这才是"抓包把机器拖慢了"的真正原因。
提示:只抓自己有权处理的链路和自有服务,抓下来的 pcap 里可能包含凭据、令牌、内网地址,别随手往外发。
1.2 Windows 上装 Wireshark:Npcap 那几个勾怎么选
Windows 版 Wireshark 本身只是个分析器,真正干活的是驱动Npcap(早期是 WinPcap)。安装过程中会弹出一堆选项,这里逐个说清:
| 安装选项 | 建议 | 原因说明 |
|---|---|---|
| Install Npcap in WinPcap API-compatible Mode | 勾选 | 一些老工具仍依赖 WinPcap 的接口,勾上兼容性更好 |
| Restrict Npcap driver's access to Administrators only | 单人使用可勾,多人共用机器建议不勾 | 勾上后只有管理员组能抓包,安全性更好但非管理员账号会看到空网卡列表 |
| Support raw 802.11 traffic (monitor mode) | 需要抓无线空口时勾 | 只有特定芯片的无线网卡支持监听模式,勾了也不代表一定能用 |
| Install USBPcap | 有 USB 设备排障需求时勾 | 抓 USB 总线,蓝牙 HCI 类流量常靠它 |
| Loopback adapter | 需要抓本机回环时勾 | Windows 默认没有回环网卡,不勾就抓不到 127.0.0.1 的包 |
装完之后有个高频故障:网卡列表是空的,或者只有一个"以太网"却抓不到任何东西。八成是 Npcap 的服务没起来,或者被安全软件拦了驱动加载。可以在服务列表里找npcap相关的项确认状态。另一个坑是机器上装过老版 WinPcap,两者共存会让接口枚举错乱,老老实实卸干净再装。
1.3 Linux 和 macOS 上别一直用 sudo
Linux 下最省事的做法是让普通用户也能调用抓包能力,而不是每次都sudo wireshark(以 root 跑图形程序本身也不是好习惯)。安装时会自动创建一个wireshark用户组,把自己加进去重新登录即可:
sudo dpkg-reconfigure wireshark-common # 选择允许非 root 用户抓包 sudo usermod -aG wireshark $USER # 重新登录后验证 groups | grep wireshark如果因为权限策略不能改组,退而求其次给dumpcap单独加能力:
sudo setcap cap_net_raw,cap_net_admin+eip /usr/bin/dumpcapmacOS 上权限由/dev/bpf*设备控制,官方安装包里带了一个 ChmodBPF 的启动项,装好重启就正常了。如果提示No interfaces found,先看/dev/bpf0的属主和权限对不对。
1.4 界面三个区域各管什么
打开一个 pcap 后,主窗口从上到下是三块:
- 包列表区:一行一个帧,
No.是帧序号,Time是时间戳,Source/Destination是地址,Protocol是最高层协议名,Length是帧长度,Info是协议摘要。这一区域的颜色不是装饰,默认着色规则里黑色背景常表示 TCP 异常(重传、乱序、RST),红色背景常见于各类错误,看到大面积黑色就该警觉了。 - 包详情区:按协议栈从下往上分层,从 Frame、Ethernet II、IP、TCP 一直到应用层,每一层都能展开看字段。这里有个技巧:用
Ctrl+F在详情里搜字节或字符串,比在列表里翻快得多。 - 字节视图区:十六进制加 ASCII,鼠标点在哪个字段,对应字节就会高亮,这是学习一个协议字段到底占几个字节的最直观方式。
界面底部状态栏的信息别忽略,Packets是当前显示/总数,Profile是当前配置档,Dropped是丢包数。抓包过程中如果Dropped有值,说明抓到的数据已经不完整了,任何时间间隔和统计结论都要打折看待。
2. 抓包前花三分钟做准备:网卡、过滤器、写盘策略
新手最容易跳过准备阶段,直接点那个蓝色的鲨鱼鳍图标,然后抓出一堆无关流量,分析阶段全靠硬翻。实际工作中我一般先花几分钟定三件事:抓哪块网卡、用哪个 BPF 表达式、文件怎么落盘。
2.1 选错网卡是第一大坑
Capture 界面里每块网卡后面都有一个小折线图,那是实时流量强度,一直趴在地板上的网卡八成选错了。几个经验判断:
- 虚拟网卡要格外小心。装了虚拟机、容器或者 WSL 的机器上会多出好几块虚拟接口,抓这些接口只能看到主机与虚拟网络之间的流量,看不到真实物理链路。曾经有人排查"生产环境接口超时",结果一直抓的是 WSL 的虚拟网卡。
- 抓本机两个进程之间的通信,必须走回环接口:Linux 是
lo,macOS 是lo0,Windows 需要额外装 Npcap 的回环适配器,否则抓不到。 - 抓 VLAN 里的流量,注意网卡驱动是否剥掉了 VLAN tag,必要时在网卡属性里关掉 VLAN 卸载,否则你看到的二层帧结构会缺少 802.1Q 字段。
- 抓无线空口需要网卡支持监听模式,并且要把网卡切到对应信道,否则只能看到关联到自己所在 AP 的流量。
2.2 抓包过滤器(BPF)和显示过滤器是两回事
这是必须分清的概念,混用会导致"为什么我明明写了过滤器还是抓了一堆无关包"。
| 对比项 | 抓包过滤器(BPF) | 显示过滤器 |
|---|---|---|
| 生效时机 | 数据进入内核之前,不匹配的直接丢弃 | 数据已经在内存里,只影响展示 |
| 语法 | 类 tcpdump 语法,如host 10.0.0.5 and port 443 | Wireshark 自有语法,如ip.addr == 10.0.0.5 && tcp.port == 443 |
| 性能影响 | 显著降低磁盘和内存压力,高流量下必须用 | 不影响抓包,但表达式太复杂会拖慢界面 |
| 能否事后修改 | 不能,没抓到的就永远没有 | 随时改,反复筛 |
我的习惯是:凡是明确知道只关心某个主机或端口,BPF 一定先写上,尤其是长时间抓包。常用表达式抄下来就够用:
host 10.0.0.5 # 与某主机相关的所有流量 net 192.168.10.0/24 # 某个网段 tcp port 443 # 443 端口的 TCP udp portrange 17000-18000 # UDP 端口范围 not arp and not port 53 # 排除 ARP 和 DNS 噪音 host 10.0.0.5 and (port 80 or port 443) ether host 00:1a:2b:3c:4d:5e # 按 MAC 地址括号在 BPF 里很重要,host 10.0.0.5 and port 80 or port 443和host 10.0.0.5 and (port 80 or port 443)完全是两个意思,前者会被解析成(host 10.0.0.5 and port 80) or port 443。
2.3 长时间抓包怎么配才不崩
抓一两个小时不是问题,但抓一整天就要认真配参数了。Capture Options 里几个关键项:
- Snaplen:默认 262144 字节基本等于全量抓。改成 0 表示不限制。反过来,如果你只关心包头(比如统计连接关系),把它设成 96 或 128 能省下大量磁盘,这直接决定了你能不能抓满一整天。
- Buffer size:内核缓冲区,高流量链路上调到 128MB 到 256MB 很常见,太小就会丢包。
- Output 页签的环形缓冲:勾上
Create a new file automatically并配合Ring buffer with N files,就能实现"滚动覆盖"的长时间抓包。比如每 100MB 落一个文件、保留最近 20 个,总共占 2GB 磁盘,一天下来也不会撑爆硬盘,出问题时回看最近那一段就够了。 - Options 页签:把
Update list of packets in real time和Automatic scrolling in live capture关掉,在跑满千兆的链路上这两个选项就是灾难,界面渲染不过来会直接导致内核丢包。抓完再一次性加载。 - 名字解析:务必确认关闭
Resolve network names和Resolve transport names。开着它每抓到新 IP 就发一次 DNS 查询,既慢又脏,还会让抓包文件里混入你自己的查询流量,这同时也是很多人抱怨"Wireshark 抓包时特别卡"的根源。
高流量场景的正解其实是绕开图形界面,直接上命令行抓:
# 后台抓包,每 200MB 一个文件,最多保留 30 个 dumpcap -i eth0 -b filesize:204800 -b files:30 -w /data/cap/run.pcapng把抓包和显示界面彻底分开,机器压力小得多,界面卡死的问题也不存在了。
2.4 文件命名和保存习惯
抓包文件命名我固定用场景_主机_端口_日期时间.pcapng这种格式,比如timeout_api10_443_20240612_1430.pcapng。看起来啰嗦,但一周后你面对十几个 pcap 时就知道这点啰嗦有多值。文件格式优先用.pcapng,它支持多接口、注释和每包元数据,比老的.pcap信息更全,需要给别人时再导出成 pcap。
3. 显示过滤器:把几万个包砍到只剩你要看的那几十个
抓完包最爽的一刻,是过滤器一敲回车,几万个包瞬间只剩二十行。这一节是纯实战,把高频表达式和几个容易写错的细节讲透。
3.1 高频显示过滤器速查表
ip.addr == 10.0.0.5 ip 源或目的等于该地址 ip.src == 10.0.0.5 && ip.dst == 10.0.0.9 tcp.port == 8443 TCP 源或目的端口 udp.port == 17224 tcp.flags.syn == 1 && tcp.flags.ack == 0 只看 SYN tcp.analysis.flags 只看所有 TCP 异常帧(重传/乱序/重复ACK/零窗口) tcp.stream eq 3 只看编号为 3 的那条 TCP 流 http.request.method == "POST" http.response.code >= 500 tls.handshake.type == 1 只看 Client Hello dns.qry.name contains "example" frame.len > 1000 只看大帧 frame.number >= 1200 && frame.number <= 1400tcp.analysis.flags是我个人使用频率最高的一条,它把重传、快速重传、乱序、重复 ACK、零窗口、窗口满这些异常一网打尽。排网络抖动的时候,先来一句tcp.analysis.flags && ip.addr == <目标IP>,有没有问题基本三秒出结论。
3.2 逻辑与比较运算符的写法细节
Wireshark 的显示过滤器接受==、!=、>、<、>=、<=,逻辑运算是&&(与)、||(或)、!(非),也兼容and、or、not。字符串比较用contains(包含)、matches(正则)、==(完全相等)。几个容易踩的点:
ip.addr == 10.0.0.5是"源或目的任一匹配",要限定方向必须写ip.src或ip.dst。- 比较字符串时大小写敏感,
http.host == "api.example.com"和"API.example.com"不是一回事。 - 显示过滤器不会校验逻辑是否合理,写错了只是筛不出东西,不会报错,所以筛不出结果时先怀疑表达式而不是数据。
- 组合复杂条件时用括号,
(tcp.port == 80 || tcp.port == 443) && ip.dst == 10.0.0.9这种写法比省括号安全得多。过滤器输入框变绿才算语法正确,变红就直接告诉你哪一段有问题。
筛到一半想调整条件,有个比手敲更快的方式:在包详情里右键某个字段,选Apply as Filter→Selected,它会自动生成表达式;选Prepare as Filter则只填进输入框让你继续改,这个功能用熟了效率翻倍。想反过来排除,选... and not Selected就行。
3.3 统计 UDP 前后两包的时间间隔
这是个高频需求,也是最容易走弯路的地方:显示过滤器本身不能计算时间差,它只能判断字段值。要拿间隔数据有两条路。
第一条是在界面上做:右键列标题,选Column Preferences,添加一个自定义列,字段名填frame.time_delta_displayed,类型选Delta time displayed。它会显示"当前帧距离上一个被显示的帧"的时间差。这意味着你先用过滤器把目标流量筛出来,这一列就直接是相邻两包的间隔,非常直观。如果填的是frame.time_delta,那算的是相邻两帧(不区分是否被过滤)的差值,两者用途不同,别搞混:
| 字段名 | 含义 | 适用场景 |
|---|---|---|
frame.time_delta | 与上一帧(无论是否显示)的时间差 | 看整体节奏 |
frame.time_delta_displayed | 与上一个被显示帧的时间差 | 筛选后看目标流的间隔 |
tcp.time_delta | 同一 TCP 流内与上一帧的差值 | 看单条连接的交互延迟 |
第二条路是命令行,输出成表格方便二次加工,也方便统计最大/最小/平均值:
tshark -r udp.pcapng -Y "udp && ip.addr==10.0.0.5" \ -T fields -e frame.number -e ip.src -e udp.srcport -e udp.dstport \ -e frame.time_delta_displayed -E separator=, > delta.csv要在几十万包里找"超过 200ms 的间隔",再补一句过滤就行:
tshark -r udp.pcapng -Y "udp && frame.time_delta_displayed > 0.2" \ -T fields -e frame.number -e frame.time_delta_displayed如果是周期性报文(心跳、控制指令),想看有没有丢包导致的间隔异常,我一般会把 delta 列排序后对比:正常情况下间隔应该稳定在某几个值附近,一旦出现 2 倍、3 倍的间隔,基本就是丢了包或者发送方卡住了。这个技巧在排查"偶发丢指令"这类问题上屡试不爽。
3.4 把过滤器存成按钮和配置档
常用的过滤器不必每次手敲。过滤器输入框右侧有个书签图标,点开可以保存当前表达式并起名,之后一键调用。更进一步可以建Profile(配置档),把过滤器按钮、列配置、着色规则、协议首选项打成一包,按场景切换:一个"HTTP 排障"档、一个"TCP 传输质量"档、一个"RTP 语音"档。切换配置档在右下角状态栏,改动了记得保存,否则换个 pcap 打开又回到默认。
4. 一次真实排障:从"网页打开慢"到定位到具体那一帧
光讲过滤器容易变成语法手册,还是拿一个真实场景串一遍完整链路更有说服力。场景是:业务方反馈某个内部管理页面偶尔打开要 8 秒以上,服务器监控指标一切正常。
4.1 先建立基线,别急着找异常
抓包之前我会先明确一件事:正常情况长什么样。同一条链路、同样的操作,抓一次正常打开的包存好,作为基线。没有基线,你看到 8 秒的 TLS 握手也不知道是因为握手本身就慢,还是重传拖的,还是服务端算得慢。
基线抓取注意两点:一是在同一台客户端上抓,客户端性能差异会污染结论;二是把浏览器的缓存和连接复用因素考虑进去,第一次打开和刷新页面走的路径完全不同(一个是完整握手,一个是复用连接),对比时要用同一种操作。
4.2 把 8 秒拆成几段:握手、请求、响应
抓到一次慢的之后,用ip.addr == <服务器IP> && tcp.port == 443筛出这条流,然后打开包详情里的Statistics→Conversations,切到 TCP 页签,能看到这条连接的起止时间、包数、字节数。接着按几个刻度去分段:
- DNS 解析耗时:筛
dns,看查询和响应的frame.time_delta。我之前遇到的"页面慢"里,有三成问题在 DNS,一次解析 2 秒多,超时重试就更久。 - TCP 三次握手耗时:从 SYN 到 SYN/ACK 的间隔就是一次 RTT。同一对地址多次握手,这个值应该稳定。忽大忽小说明链路不稳。
- TLS 握手耗时:从 Client Hello 到 Finished。可以看
tls.handshake.type的各个阶段,Server Hello到Certificate之间如果停很久,可能是服务端证书链太大或临时算密钥慢。 - 首字节时间(TTFB):从发出请求到收到第一个响应字节。这一段长,但前面的握手都正常,八成是服务端处理逻辑慢。
这里有个我非常依赖的判据:在包详情里找 TCP 层的tcp.analysis.initial_rtt字段,它给出这条连接初始往返时延的估算值。如果 initial_rtt 只有几毫秒,但 TTFB 有好几秒,那问题在服务端,网络是无辜的;反过来如果 initial_rtt 本身就几十上百毫秒还波动,那链路或对端确实有问题。这个字段能省掉大量无意义的争论。
4.3 重传、重复 ACK、零窗口怎么认
TCP 层的异常帧都会被打上tcp.analysis系列的标签,在包详情里以[TCP Analysis Flags]的形式出现,列表里也常常整行变黑。常见的几个:
| 标签 | 含义 | 通常意味着 |
|---|---|---|
[TCP Retransmission] | 超时重传 | 包丢了,可能是链路拥塞或不稳定 |
[TCP Fast Retransmission] | 快速重传 | 收到 3 个重复 ACK 后立刻重发,属于快速恢复 |
[TCP Dup ACK] | 重复确认 | 后面通常跟着重传,是乱序或丢包的信号 |
[TCP Out-Of-Order] | 乱序到达 | 多路径或负载均衡常见,未必是故障 |
[TCP ZeroWindow] | 接收窗口为 0 | 接收方处理不过来,应用层是瓶颈 |
[TCP Window Full] | 发送窗口已满 | 发送方在等接收方消费 |
[TCP Keep-Alive] | 保活探测 | 长时间空闲连接的正常现象 |
看到重传不要立刻下结论说网络有问题。少量重传(比如千分之几)在广域网上完全正常。真正要警惕的是短时间内密集重传、伴随重复 ACK 和窗口缩小,那才说明这条链路在某个时刻确实拥塞了。另外有一种特别容易被误判的情况:明明网络很好,却出现大量[TCP Retransmission],原因是抓包点在本机,本机网卡驱动做了大量卸载(TSO/LRO/校验和卸载),Wireshark 看到的是还没被硬件合并的中间状态。遇到这种,抓包前把相关卸载选项关掉再看。
4.4 Statistics 菜单里那几个窗口值得单独用
很多人的分析流程是"看列表、翻详情",其实 Statistics 菜单里有几个窗口能一眼看全局:
- Protocol Hierarchy:按协议分层统计包数和字节数占比。抓完之后第一眼看它,能迅速发现"原来这一半流量都是某个广播或心跳",避免在噪音里做无用功。
- Conversations:按会话聚合,可以分别看 Ethernet、IPv4、TCP、UDP 几个维度,按字节数排序,谁在占带宽一目了然。
- IO Graph:把吞吐量画成曲线,横轴时间纵轴包数/字节数。查"周期性的卡顿"时非常好用,卡顿的时间点和曲线上的空档能直接对上。
- Expert Information:把各种异常汇总成一个列表(重传、校验和错误、畸形包等),点进去能直接跳到对应帧,是个快速体检入口。
- Flow Graph:把一次会话画成时序图,看清谁在什么时候说了什么,讲给别人听的时候特别有说服力。
我在那次 8 秒问题的最后结论是:TCP 握手和 TLS 握手都在 100ms 内完成,但发出 HTTP 请求后 7.6 秒才收到第一个响应字节,同时伴随服务端侧一个[TCP ZeroWindow],说明服务端应用在处理这个请求时把读取缓冲占满了——问题在服务端某个查询缺索引,跟网络没关系。整个过程从抓包到定位不超过二十分钟,因为用的就是上面这套分段方法,而不是在几万个包里乱翻。
5. 那些让人抓狂的显示问题:字节看不全、界面卡死、打不开
Wireshark 有相当一部分问题不在协议本身,而在配置和性能上。这类问题有个共同特点:现象很吓人,原因往往特别小。
5.1 为什么只显示 520 字节,怎么看到完整的 2090 字节
"抓到的包只能显示 520 字节数据"是个经典问题,通常有两个完全不同的原因,搞清楚就能对症下药。
原因一:抓包时设了 Snaplen。打开包详情,看 Frame 层下面那几个字段:
Frame 12: 2090 bytes on wire (16720 bits), 520 bytes captured (4160 bits) on interface eth0on wire是原始长度,captured是实际抓下来的长度。后者小于前者,说明抓包时 snaplen 被限制了,包详情里还会出现[Packet size limited during capture]的提示。这种情况没法补救,因为数据本来就没抓下来,唯一办法是把 snaplen 改成 0 或改大后重新抓。虚拟化环境里还有一种变体:某些虚拟网卡驱动会截断大帧,需要在宿主机一侧抓。
原因二:被截断的是应用层消息,本身被 TCP 分段了。2090 字节的响应体如果超过了 MSS(以太网常见 1460),必然被拆成两个 TCP 段传输。你在列表里看到的是两个包,各 1460 和 630 字节,看起来"不完整",其实数据一点没少。要看到完整内容,有三种做法:
- 右键其中一个包,选
Follow→TCP Stream。它会把整条流的所有载荷按顺序拼起来显示,这是最省事的方式。 - 确认协议首选项里开启重组:
Edit→Preferences→Protocols→TCP,把Allow subdissector to reassemble TCP streams勾上。这样上层协议解析器会把分段拼好再展示(比如一个 HTTP 响应体或一张内嵌的图片),但包列表里仍然是两个独立帧,这一点不会变。 - 需要把响应体导出成文件时,用
File→Export Objects→HTTP,直接把传输过的对象存到本地。
还有一种情况是"字节面板只能看到前面一段"。字节视图面板有水平滚动条,双击某个字段会让视图自动滚到对应位置。面板太矮的时候拖动分隔线拉高即可,这个纯属界面操作问题,但确实困扰过不少人。另外如果包本身长度超过 1500 字节(比如开启了巨型帧的链路上有 9000 字节的帧),首先确认网卡和交换机都支持并启用了巨型帧,其次确认 snaplen 足够大,否则抓到的永远是截断版。
5.2 抓包界面卡住不动怎么办
"Wireshark 为什么一直卡住"这个问题的答案通常是四个之一:
- 开启了网络名称解析。前面提过,每个新 IP 都触发一次 DNS 查询,在离线或受限网络里会一直等超时。关掉
View→Name Resolution下的两项,立刻顺畅。 - 实时刷新 + 高流量。抓高速链路时关闭实时刷新,或者干脆用 dumpcap 抓完再分析。
- 打开了一个超大文件。几百 MB 以上的 pcap 打开时会有明显停顿,这是加载和建索引的过程,耐心等一会儿。长期处理大文件的正确姿势是先用
editcap切片:editcap -c 200000 big.pcapng part.pcapng,切成每 20 万包一个,只加载要分析的那段。 - 表达式太复杂或着色规则太多。过滤器里写正则匹配会明显变慢,着色规则上百条也会拖慢渲染,按需精简。
还有一个容易被忽略的点:Wireshark 会对每个包做完整的协议解析。看到某些畸形包时解析器可能进入长时间的循环处理,表现得就像卡死。这种情况一般是特定版本的 bug,升级到新版(4.x 系列已经很稳定)基本能解决。
5.3 打不开、抓不到、网卡列表为空
按现象对照排查比较快:
| 现象 | 首要怀疑 | 处理方向 |
|---|---|---|
| 启动即崩溃或闪退 | 配置文件损坏 | 删除用户配置目录下的 profile 后重启,或直接重置首选项 |
| 网卡列表为空 | 驱动/权限 | Windows 检查 Npcap 服务;Linux 检查 wireshark 组和 cap 能力 |
| 选了网卡抓不到任何包 | 选错网卡 | 对照实时流量折线图重新选,注意虚拟网卡和回环网卡 |
| 抓本机回环抓不到 | 缺回环接口 | Windows 装 Npcap 时勾选回环适配器;Linux 用 lo |
| 抓到的包全是自己的 DNS | 名字解析开着 | 关闭名称解析重新抓 |
| 底部 Dropped 持续增长 | 缓冲太小或磁盘慢 | 调大 buffer,改用 dumpcap 直接写本地 SSD |
关于"打不开"还有一种情况是文件本身的问题:别人给的 pcap 用了较新的格式,而你本地版本太老。Wireshark 的向下兼容是单向的,新版本能读老文件,老版本读不了新文件。这类问题升级软件比找转换工具省事。
5.4 时间戳和列配置:让数据说人话
默认的时间戳是相对第一个包的秒数,看长时间抓包时很难对应到真实发生时间。View→Time Display Format里改成Time of Day或 UTC 时间,再把Seconds精度调到毫秒或微秒。跨时区协作时统一用 UTC,这一点在分布式系统排查里能省掉一堆换算。
列也可以自己配。我固定会加四列,这样分析时少点很多次鼠标:
tcp.stream 流编号,同一连接一眼识别 tcp.len 该包承载的 TCP 载荷长度,看有没有纯 ACK frame.time_delta_displayed 过滤后的时间间隔 tcp.analysis.ack_rtt 该 ACK 对应的往返时延配置好之后记得在 Profile 里保存,别指望它跨会话自动记住。
6. 再往前一步:TLS 解密、RTP 流还原和非常规链路
到这里基础操作已经够用了,下面这些是"从会用变成用得舒服"的分水岭。
6.1 HTTPS 抓包看到全是密文,怎么解
先明确一件事:现代 TLS(ECDHE 密钥交换)下,光有服务器私钥解不开流量,因为会话密钥是临时协商的,和私钥无关。可行的路径只有一条——拿到客户端的会话密钥日志。前提是你对客户端有控制权,比如调试自己开发的 App 或自己配置的浏览器环境。做法分两步:
第一步,让客户端把密钥写出来。设置环境变量SSLKEYLOGFILE指向一个文件,Chrome、Firefox、以及基于 OpenSSL 的程序都支持这个机制:
# Linux / macOS export SSLKEYLOGFILE=$HOME/keys/sslkeys.log # Windows PowerShell $env:SSLKEYLOGFILE="C:\keys\sslkeys.log"第二步,在 Wireshark 里告诉它去哪读:Edit→Preferences→Protocols→TLS,把(Pre)-Master-Secret log filename指向同一个文件。之后重新打开抓包文件,原本显示为Application Data的帧会变成可读的 HTTP 或 HTTP/2。
几个实战要点:
- 顺序很重要:必须先设置环境变量再启动客户端,已经在跑的进程不会生效,重启客户端。同时 Wireshark 要重新加载 pcap 才应用新配置。
- 如果解出来还是乱码,看是不是 HTTP/2。Wireshark 4.x 默认支持 h2 解码,但早一点的版本需要在 TLS 首选项里把协议端口显式加上,或者确认 ALPN 协商结果确实是你以为的那个协议。
- 解密后的显示过滤器要用
http或http2,而不是tls。tls过滤器在你解密之后往往什么都筛不出来,因为那些帧已经被重新解析到上层协议去了。 - 调试 HTTP/2 时,
http2.headers.path和http2.header.value是最好用的两个字段,再配合Follow→HTTP/2 Stream就能看到单个请求的完整往返。 - 会话密钥文件里包含你能解密的全部会话授权信息,属于敏感材料,用完删除,别提交进代码仓库。
如果抓的是 HTTP/1.1 且用了 RSA 密钥交换(老服务才有),理论上可以配置服务器私钥直接解。但现实里这套早就被弃用了,遇到这种配置先怀疑是不是没有启用前向保密,本身就该修。
6.2 把 RTP 流还原成能播放的音视频
语音和视频质量排查里,媒体流走 RTP,抓到之后最直观的验证方式就是把它导出来听一听、看一看。
音频的步骤:Telephony→RTP→Show All Streams,在列表里选中要分析的流,点Analyze看丢包、抖动、乱序统计,再点Save Payload导成.au或.raw,然后转码:
ffmpeg -f mulaw -ar 8000 -ac 1 -i stream.au -c:a pcm_s16le output.wav参数要按实际的编码类型改,-f mulaw对应 G.711 μ 律,G.711 A 律是alaw,有些编码导出来是裸流.raw,需要用-f指定格式。视频那边同理,把 H.264 载荷存成.h264文件后:
ffmpeg -i stream.h264 -c copy output.mp4两个容易翻车的点:一是RTP 包可能跨越多个抓包文件,如果你是用环形缓冲抓的,可能前半个流在上一个文件里,得用mergecap先合并;二是如果 SDP 里协商了动态载荷类型(96-127),Wireshark 未必能自动识别编码,需要在Telephony→RTP→RTP Player里手动指定 payload type 对应的编码,否则导出的文件是不完整的。丢包统计里Max Delta和Max Jitter这两个值尤其要看,语音质量的问题十有八九体现在抖动上。
6.3 蓝牙、串口和工业协议这类非以太网流量
Wireshark 早就不只是以太网工具了,但每类链路的抓法都有额外门槛。
蓝牙这块,Windows 上内置蓝牙栈不直接暴露 HCI 给 Wireshark。常用做法是用USBPcap抓主机与蓝牙适配器之间那条 USB 总线上的 HCI 流量,安装时勾上 USBPcap,抓包时选对应的 USB 接口,过滤器用bthci或btle。想抓空口上的 BLE 广播和连接,需要专用的嗅探器和配套固件,普通网卡做不到。这里要注意加密连接的信道跳频,普通嗅探器跟不上的时候只能看到广播包。
工业协议方面,很多是基于 UDP 多播的实时控制协议,比如列车通信里常用的 TRDP。抓这类流量的关键有三点:一是网卡必须加入对应多播组或者在支持多播的交换设备上抓(有些交换机默认丢弃未加入组的多播);二是用udp.port或ip.dst多播地址过滤,别指望 BPF 里的host能匹配多播;三是这类流量通常周期性极强,用之前讲的时间间隔列做统计能很快发现丢帧。解析器对不同厂商的扩展字段支持不一,遇到显示为Unknown的载荷,可以先把对应的协议解析器在首选项里启用,或者按原始字节分析。
6.4 交给命令行:tshark、dumpcap 和批量处理
界面适合探索,脚本适合重复劳动。几个常用命令组合值得收进工具箱:
# 从已有文件里提取会话五元组和字节数 tshark -r a.pcapng -q -z conv,tcp # 提取 DNS 查询名和应答 IP tshark -r a.pcapng -Y "dns.flags.response == 1" \ -T fields -e dns.qry.name -e dns.a # 只保留某主机相关的帧另存 tshark -r a.pcapng -Y "ip.addr == 10.0.0.5" -w filtered.pcapng # 切割、合并、去重 editcap -c 100000 big.pcapng sliced.pcapng mergecap -w merged.pcapng part1.pcapng part2.pcapng批量处理多个抓包文件时,把 tshark 的输出重定向到 CSV,再用表格工具做透视,比在界面上一个个点快得多。这也是做容量分析、周期性统计时的标准做法。
7. 长期抓包攒下来的几个习惯
用得久了会形成一些固定动作,这些不写在任何文档里,但确实能显著提高效率。
第一,抓包之前先写下假设。"我怀疑是客户端到网关这一段丢包"和"我怀疑服务端查询慢",对应的抓包位置、过滤器和观察指标完全不同。没有假设就开始抓,最后一定是抓了一堆数据然后不知道看什么。
第二,BPF 先收窄,显示过滤器再细筛。尤其在共享链路或高流量环境,抓下来再筛这个习惯会让你的抓包文件变成垃圾场。
第三,抓完立刻做三件事:看一眼 Expert Information 有没有异常、看一眼 Protocol Hierarchy 的构成、把关键帧加注释或导出。我习惯在关键帧上按Ctrl+M加标记,并写一句注释说明"这里是第一次重传",回头复盘时能省大量时间。
第四,别忽视关闭名字解析和调大缓冲这两个小动作,它们在关键时刻决定了你的数据是否可信。
第五,pcap 文件要当敏感数据对待。里面可能有明文凭据、Cookie、内网拓扑,外发之前用editcap裁掉载荷只保留头部,或者干脆只截图说明问题。
第六,保持版本更新。4.x 之后的分析器和协议支持比老版本好太多,很多"抓不到""解析不出来""界面卡死"的问题在新版里根本不存在。升级的成本远低于和老 bug 搏斗的成本。
第七,建几个按场景划分的配置档并保存好过滤器书签,把个人经验固化成工具配置,下次换个项目直接切换过来,不用从零开始调试界面。