首页 / 资讯中心 / 文章详情

Wireshark抓包分析实战:过滤器、TCP排错与长时间捕获

Wireshark抓包分析实战:过滤器、TCP排错与长时间捕获 ★ FEATURED ARTICLE
1. 把 Wireshark 当成网络世界的示波器而不是排错时的最后一根稻草刚入行那会儿我以为 Wireshark 是网络出大问题才请出来的神器平时装都懒得装。后来被现实教育了几次才明白它更像示波器——你不会等板子烧了才想起来去测波形而是在调试的每一步都习惯性看一眼。Wireshark 这款网络数据报分析工具真正值钱的地方不是它能抓包而是它能把网线上流动的电信号翻译成人类能读懂的一次次对话。1.1 它到底在做什么把网线上的电信号翻译成人话网线里跑的东西本质上是高低电平网卡把它们还原成帧操作系统再把帧交给协议栈。Wireshark 做的事就夹在中间它通过抓包驱动向网卡要一份帧的副本然后按协议一层层剥开从以太网头到 IP 头再到 TCP/UDP 头最后到应用层载荷。你在界面上看到的那一行行彩色条目其实是这套解析链条的最终产物。理解这一点非常重要因为它直接解释了两个新手最常见的困惑。第一为什么我明明抓到了包但看不懂——因为 Wireshark 只负责拆不负责解释业务逻辑业务含义要靠你自己脑补。第二为什么有些包抓不到——因为副本是在网卡和驱动这一层拿的如果流量根本没经过你选的那块网卡比如走了别的接口、被交换机隔离、或者被硬件卸载处理掉了Wireshark 再怎么努力也变不出来。我习惯把它的能力拆成三块来看捕获把帧存下来靠 Npcap/libpcap 这类驱动、解码把字节翻译成协议字段靠内置的几百个 dissector、分析过滤、统计、跟踪流、导出对象。新手最容易只盯着中间那块结果抓了一堆包不知道怎么筛老手往往在第一步和第三步上花更多心思。1.2 什么时候该上它什么时候纯属浪费生命有些问题根本不需要抓包。比如网站打不开先 ping、先看 DNS、先换台机器试绝大多数情况五分钟就有结论。真正值得打开 Wireshark 的场景通常有这几个特征问题偶发且无法稳定复现日志里又什么都没写两个系统之间我说我发了他说他没收到需要第三者做证协议交互不符合预期比如握手莫名其妙失败、报文被切成了奇怪的分片性能问题需要看时序比如到底卡在服务端处理还是网络往返。反过来如果是容量规划、长期趋势统计这种需求抓包就是拿错了工具上监控系统更合适。我见过有人为了查为什么慢挂了三天抓包最后导出几十 GB 文件打开就卡死——问题其实在数据库慢查询上。先缩小范围再动用抓包这是我踩过坑之后给自己定的规矩。还有一点心态上的准备Wireshark 给出的从来不是答案而是证据。它能告诉你第 37 号包发生了重传但重传是因为链路丢包还是因为对方没回 ACK得你自己结合拓扑去判断。把它当证物袋不当法官。2. 安装这一步就劝退了不少人驱动、权限和打不开的真实原因下载安装本身没什么难度官网页面找对应平台Windows / macOS / Linux的安装包即可。真正让人栽跟头的是安装过程中的几个选项以及装完之后双击没反应网卡列表是空的这类问题。我帮同事处理过的安装问题九成都出在驱动和权限上跟 Wireshark 本体关系不大。2.1 Npcap 是什么为什么它决定了你有没有网卡可选在 Windows 上Wireshark 自己是没有抓包能力的它依赖一个叫Npcap的驱动早期是 WinPcap现在基本被 Npcap 取代。安装包里一般会捆绑 Npcap你只要在弹出安装向导时别一路无脑下一步就行。有两个选项值得注意第一个是Install Npcap in WinPcap API-compatible Mode如果你手上有依赖老接口的工具勾上比较稳妥。第二个是关于以受限用户身份运行的选项勾选后普通权限也能抓包代价是权限管理稍微绕一点不勾的话每次都得管理员身份启动。Npcap 装好之后打开 Wireshark 的捕获选项你应该能看到一串接口列表比如以太网WLAN本地连接* x以及各种虚拟适配器。看到Adapter for loopback traffic capture这种东西是正常的它负责抓本机回环流量排查本机两个进程通信时特别有用。如果列表是空的八成是 Npcap 没装上、装的时候被安全软件拦了或者你装的是便携版但没装驱动。2.2 装完打不开、拨号上网蓝屏这类问题的排查顺序Wireshark 打不开这个现象我一般按下面的顺序过一遍基本能定位看进程有没有起来。任务管理器里如果能看到 Wireshark 进程但界面不出现多半是窗口跑到了屏幕外或者多显示器配置变了。删掉配置目录里的窗口位置记录通常能解决。看是不是被杀软拦了。抓包驱动天生敏感某些安全软件会直接阻止加载表现就是启动瞬间闪退。看显卡/渲染问题。新版界面基于 Qt某些老显卡驱动会导致白屏或崩溃可以试试禁用硬件加速相关的启动参数。看配置文件损坏。把个人配置目录Windows 下在%APPDATA%\Wireshark临时改名让它以全新配置启动能启动就说明是配置问题。至于网上常提到的拨号上网时触发蓝屏这个具体现象我没有在现场复现过但同类问题的根因通常是第三方网络驱动和系统网络栈之间的冲突——可能是抓包驱动版本过旧、可能是某些安全软件的网络过滤驱动、也可能是系统补丁与驱动不匹配。稳妥的处理方式是先卸载所有网络过滤类驱动再按官方渠道装最新稳定版抓包驱动重启后逐个恢复。不要同时装两套抓包驱动比如 WinPcap 和 Npcap 并存这是最经典的翻车姿势。3. 抓包前的三分钟准备决定了后面三小时的效率我见过太多人打开 Wireshark点一下开始然后对着满屏几万个包发呆。其实在按下开始之前有三分钟的准备动作能省下后面大量的返工。这三分钟里要做的事就两件选对网卡以及在源头把噪声掐掉。3.1 选对网卡为什么默认那块往往不是你要的Wireshark 默认会选它认为最活跃的接口但这个判断经常是错的。判断该选哪块网卡最可靠的办法是看路由。你要抓的目标 IP 走哪块网卡出去就抓哪块。Windows 上route print或者tracert一个目标地址Linux/macOS 上ip route get 1.2.3.4都能告诉你答案。几个容易踩的坑我列一下场景常见误选正确做法本机两个程序通信物理网卡选 loopback / Adapter for loopback虚拟机上排查宿主网卡选虚拟交换机对应的接口容器内应用宿主机默认网卡选 veth / bridge 对应接口无线网络有线网卡选 WLAN 接口并注意混杂模式还有一个概念要澄清混杂模式Promiscuous Mode只在共享介质上有意义。在今天的交换网络里你开不开它基本都只能看到自己这块网卡收发的流量广播除外。想让 Wireshark 看到别人的流量得靠交换机的端口镜像、网络分路器TAP或者在虚拟化环境里把虚拟交换机设成混杂。这一点搞不清楚会浪费很多时间在为什么抓不到别人的包上。3.2 捕获过滤器在源头就把噪声掐掉捕获过滤器用的是BPF 语法它在驱动层就生效不符合条件的包根本不会被记录。这一点和显示过滤器有本质区别后面会细说。常用的几组host 192.168.1.50 # 只看这台主机的收发 src host 192.168.1.50 and dst port 443 tcp port 8080 udp and not port 53 # 排除 DNS 噪声 ether host 00:11:22:33:44:55 # 按 MAC 过滤写捕获过滤器时我有个习惯宁可先窄后宽。一开始就限定 IP 和端口抓个几十上百个包看清楚交互模式再决定要不要放宽。反过来先抓个几 GB 再回头筛既浪费时间又可能把关键信息淹没。有一点要提醒捕获过滤器写错了不会报错只会什么都抓不到。如果你信心满满地加了过滤条件却发现一个包都没有第一件事就是把它删掉再抓一遍确认不是过滤条件本身写错了。这个坑我踩过至少三次。4. 显示过滤器才是真正的分水岭几个表达式吃一辈子如果只能给新手推荐一项 Wireshark 技能我会毫不犹豫选显示过滤器。抓包谁都会点能不能从几万个包里三秒定位到那三个有问题的包才是水平差距所在。我身边效率高的同事抓包动作都差不多但过滤器输入框里敲的东西又快又准。4.1 捕获过滤器和显示过滤器的语法差异这是新手最容易混淆的地方我直接给对照维度捕获过滤器显示过滤器生效时机抓包前驱动层丢弃抓包后仅隐藏数据是否保留不保留保留可随时改条件语法体系BPF类 tcpdumpWireshark 自有语法语法示例tcp port 80tcp.port 80能否用协议字段不能只有粗粒度能几乎任意字段关键区别在于显示过滤器能访问协议内部的任意字段比如tcp.flags.syn 1、http.host contains api、tls.handshake.type 1。这是捕获过滤器做不到的。所以我的习惯是捕获过滤器只用来砍掉明显无关的流量比如排除掉备份流量精细筛选全部交给显示过滤器。4.2 我常用的几组实战表达式下面这些是我这些年反复用到的几乎覆盖了八成的排查场景ip.addr 10.0.0.5 tcp.port 8080 # 指定主机与会话 tcp.stream eq 7 # 跟踪某一条完整会话 tcp.analysis.flags # 所有异常标记重传/乱序/零窗口 tcp.analysis.retransmission # 只看重传 tcp.flags.syn 1 tcp.flags.ack 0 # 只看 SYN快速定位谁在发起连接 http.request.method POST # 只看 POST 请求 http.response.code 500 # 只看服务端错误 dns.flags.rcode ! 0 # 只看失败的 DNS 响应 frame.time_delta 0.5 # 相邻包间隔大于 500ms frame contains error # 载荷里含特定字符串其中tcp.stream eq N是我用得最多的。右键任意一个包选 Follow → TCP Stream就能把整条会话的载荷拼出来同时自动生成对应的 stream 编号。排查请求发出去了但没有响应这类问题时这个功能比看包列表直观得多。frame.time_delta也值得多说一句。它显示的是当前包和上一个包的时间差配合排序能快速找出卡了很久的位置。我处理过一起接口超时问题就是用这个过滤器发现客户端发出请求后中间空了整整 3 秒才有响应——顺着这 3 秒往前追发现是服务端在做一次同步的 DNS 查询。时间维度往往比内容维度更容易暴露问题。5. 把一屏包读成一条结论TCP 会话的阅读顺序抓到了、筛出来了接下来是读。TCP 的包列表信息密度很高新手容易被各种标志位和序号绕晕。我的建议是别从中间开始读而是跟着一次完整的请求从头走到尾把整条链路的时间线先建立起来。5.1 跟着一次请求走一遍从握手到挥手一次典型的请求大致是这样的节奏客户端发 SYN服务端回 SYN-ACK客户端再回 ACK连接建立。然后客户端发请求数据服务端回 ACK服务端处理后发响应客户端回 ACK。最后某一方发 FIN另一方 ACK再反向 FIN/ACK连接关闭。在 Wireshark 里看这条线重点看几个东西握手时间从 SYN 到 SYN-ACK 的时间差反映的是网络往返时延RTT。这个值稳定在几毫秒说明链路健康忽大忽小说明链路有抖动。请求到响应的时间从发请求到收到第一个响应包这里包含服务端处理时间通常是最值得优化的部分。确认与窗口窗口字段反映接收方还有多少缓冲空间窗口一路缩到 0 就是著名的零窗口。我通常会先套一个tcp.flags.syn 1 or tcp.flags.fin 1的快照把这次抓包里所有的连接建立和关闭都列出来看看是不是有大量短连接反复建立。连接建立的开销经常被低估尤其是跨机房调用时一次握手就要一个 RTT。5.2 重传、乱序、零窗口分别对应什么问题这三个异常是 TCP 分析里出现频率最高的但它们的含义完全不同混淆了就会误判方向重传Retransmission意味着发送方在超时或收到重复 ACK 后把某个段又发了一遍。原因可能是真的丢包也可能是 ACK 在路上丢了导致误判。判断依据是看重传的次数和分布零散几次重传在网络里很常见不用太紧张如果短时间内密集重传说明链路质量确实有问题。乱序Out-of-order指包到达的顺序和发送顺序不一致。这在多路径、链路聚合或者某些负载均衡场景下很普遍本身不一定有害因为接收方会缓存重排。但如果乱序严重到触发快速重传就会拖慢整体吞吐。值得注意的一个细节是抓包点自身也可能制造假乱序因为抓包是在某一跳上做的这一跳之后的路径变化你看不到。零窗口Zero Window是接收方告诉发送方我缓冲区满了先别发了。这通常说明接收方的应用层处理速度跟不上而不是网络问题。看到零窗口排查方向应该立刻从网络转向接收端的应用。我遇到过一起网络很慢的投诉最后定位到是接收程序在做同步写磁盘把接收缓冲撑爆了。顺带说一句tcp.analysis.flags这个过滤器它会把所有被 Wireshark 标记为异常的包一次性列出来。排查初期用它扫一遍能快速判断这次抓包干净不干净。但别被它的措辞吓到——它标红了不代表一定有问题很多标记只是提示这里存在某种现象是否构成故障还得结合业务判断。6. 长时间抓包不炸盘环形缓冲、文件切分与自动化Wireshark 长时间抓包怎么操作是个被反复问的问题。答案的核心其实就一句话不要让界面版 Wireshark 一直挂着抓。界面开着抓包意味着每个包都要实时解析、实时刷新列表、实时跑着色规则内存和 CPU 消耗会随着包数量线性上涨几百兆之后必然卡死。6.1 为什么一直挂着是最糟的做法界面版的设计目标是交互分析不是长时间记录。它会把抓到的包全部保留在内存里还会维护一套显示状态。你抓个几小时文件几个 GB打开就得等半天滚动一下卡三秒最后想说算了重新抓——那前面的时间全白费了。正确的做法是把捕获和分析分成两件事捕获交给轻量的命令行工具dumpcap或tshark它只负责往磁盘写文件几乎不解析分析再在另一台机器或者空闲时段用界面版打开。这样做的好处是捕获进程资源占用稳定抓几天都不成问题。6.2 环形缓冲与文件切分的具体配置界面版也有对应的功能在捕获选项的Output标签页里勾选Create a new file automatically设定单个文件大小比如 100 MB或时间比如每 10 分钟。在Ring buffer里填文件数量比如 20 个形成环形缓冲。写满第 20 个文件后自动覆盖第 1 个。这样总占用被限制在 100 MB × 20 2 GB永远不炸盘。命令行的等价做法我用得更多因为可以写进脚本# 单文件 100MB保留 20 个环形覆盖 dumpcap -i eth0 -b filesize:102400 -b files:20 -w /data/cap/capture.pcapng # 按时间切分每 300 秒一个文件 dumpcap -i eth0 -b duration:300 -b files:48 -w /data/cap/capture.pcapngtshark则在dumpcap的基础上多了过滤和字段输出的能力配合-Y显示过滤和-T fields可以做准实时统计# 每抓到 100 个包就统计一下重传次数 tshark -i eth0 -Y tcp.analysis.retransmission -T fields -e frame.number有两个细节必须注意。第一磁盘写入速度要跟得上千兆线速满跑时的持续写入量不容小觑写到慢速盘或者网络盘上会丢包。第二capture buffer 别设太小默认值在突发流量下容易丢可以在捕获选项里调大命令行用-B参数。丢包这件事在抓包侧其实是静默的Wireshark 只能在界面上给你一个警告等你事后分析时才发现关键包没了那种感觉相当难受。我一般的做法是抓包时同时看一眼丢包计数只要不是零就得调整。7. RTP 转视频、TRDP 与蓝牙几个特殊场景的玩法Wireshark 的协议覆盖面非常广有些场景的处理方式跟普通 TCP 排查完全不同值得单独拎出来说说。7.1 把 RTP 流还原成能播放的视频分析音视频质量时光看包列表意义不大最直观的是把 RTP 载荷还原成媒体文件。步骤大致是这样抓包时确认抓全了信令比如 SIP 或 RTSP和媒体RTP流量两者要在一起。打开Telephony → RTP → Show All Streams能看到所有识别出的 RTP 流包括源/目的地址、SSRC、丢包率、抖动等统计。选中目标流点Analyze可以看详细的质量报告点Save Payload把载荷导出来通常得到的是原始编码数据比如 H.264 裸流或 PCM 音频。如果导出的载荷带了 RTP 头干扰可以先在 Decode As 里把端口正确指定为 RTP让 Wireshark 正确剥离头。拿到裸流之后用 ffmpeg 之类的工具封装成可播放文件ffmpeg -f h264 -i payload.h264 -c copy out.mp4 ffmpeg -f s16le -ar 8000 -ac 1 -i payload.pcm out.wav这里的关键前提是编码参数得搞清楚。同一个 SSRC 流里如果编码中途变了或者有丢包导致帧不完整导出来的视频就会花屏甚至解不出来。我一般会先看 RTP 流统计里的丢包率超过一定比例就别指望画面完整了直接看统计数字更有效率。另外 Wireshark 有时能自动识别出 RTP 事件和媒体直接在 Show All Streams 里点播放按钮试听——但实际能播成功的情况不多别把希望都押在这上面。7.2 TRDP 与蓝牙抓包的前置条件TRDP列车实时数据协议这类工业协议基于 UDPWireshark 内置了 dissector但前提是它得知道这个端口上跑的是 TRDP。默认端口对不上的时候需要手动Decode As把对应端口指定为 TRDP。工业协议排查有个特点周期性报文和突发报文混在一起用udp.port xxxx先筛出目标再看frame.time_delta判断周期是否稳定往往比逐个读包快得多。蓝牙抓包的坑主要在于硬件。普通网卡是抓不到蓝牙空口数据的你需要专门的蓝牙嗅探硬件或者利用系统已有的能力。在 Linux 上可以通过 HCI 接口抓在 Windows 上比较常见的做法是导入系统生成的 btsnoop 日志Wireshark 是支持直接打开这类文件的。所以流程往往是先在系统层打开蓝牙日志记录复现问题退出再拿日志到 Wireshark 里分析。这一步的硬件限制经常被忽略很多人在软件里找了半天蓝牙接口其实根本没有可选的东西。8. 卡住、丢包、时间戳不对那些让人怀疑人生的异常用久了总会碰到一些玄学问题界面卡死、抓不到想抓的包、时间戳看起来不对劲。这些问题的成因大多不在协议本身而在工具的运行环境上。8.1 Wireshark 界面卡死或一直转圈的常见原因排在第一位的永远是地址名称解析。当 View 菜单里的 Resolve Network Addresses 打开时Wireshark 会尝试对每个 IP 做反向 DNS 查询。如果 DNS 服务器不可达每个包都要等超时界面就会卡到让人想砸键盘。而抓包时也开着名称解析更糟会让抓包进程也变慢。我的习惯是抓包和分析时都关掉名称解析需要看域名时再手动开或者用dns.qry.name过滤器针对性看。第二个原因是大文件全量加载。一个几 GB 的 pcap 打开时Wireshark 要把所有包都解析一遍。这种情况我一般先用editcap切成小块或者用tshark先做一次过滤再导出# 只把符合条件的前 10000 个包导出成新文件 tshark -r big.pcapng -Y tcp.port 8080 -c 10000 -w small.pcapng第三个原因是着色规则和列配置过多。每加一列每个包都要多算一次着色规则一多滚动时的重绘成本就上去了。排查大文件时我会临时把列精简到最基本的几项。第四个是实时刷新。Capture Options 里的 Update list of packets in real time 和 Automatic scrolling during capture 都会显著影响抓包性能长时间抓包时建议关掉。8.2 时间戳与时钟被忽略的误差来源时间戳这件事我在项目里被坑过一次之后就一直很在意。Wireshark 默认取的是操作系统时钟而普通 PC 的时钟精度和平稳度都很一般更别说还有 NTP 校时带来的跳变。如果你要做的是跨机器的时序分析必须保证两边的时间源一致。几个实操建议捕获选项里可以选用抓包驱动提供的时间戳通常是网卡硬件时间戳精度比系统时钟高不少跨机分析时如果我关心的是相对时间就直接看frame.time_delta它不依赖绝对时钟如果非要看绝对时间那就必须先把各机器的 NTP 状态确认一遍。绝对时间不可信、相对时间可用这是我给这条经验总结的一句话。同样的道理也适用于为什么抓到的包和日志对不上。应用日志用的是应用进程的时钟Wireshark 用的是系统时钟中间还隔着缓冲区刷盘等延迟。做时间线对齐时我一般会找一个特征非常明显的包比如一次唯一的请求作为锚点把两条时间线对齐而不是直接拿时间戳相减。说个我自己的使用习惯收尾。这些年我在每台开发机上都会留一份 Wireshark但真正每天打开它的时间并不多。更多时候我是先用tshark在后台跑一条过滤规则让它安安静静地把可疑流量写进文件等真出问题了再翻出来看。抓包这件事价值不在于你抓了多少而在于你在抓之前就想清楚了要找什么。至于那些高级特性——协议解析脚本、自定义 dissector、配合 Lua 做批处理——我建议先别急着学把过滤器、环形缓冲、TCP 时序这三样用熟了日常排查里九成的问题都够用了。剩下那一成等你真遇到的时候自然会去学而且那时候学起来会比现在顺手得多。
阅读完成 · 觉得有帮助?
咨询建站