1. 为什么说Wireshark是网络排查的必备工具
1.1 Wireshark能解决什么实际问题
搞网络、搞运维、搞安全的,谁还没跟Wireshark 打过几回交道?在我眼里,Wireshark 就是网络世界的“显微镜”。抓包、流量分析、协议拆解、异常流量识别,这些听起来有点吓人的名词,说白了就是一件事情:把网线里跑的比特流变成人能看懂的信息,然后在里面找问题、找规律、找异常。
举几个我自己遇到过的情况你就明白了。某次线上服务突然变慢,前端反馈接口超时,后端说接口处理只要20毫秒——两边都觉得自己没毛病。用Wireshark抓了20000个包,一看TCP握手阶段从客户端到服务端的往返时间已经花了800毫秒,问题根本不在应用逻辑,而是网络路径上丢了几个ACK,触发了大量TCP重传。这类问题,不用Wireshark看谁都说不清。
另一类是学习协议。当年学TCP三次握手,看十遍书不如自己抓一次包。用Wireshark抓一次本机请求,SYN、SYN-ACK、ACK三个包老老实实摆在眼前,sequence number、acknowledgment number、flags标签清清楚楚,比任何图都直观。这就是Wireshark不可替代的地方:它不只给你看结果,还能让你把过程拆开、掰碎、读懂每一步。
1.2 从零开始:安装与首次抓包
很多新手装Wireshark时踩过坑,主要是驱动选错导致抓不到包。这里说下现在的推荐做法。
下载Wireshark后,安装过程中会提示安装Npcap,这个组件是Windows下抓包的核心驱动,一定要勾选。老版本的WinPcap已经停止维护很多年,尽量不要用,在Windows 10及以上系统里Npcap对回环流量、802.11无线流量支持更好。Linux和macOS用户就没这么复杂,普通用户权限跑Wireshark可能提示找不到接口,加sudo就可以了,但这会带来GUI权限问题,后面我会讲怎么规避。
首次启动Wireshark,主界面会列出当前机器所有可用的网络接口。一般选有线网卡(名字通常是Ethernet开头)、无线网卡(Wi-Fi或WLAN开头)或者正在使用的接口。双击接口就开始抓包,再点红色方块停止。第一次抓的话我建议你做个最简单的实验:开抓包后,在终端里ping一下baidu.com,几秒后停止,搜索一下“ICMP”——你会看到四对ICMP Echo request和Echo reply,这就是最基本的“流量”了。
2. 核心功能拆解:过滤、着色与统计
2.1 抓包过滤器VS显示过滤器:两套语法的分水岭
Wireshark最核心的操作是过滤。但很多新手上来就懵——界面上有两个过滤栏,一个是“Capture Filter”,一个是“Display Filter”,到底用哪个?
抓包过滤器(Capture Filter)是在数据包进入Wireshark缓冲区之前就生效的,它用的是BPF语法,只保留符合条件的数据包,其余全部丢弃。效果是省内存、省磁盘,但缺点是如果过滤条件写得太死,比如只抓了tcp,后面想分析DNS就完全没数据了。
显示过滤器(Display Filter)是在抓包之后,对已捕获的数据包做二次筛选,只是“隐藏”不符合条件的包,不会删除数据。比如你抓了一堆包,现在只想看TCP 80端口的流量,输入tcp.port == 80,剩下包全被暂时折叠,改回空就是恢复全部。
我给的实操建议是:日常调试尽量用显示过滤器而不是抓包过滤器,因为完整的数据是分析的基础。只有在明确知道目标流量类型、且流量量巨大到影响磁盘空间和软件流畅度时,才考虑用抓包过滤器。
两个常用场景对比:
| 场景 | 抓包过滤器语法 | 显示过滤器语法 |
|---|---|---|
| 只抓与目标IP的流量 | host 192.168.1.10 | ip.addr == 192.168.1.10 |
| 抓HTTP端口流量 | tcp port 80 | tcp.port == 80 |
| 抓DNS流量 | port 53 | dns |
| 抓ICMP | icmp | icmp |
| 排除某些IP | not host 10.0.0.1 | !(ip.addr == 10.0.0.1) |
显示过滤器的强大还在于它能叠加条件和关键词自动联想,比如我想看“从某个IP发往某个IP的、长度大于1000字节的TCP包”,就直接输入:
ip.src == 192.168.1.10 && ip.dst == 192.168.1.20 && tcp && frame.len > 1000自动补全会逐字段提示,写错了关键字还会标红,非常友好。
2.2 包列表着色规则:一眼看出“不对劲”
Wireshark默认的包列表里,各种协议有不同的底色:TCP SYN包是深灰底、HTTP是绿底、UDP是浅蓝。这套着色规则不只是好看,它是帮助你快速扫一眼抓包结果就能发现问题的手段。
默认规则里最有价值的是:TCP乱序、重传的包会被标成浅红色或黄绿色,这类包一旦出现往往意味着网络丢包或路径质量问题。你还可以自己定义规则:进入View - Coloring Rules,新建一条规则,比如把HTTP状态码为5xx的响应包标成红色背景,这样刷一遍列表,服务端报错就能立刻看见。
自定义着色规则的逻辑是“先匹配先生效”,所以新规则尽量往上排,否则会被前面的规则覆盖掉。这里分享一个我个人的习惯:我会把tcp.analysis.retransmission单独着色成亮橙色,tcp.analysis.duplicate_ack着色成浅黄,这样一旦网络有重传、重复确认,脑子里就有很强烈的警示信号。
2.3 统计菜单:流量分析的高级玩法
很多人在Wireshark里只会看包列表、用过滤,忽略了顶部的“Statistics”菜单。这个菜单里隐藏着不少好用的功能。
Protocol Hierarchy(协议分级):能告诉你捕获的文件里ARP、IPv4、IPv6、TCP、UDP、HTTP、DNS各占多少数据包和字节。我第一次分析一个异常pcap时发现ARP包数量居然占了两成,这显然不正常——正常局域网里ARP率小于1%,当时就顺着这条线索查出了一个ARP扫描行为。
Conversations(会话)和Endpoints(端点):可以看到任意两个IP之间通信了多少包、多少字节,也可以看到某个IP总共产生了多少流量、占带宽比例。排查“谁把出口带宽吃满了”的经典操作就是打开Endpoints,按Bytes列排序,瞬间找到罪魁祸首。
IO Graph(IO图表):一个非常直观的时间轴图表,可以按时间统计每秒的包数或流量字节数。我一般用它看整体流量趋势——如果某个时间点出现一个剧烈的“尖峰”,那大概率是某种突发行为,接下来就会针对这个时间段做重点筛选分析。
3. 协议拆解方法论:从包里面读故事
3.1 TCP三次握手:真实世界的连接建立
协议拆解是抓包分析的基本功,先从TCP三次握手说起。抓包后,用一个简单的显示过滤器tcp.flags.syn == 1,能快速把带SYN标志的包筛出来,再配合时间戳就能看到完整的三次握手握手对。
严格来说,三次握手由三个包构成:
- 客户端发送
SYN=1, seq=0(实际初始序列号是随机的,这里相对序号是0),请求建立连接; - 服务端回复
SYN=1, ACK=1, seq=0, ack=1,表示“收到你的初始序列号+1,并且我也准备好连接了”; - 客户端发送
ACK=1, seq=1, ack=1,完成连接建立。
在Wireshark的包详情面板里,展开Internet Protocol Version 4和Transmission Control Protocol就能看到完整的地址和端口信息,展开TCP头部后还有Flags、Sequence Number、Acknowledgment Number,这些字段的意义在抓包时都一目了然。
这里有个非常关键的细节:Wireshark默认显示的是Relative Sequence Number(相对序列号),首包显示seq=0,这是为了方便阅读。如果你要分析真实的绝对序列号——比如做某些安全分析时——可以在Protocols - TCP里取消勾选Relative sequence numbers,恢复真实值。我第一次做接入设备调试时就是因为没注意相对序号和绝对序号的差别,对照日志时怎么也对不上号。
3.2 DNS查询与响应:扩展位和响应时间
DNS看起来简单,实则细节不少。抓一次DNS请求,过滤器输入dns,你能看到两部分:Query和Response。
Query部分关键字段是Transaction ID、flags里的RD位、Questions区的内容;Response部分除了Transaction ID要跟Query一致外,还要看flags里的QR=1、AA/RA标志,以及Answers区传回的IP。如果有多个IP,会看到Answers里有多个记录,浏览器依次去连接这些IP,这也就是DNS轮询负载均衡的基本原理。
实际分析DNS时,我最关注三个东西:
- 查询类型:A记录是IPv4,AAAA是IPv6。如果一个域名只解析出AAAA但目标设备不支持IPv6,那就会出现“能通但访问很慢”的情况;
- 响应状态:正常是No error,如果看到NXDomain,那就是域名不存在,这时候去查应用层为什么把这个域名拼错了;
- 响应时间:在Wireshark里点击一个DNS查询包,底层Protocol处显示的时间是Queried time,对应响应包的时间是Response time,两个时间差就是DNS解析耗时。我排查过一个“网页首屏慢”的问题,最后发现是DNS服务器故障导致解析耗时3.2秒,浏览器一直在等DNS结果——这种问题看应用日志根本看不出来。
3.3 HTTP/HTTPS:从明文到加密流
HTTP分析相对直观,因为头部都是明文。抓到HTTP请求包后,展开Hypertext Transfer Protocol层级,能看到Method (GET/POST)、Host、User-Agent、Cookie、Referer等信息,Response里有Status Code、Content-Type、Content-Length等字段。右键任意HTTP包选择Follow - HTTP Stream,可以还原出整个HTTP会话的请求和响应内容,就像在日志里看一对消息。
HTTPS就麻烦多了,因为TCP payload被TLS加密了,Wireshark只能看到TLS握手和Application Data记录,看不到里面的明文。但有一种调试方法我很常用:通过SSLKEYLOGFILE环境变量导出TLS会话密钥。
在启动浏览器或应用前,在终端里设置:
export SSLKEYLOGFILE=/path/to/keys.log然后在Wireshark里:Edit - Preferences - Protocols - TLS,在(Pre)-Master-Secret log filename里填上这个文件路径。重新抓包后再打开会话,HTTPS的Application Data就会自动解密,你甚至可以直接在HTTP Stream里看到明文。不过要注意,这种方式只对能控制SSLKEYLOGFILE的本地应用有效,对别人的HTTPS流量是无效的,别拿去做不该做的事——正常的调试场景就够用了。
4. 异常流量识别:在海量数据里发现“不对劲”
4.1 常见异常流量有哪些特征
异常流量识别是整个抓包分析里最有含金量的一部分,它拼的不是“会不会用工具”,而是“对正常基线熟不熟悉”。常见的异常特征我大致归为几类:
- 广播/组播风暴:大量ARP请求、NetBIOS广播或组播包,会瞬间占满二层带宽。特征是在IO Graph上看到平缓的流量曲线突然拉满,协议分级里二层协议的占比异常升高;
- TCP重传/重复确认大量出现:通常意味着网络存在丢包、拥塞或者网卡/链路有问题。重传比例超过2%基本可以认定链路不健康;
- 大量新建连接但几乎无数据交互:典型的扫描行为,比如一个IP在几秒内向同网段的上千个IP发SYN包,然后没有后续握手,这是端口扫描或主机发现的特征;
- DNS请求量异常:一个IP短时间查询大量不相关域名,或者持续查询根本没有解析的域名;
- 大包小包比例失衡:正常业务流量TCP包长多集中在1500字节左右(满MTU),如果大量出现很小的TCP包(几十字节),说明应用在“碎碎念”式通信,或有人在打HTTP请求刷接口。
4.2 实战:如何定位ARP扫描行为
ARP是二层协议,正常只用于IP与MAC的匹配,频率很低。如果某个时刻ARP流量突然暴涨,很可能是扫描行为或网络中有环。
判断方法很简单:在显示过滤器里输入arp,如果发现大量目标IP连续递增的ARP请求,例如连续请求192.168.1.1、192.168.1.2、192.168.1.3……一直到192.168.1.254,这种情况基本可以断定是ARP扫描。此时打开Endpoints面板,看哪个MAC地址发出最多ARP请求,顺着MAC在交换机上定位物理口。
抓包时我习惯同时统计一下ARP请求速率:记录解析开始时间和结束时间,用包数除以时间。如果每秒几十个甚至上百个ARP请求,已经不属于正常范围。真实场景里常见的根因包括:网关设备配置了错误的探测、某个终端上运行了网段扫描工具、或者交换机上存在环路导致广播帧反复兜圈子。
4.3 实战:排查TCP重传与乱序
TCP重传是网络中比较常见也让人头大的问题。Wireshark里TCP重传显示为浅红色,包详情里会明确标注“TCP Retransmission”。有重传意味着发送方在规定时间内没有收到ACK,所以认为包丢了,于是重发。
出现重传后的排查逻辑一般是:
- 先看重传比例:在包列表底部状态栏看数据包统计,或者在Statistics - Capture File Properties里看总包数和重传数,如果重传率偏高,链路大概率有问题;
- 看重传是集中在一个IP还是分散在所有流量中。集中在一个IP,则问题很可能出在这个IP对应的设备或链路;分散在所有流量里,就要怀疑共同链路、路由器或交换机;
- 在Wireshark里分析重传的RTT。选中一个重传包,查看TCP -Timeline - Round Trip Time,如果RTT忽大忽小、重传包出现了跨度极大的等待时间,通常是拥塞或丢包;
- 检查过滤规则:有时重传多是因为抓包链路本身有问题,比如用不稳定的无线网络抓包,抓到的包本身就包含了无线重传。所以分析重传时尽量用有线、用旁路镜像端口。
乱序(Out-of-Order)和重传不同:乱序表示包到达的顺序与序列号不一致,通常是网络多点路径导致,或者接收端缓冲问题。如果是乱序严重,应用层往往会看到数据等待超时,表现为响应延迟。排查思路与重传类似,但更多要关注路由路径是否存在多条等价路径(ECMP),以及交换机上是否启用了基于流量的负载均衡而把同一TCP流打散了。
5. 分析指标与性能瓶颈定位
5.1 IO Graph:一眼看穿流量趋势
性能问题排查时,IO Graph是我必用的工具。它位于Statistics - IO Graph,打开后默认是对整体流量做每秒包数统计,但你可以针对场景自定义。
比如我想看特定服务某段时间的流量趋势,就加上一个过滤条件,类似http && ip.addr == 192.168.1.100,然后选择统计单位是Bytes还是Packets。如果要看带宽占用,把显示单位改成Bytes,Y轴可以选Bytes/Tick,能更直观地看到是否打满了带宽。
一个小技巧是,添加多条过滤条件到同一个IO Graph里,用不同颜色区分。例如同时看TCP重传的包数、HTTP请求的包数和总包数,如果总包数尖峰和HTTP请求尖峰同时发生,说明流量是正常业务造成的;但如果重传尖峰和其他流量尖峰隔离,那网络质量可能就是隐患点。这种多线叠加看图,比单纯看一个总体曲线能多出大量信息。
5.2 如何计算服务响应时间
服务慢到底是慢在网络上还是应用上?这个问题用Wireshark算一次就明白。分几段来测:
- DNS解析耗时:从DNS Query发出到DNS Response返回的时间差;
- TCP建连耗时:从SYN发出到SYN-ACK返回的时间差;
- HTTP请求首字节时间(TTFB):从客户端发出HTTP Request到收到第一个HTTP Response字节的时间。先找到请求包,再右键Follow HTTP Stream,看请求包和响应包之间的时间戳差值。
我常用的操作是:在包列表里显示Time列,Columns上右键选择Column Preferences,可以添加自定义列,把tcp.time_delta(相对前一包的时间差)和http.time(HTTP请求响应时间)作为列展示出来。这样不用点进去,在列表里扫一眼就能看出哪些请求特别慢。
有一次排查一个“接口偶发慢”的问题,用这个方法发现异常请求的TTFB高达3秒,但相关TCP本身建连只要1毫秒,说明问题在网络或后端程序上,不在客户端。再继续跟进发现,3秒正好是TCP SYN重传的超时时间——因为SYN包丢了,客户端等不到SYN-ACK,3秒后重发SYN才连上。所以结论是网络丢包,而不是应用慢。这类判断光看应用日志根本做不出来,只有抓包能定位到精确的协议层时间。
5.3 Expert Infos:让Wireshark帮你总结问题
Wireshark左下角的“Expert Infos”按钮常常被忽略,但其实是个很好的辅助。它会把捕获的数据包分类为Error、Warning、Note、Chat四个等级,展示了Wireshark分析引擎发现的协议异常和潜在问题。
例如它会自动列出TCP重传、重复ACK、零窗口、DNS重传等各类异常。虽然不一定会直接告诉你“故障在哪”,但它相当于一个方向性指引,能帮你快速拿到所有疑似可疑的包序号,再逐一查看详情。对于刚入手协议分析的读者,我建议常看这个面板,它会教你们有哪些异常类型值得关注。
6. 常见问题与排查技巧实录
6.1 为什么只抓到了520字节而不是2090字节
这是后台被问得很多的一个问题:我用Wireshark抓包,为什么一个包明明应该有2090字节数据,列表里却只显示520字节?
原因基本是抓包时设置了快照长度(snaplen)。抓包过滤器对话框里有一个“Limit each packet to”选项,想要完整抓到2090字节的数据,必须保证这个值大于2090。同时如果在Wireshark主界面的“Capture Options”里勾选了“Enable promiscuous mode”旁边的“Limit each packet to X bytes”,也一样会限制每个包记录的字节数。
简单理解:抓包就是把网线上跑的数据复制一份,限制长度相当于只复制每个包的前N个字节,后面的数据直接丢弃。如果N=520,那你只能看到每个包的前520字节,后面的数据对你就“不可见”了。2090字节超过了标准以太网MTU 1500,意味着你抓的是巨型帧(Jumbo Frame,常见于数据中心或高性能存储网络),此时必须把快照长度设得足够大,一般推荐设成65535,既能覆盖绝大部分帧,又不至于内存和磁盘爆掉。
我建议在抓包开始前取消勾选长度限制,或者显式填写65535。因为一旦抓包文件里已经截断的载荷,后续想恢复是不可能了,只能重新抓。
6.2 抓不到本机回环流量
在Windows上抓127.0.0.1的回环流量是一个经典坑。Wireshark默认列表里没有Loopback接口,即使看到了名为“Npcap Loopback Adapter”的接口,也可能抓不到包。解决办法是安装Npcap时勾选“Support loopback traffic”,然后在抓包时选择这个“Npcap Loopback Adapter”而不是有线网卡。
在Linux上就没这个问题,lo接口直接抓。但要注意:在Linux下如果你用的是普通用户,针对lo接口抓包同样需要root权限,Wireshark会提示没有权限打开接口。不建议直接给Wireshark UI加sudo,更稳妥的办法是先用tshark或dumpcap抓包再交给Wireshark分析。
6.3 无线网卡看不到其他设备的流量
绝大多数无线网卡即使在“混杂模式”下,也只能收到发给本机的帧和广播帧,收不到其他设备的单播帧。这是因为无线网络的加密机制和定向传输特性,AP不会把发给A的数据包复制一份给B。
想要抓取无线环境中的其他设备流量,需要用支持RFMON模式(monitor mode)的无线网卡和驱动,在Linux下用airmon-ng等工具启用监听模式,再用Wireshark在Monitor接口上抓包。但这在Windows下非常受限,多数Windows无线网卡驱动不支持monitor mode,这也是为什么做无线抓包的人常备一个Linux笔记本或专门的USB网卡。
6.4 pyshark调用报错
如果你用Python写脚本来调用Wireshark的解析引擎,最常见的问题是版本匹配。pyshark对TShark的版本要求比较严格,新版本的Wireshark(4.x)在某些场景下会和旧版pyshark不兼容,导致抓包时报“TShark not found”或“dumpcap not found”。
解决办法:一是检查pyshark调用时指定的tshark路径是否正确,比如在代码里显式传入:
import pyshark cap = pyshark.LiveCapture(interface='eth0', use_json=True, tshark_path='/usr/local/bin/tshark')二是套用Wireshark官网推荐的TShark路径。第三个建议是:对最新版本Wireshark,尽量升级pyshark到最新版;反之如果项目要求固定旧版,就安装对应旧版Wireshark。这类“环境联调”问题在Windows上尤其多,可以先在命令行直接运行tshark验证一下,如果tshark本身跑不了,pyshark自然也会报错。
另外,在Windows下运行pyshark需要管理员权限,否则Npcap可能不给普通进程开放接口。
6.5 手动查包太累?用tshark做批处理
最后一个经验是,当抓包文件特别大(几百MB甚至几个GB)时,直接在Wireshark GUI里操作会变得非常卡。这时候我会先放弃GUI,用命令行工具tshark做快速统计。
比如想统计一个pcap文件里HTTP请求的数量:
tshark -r capture.pcap -Y "http.request" | wc -l想按IP分组统计流量:
tshark -r capture.pcap -q -z ip_hosts,tree这些统计结果能帮助快速定位重点,再回到Wireshark打开整个文件时就更有目的性,不需要反复拖动和刷新界面。
写在最后的一点个人体会
用了这么多年Wireshark,我越来越觉得抓包这件事本身就特别像“通灵”:所有真实的网络行为其实都变成了数据包里的字段,你只要把它带到Wireshark面前,它就会把客户端难言之隐、服务端的苦衷、网络设备的小动作,一五一十全给你交代出来。但想真正用好它,靠的是对协议的熟悉程度和对异常模式的敏感度——这两样都得靠一次一次实战喂出来。
所以,别怕刚开始看什么都像天书,拿一台平时在用的电脑,开个Wireshark,访问几个网站,抓20分钟的包,再按这篇文章的路子翻一翻协议分级、会话、IO图表,你会发现原来网络里每一天都在发生这么多故事。等你能在几百个包里迅速定位哪条连接有问题、哪些流量不对劲的时候,前面折腾过的所有坑都值了。