Wireshark 抓包教程:过滤器写法与常见问题分析
Wireshark 怎么用:选中有流量的网卡开始抓包,复现问题后停止,再用显示过滤器(如 ip.addr == 203.0.113.10、tcp.flags.syn == 1)筛出相关的包,右键追踪 TCP 流看完整会话。服务器没有图形界面时,用 tcpdump -w 抓成 pcap 文件,下载到电脑上用 Wireshark 打开分析。
Wireshark 是一款开源的抓包和协议分析工具,用法可以概括成四步:在有流量的网卡上开始抓包,复现问题后停止;抓的时候用捕获过滤器(BPF 语法,如 host 203.0.113.10)少抓无关的包;停下以后用显示过滤器(Wireshark 字段语法,如 ip.addr == 203.0.113.10)筛出要看的包;最后右键追踪 TCP 流,看三次握手、重传和每一段的耗时,判断问题出在网络还是应用。机房里的服务器大多没有图形界面,做法是在服务器上用 tcpdump -w 抓成 pcap 文件,下载到自己电脑上用 Wireshark 打开。下面从安装讲到分析,每一步都给出可以照做的操作和过滤表达式。
Wireshark 怎么用:安装并完成第一次抓包
安装。 Windows 上运行官方安装包,安装过程中会一并安装 Npcap,Wireshark 靠它从网卡收包,这一步不要跳过。Linux 上用包管理器安装,并把自己加入 wireshark 组,免得每次都用 root 运行图形界面:
# Debian / Ubuntu:安装时询问是否允许非 root 用户抓包,选“是”
sudo apt install wireshark
sudo usermod -aG wireshark $USER # 重新登录后生效
# RHEL / Rocky / AlmaLinux:图形界面和命令行工具分为两个包
sudo dnf install wireshark wireshark-cli
第一次抓包。
- 打开 Wireshark,启动页列出了所有网卡,每块网卡后面有一条流量小曲线,选曲线在跳动的那块。笔记本上通常是“WLAN”或“以太网”;Linux 上的 any 表示同时抓所有网卡。
- (可选)在网卡列表上方的捕获过滤器输入框里填条件,例如
host 203.0.113.10,只抓与这台服务器相关的包。 - 双击网卡或点左上角蓝色的鲨鱼鳍按钮,开始抓包。
- 去复现问题:打开那个打不开的网页、执行那条连不上的命令。
- 点红色方块停止,按 Ctrl+S 保存为 pcapng 文件,留作对比和交给同事分析。
抓包时间尽量短,只覆盖问题发生的那几秒到几分钟。抓了半小时再在几十万个包里找问题,比重新抓一次还慢。
看懂 Wireshark 界面:分组列表、分组详情与字节
停止抓包后,主窗口分成上中下三块:
| 区域 | 显示什么 | 怎么用 |
|---|---|---|
| 分组列表(上) | 每个包一行:序号 No.、时间 Time、源和目的地址、协议、长度、摘要 Info | 找包、排序,看整体的时间顺序 |
| 分组详情(中) | 选中包的逐层解析:Frame、Ethernet II、IPv4、TCP,再往上是 HTTP、DNS 等 | 展开看具体字段,右键字段可以直接生成过滤条件 |
| 分组字节(下) | 原始十六进制和 ASCII | 核对某个字段的原始值,明文协议能直接读出内容 |
四个设置能明显提高效率:
- 时间列改成“与上一个显示的包的间隔”:View → Time Display Format → Seconds Since Previous Displayed Packet。配合过滤器,一眼看出哪两个包之间等了很久。
- 把常看的字段加成列:在分组详情里右键某个字段,选 Apply as Column(应用为列),例如把
tcp.stream或dns.qry.name加到列表里。 - 右键生成过滤器:右键字段选 Apply as Filter → Selected(作为过滤器应用 → 选中),不用手写表达式。
- 看懂默认配色:浅紫色是 TCP,浅蓝色是 UDP,黑底红字是 Wireshark 判定有问题的 TCP 包(重传、乱序、重复确认、零窗口等),先看黑底的行。
菜单以英文界面为准,中文界面的译名在不同版本中略有出入。
Wireshark 过滤器:捕获过滤器与显示过滤器写法对照
两套过滤器的分工不同:捕获过滤器在抓包前设置,决定哪些包被写进文件,语法与 tcpdump 相同;显示过滤器在抓包后使用,只决定显示哪些包,随时可以改。同一个需求,两种写法对照如下:
| 需求 | 捕获过滤器(BPF) | 显示过滤器 |
|---|---|---|
| 与某台主机相关的所有包 | host 203.0.113.10 |
ip.addr == 203.0.113.10 |
| 只看某台主机发出的包 | src host 203.0.113.10 |
ip.src == 203.0.113.10 |
| 某个网段 | net 203.0.113.0/24 |
ip.addr == 203.0.113.0/24 |
| TCP 443 端口 | tcp port 443 |
tcp.port == 443 |
| 某个端口,不分 TCP、UDP | port 53 |
tcp.port == 53 || udp.port == 53 |
| HTTP | tcp port 80(只能按端口) |
http |
| DNS | port 53(含 TCP 上的 DNS) |
dns |
| 带 SYN 标志的包 | tcp[tcpflags] & tcp-syn != 0 |
tcp.flags.syn == 1 |
| 排除自己的 SSH 会话 | not port 22 |
!(tcp.port == 22) |
| 某个 MAC 地址 | ether host 00:1b:21:3a:4f:10 |
eth.addr == 00:1b:21:3a:4f:10 |
| 不小于 1000 字节的包 | greater 1000 |
frame.len >= 1000 |
几条写法规则和常见错误:
- 两种语法不能互换。把
ip.addr == 203.0.113.10填进捕获过滤器,或者把host 203.0.113.10填进显示过滤器,输入框会变红,说明语法不对。 - 显示过滤器按协议名过滤更准确。
http匹配的是 Wireshark 识别为 HTTP 的包,跑在 8080 端口上的 HTTP 也算;捕获过滤器只认端口号,tcp port 80漏掉 8080。反过来,HTTP 跑在非标准端口时,Wireshark 可能认不出来,右键 Decode As 指定协议即可。 - “不等于”要小心。
ip.addr != 203.0.113.10在 3.6 之前的版本里意思是“源或目的有一个不是它”,几乎会匹配所有包;3.6 起改为“源和目的都不是它”。写成!(ip.addr == 203.0.113.10)在任何版本里含义都一致。 - 逻辑运算:
&&(and)、||(or)、!(not),文本匹配用contains,例如http.host contains "example"。
在机房服务器上抓包,第一件事通常是排除自己的 SSH 会话,否则抓包输出经 SSH 回传又产生新的包,越抓越多。
追踪 TCP 流:看三次握手、重传和连接失败
追踪流。 在任意一个 TCP 包上右键 → Follow → TCP Stream(追踪流 → TCP 流,快捷键 Ctrl+Alt+Shift+T),Wireshark 会自动把显示过滤器设为 tcp.stream eq 5 这样的形式,只留下这一条连接的包,并弹出窗口按顺序拼出双方发送的内容。明文协议(HTTP、SMTP、Redis 等)能直接读出请求和响应;HTTPS 只能看到加密数据,但包的时间和大小照样能分析。
看三次握手。 过滤 tcp.flags.syn == 1,每条连接的前两个包就出来了。一次正常的握手在分组列表里是这样的(示例,客户端侧抓包):
No. Time Source Destination Protocol Length Info
1 0.000000 192.168.1.20 203.0.113.10 TCP 74 51544 → 443 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 SACK_PERM TSval=3011847 TSecr=0 WS=128
2 0.031502 203.0.113.10 192.168.1.20 TCP 74 443 → 51544 [SYN, ACK] Seq=0 Ack=1 Win=65160 Len=0 MSS=1460 SACK_PERM TSval=88123 TSecr=3011847 WS=128
3 0.031580 192.168.1.20 203.0.113.10 TCP 66 51544 → 443 [ACK] Seq=1 Ack=1 Win=64256 Len=0 TSval=3011879 TSecr=88123
Seq=0、Ack=1 是 Wireshark 换算后的相对序号,第 3 个包的 Win=64256 也是按握手时协商的窗口缩放(WS=128)换算后的值,便于阅读。第 1 个包到第 2 个包间隔 31.5 毫秒,在客户端侧抓包时,这就是到服务器的一次往返时间(RTT);在服务器侧抓包时要反过来看,SYN-ACK 到 ACK 的间隔才是 RTT。Wireshark 还会把 SYN 到第 3 个包 ACK 的时间记为 iRTT(字段 tcp.analysis.initial_rtt),这条连接每个包的详情里都能看到,两侧抓包都可以直接参考。
连接失败的几种样子。 连不上的问题,握手阶段的包长什么样,基本就说明了原因:
| 抓到的包 | 说明 | 下一步 |
|---|---|---|
| 只有 SYN,同一个 SYN 每隔 1、2、4、8 秒重发一次(Linux 的默认节奏) | 请求被丢弃,没有任何回应:防火墙、安全组以丢弃方式拦截,或者路由不通 | 到服务器上抓包,看 SYN 有没有到达 |
| SYN 之后立即收到 RST, ACK | 包到了目标主机,但端口没有程序监听;少数防火墙也会用 RST 拒绝 | 在服务器上用 ss 查服务是否在监听 |
SYN 之后收到 ICMP 目标不可达(显示过滤器 icmp) |
防火墙以拒绝方式拦截,例如 iptables 的 REJECT 默认回 ICMP 端口不可达;也可能是沿途路由不可达 | 看 ICMP 包是谁发的、类型和代码是什么 |
| 握手完成,随后服务器发 RST 或 FIN | 网络通,是应用主动关闭:来源不在白名单、连接数满、协议不匹配 | 查应用日志和访问控制 |
看重传。 显示过滤器 tcp.analysis.retransmission 列出所有重传(含快速重传),tcp.analysis.duplicate_ack 列出重复确认。过滤后看窗口底部的状态栏,例如 Displayed: 56 (0.4%),这个百分比就是重传包占全部包的比例,可以作为粗略的重传率。还要分清两个标记:
- TCP Retransmission:发送方重发了已经发过的数据,多数是等到超时(RTO)才重发,意味着丢包,而且会带来明显停顿;收到重复确认后立即重发的,Wireshark 标为 TCP Fast Retransmission,恢复得快得多。
- TCP Spurious Retransmission:重传了对方其实已经确认过的数据,多见于确认包丢失或延迟,数据本身没丢。
抓包位置会影响判断:在发送端抓到的重传,说明数据或确认在抓包点之后的某处丢了;只在接收端抓、却看到缺口和重复确认,说明包在到达之前就丢了。两端同时抓、按序号对照,能定位到丢包发生在哪一侧。
服务器上用 tcpdump -w 抓包,再用 Wireshark 分析
服务器上没有 Wireshark 图形界面,标准做法是“服务器抓、电脑看”:
-
确认网卡名:
ip -br link或tcpdump -D。 -
开始抓包,写入文件而不是打印到屏幕:
tcpdump -i eth0 -nn -s 0 -w /tmp/web-$(date +%F-%H%M).pcap 'host 198.51.100.7 and tcp port 443'
-w 把原始数据写进 pcap 文件,-s 0 保存完整的包(较新的 tcpdump 默认已是完整长度,写上更稳妥),-nn 不解析主机名和端口名。条件和 Wireshark 的捕获过滤器写法完全一样,可以直接复制。
- 控制文件大小。不确定问题什么时候出现、需要长时间挂着抓时,用轮转:
# 每个文件约 100 MB,最多保留 10 个,写满后从第一个开始覆盖
tcpdump -i eth0 -nn -w /tmp/cap.pcap -C 100 -W 10 'host 198.51.100.7'
文件放在 /tmp 这类所有用户都能写的目录:部分发行版的 tcpdump 打开网卡后会降权为 tcpdump 用户运行,轮转出的新文件写不进 /root 会报 Permission denied。
-
复现问题后按 Ctrl+C 停止,看最后三行统计。
packets dropped by kernel不为 0,说明内核来不及处理、有漏抓,分析时要把这个因素考虑进去,下次收紧过滤条件。 -
下载到电脑:
gzip /tmp/web-2026-12-21-1530.pcap # 在服务器上压缩,Wireshark 可以直接打开 .pcap.gz
scp [email protected]:/tmp/web-2026-12-21-1530.pcap.gz . # 在自己电脑上执行
Windows 10 及以后自带 OpenSSH 客户端,PowerShell 里可以直接用 scp,也可以用 WinSCP 这类图形工具。
- 在 Wireshark 里打开,先看 Statistics → Capture File Properties(统计 → 捕获文件属性),确认抓包的起止时间覆盖了问题发生的时刻。pcap 里存的是 UTC 时间戳,Wireshark 按自己电脑的时区显示,对照服务器日志时注意换算;服务器时间不准的话,先校准 NTP。
在服务器上抓的包有两个常见“假问题”,不要误判:
- 包长度超过 1514 字节。服务器网卡开着 TSO、GSO,发出的大数据块在抓包点还没被网卡切分,Wireshark 里会看到几千甚至几万字节的“包”,线路上实际仍是 1500 以内的帧;接收方向开着 GRO 时,多个包合并后才交给抓包程序,也会出现这种超长包。
- 校验和错误。网卡负责计算校验和时,从本机发出的包在抓包点还没有算好校验和。Wireshark 默认不校验 TCP、UDP 校验和;如果你在首选项里打开了校验,看到大量 checksum incorrect 先想到这个原因。
文件不方便下载时,可以直接在服务器上用 tshark(Wireshark 的命令行版本)做初步分析:
tshark -r web.pcap -q -z conv,tcp # 按 TCP 会话统计字节数和持续时间
tshark -r web.pcap -Y 'tcp.analysis.retransmission' | wc -l # 重传包数量
tshark -r web.pcap -q -z expert # 专家信息汇总
tshark -r web.pcap -Y 'dns.flags.response == 1' -T fields -e frame.time_relative -e dns.qry.name -e dns.time
抓包文件里有完整的业务数据,可能包含客户的 Cookie、明文密码,分析完及时删除,不要留在服务器的 /tmp 里。
用时间差定位“慢在哪一段”
“打开网页慢”是最常见的抓包需求。一次 HTTPS 访问可以拆成五段,每段从哪个包算到哪个包、用什么过滤器、偏大说明什么,见下表:
| 阶段 | 从哪个包到哪个包 | 显示过滤器 | 明显偏大说明 |
|---|---|---|---|
| DNS 解析 | 查询 → 应答 | dns,看应答包里的 dns.time |
解析服务器慢,或者丢包后超时重查 |
| TCP 建连 | SYN → SYN-ACK | tcp.flags.syn == 1 |
网络往返时间长,或 SYN 被丢后重发 |
| TLS 握手 | Client Hello → Server Hello | tls.handshake.type == 1 || tls.handshake.type == 2 |
服务器 TLS 处理慢,或证书链大、遇到丢包 |
| 服务器处理 | 请求的最后一个包 → 响应的第一个数据包 | 明文 HTTP 可参考 http.time(默认算到整个响应收完,含传输时间) |
应用或数据库慢,与网络无关 |
| 数据传输 | 响应的第一个包 → 最后一个包 | 叠加 tcp.analysis.flags 看异常 |
有重传、零窗口,或者带宽不够 |
举个例子:一次访问总共 2.6 秒,抓包得到 DNS 应答 0.003 秒、SYN 到 SYN-ACK 0.031 秒、TLS 握手 0.065 秒,而请求发出后 2.4 秒才收到第一个响应数据包,之后的传输只用了 0.1 秒、没有重传。结论很清楚:慢在服务器处理,网络没问题,该去查应用日志和慢查询,而不是找机房换线路。反过来,如果建连阶段 SYN 重发了两次,按 Linux 1 秒、2 秒的重发间隔,建连就多花了约 3 秒,时间耗在了网络丢包上。
明文 HTTP 可以用 http.time > 1 一次筛出所有超过 1 秒才完成的请求;HTTPS 看不到请求内容,就用上面的方法,在追踪流里看客户端最后一个上行数据包和服务器第一个下行数据包之间的时间差。
在管理系统里怎么落地
在机房里抓包,难点往往不在 Wireshark,而在“该在哪台机器、哪个端口上抓”。Toplink DCIM 的实时流量图和网络 TOP 排行能先找出流量异常、占用高的服务器,交换机管理里能直接查到这台服务器上联的交换机和端口号,以及端口速率和所属 VLAN,需要在交换机侧配镜像或查端口计数时,可以在浏览器里打开交换机终端,会话全程录像。服务器网络出了问题、SSH 登不上去时,用 IPMI 远程管理通过 BMC 打开 VNC 控制台,照样可以在服务器上执行 tcpdump,把包写到本地磁盘,等网络恢复后再下载分析。
常见问题
Wireshark 抓不到发往 127.0.0.1 的包怎么办?
本机回环流量不经过物理网卡,要选专门的回环接口:Windows 上选接口列表里由 Npcap 提供的 Adapter for loopback traffic capture;Linux 上选 lo;macOS 上选 lo0。
pcap 和 pcapng 有什么区别?
pcapng 是 Wireshark 现在默认的保存格式,能在一个文件里记录多个接口、注释和名称解析信息;tcpdump 默认写 pcap。Wireshark 两种都能打开,只认 pcap 的老工具可以用 editcap -F pcap 输入.pcapng 输出.pcap 转换。
能用 Wireshark 看 HTTPS 的内容吗?
前提是拿得到会话密钥。在自己的电脑上设置环境变量 SSLKEYLOGFILE 指向一个文件,再启动 Chrome 或 Firefox,浏览器会把每个 TLS 会话的密钥写进去;在 Wireshark 的首选项 Protocols → TLS 里把这个文件填到 (Pre)-Master-Secret log filename,就能解开这台电脑发起的 HTTPS 流量。别人设备上的 HTTPS 拿不到密钥,无法解密。