3、抓包过滤器:捕获过滤器 vs 显示过滤器、BPF 语法入门、常见过滤表达式
说实话,我见过太多人一上来就开 Wireshark 全量抓包。结果呢?几秒钟就几万条数据包,看得人头皮发麻。这就像在图书馆里找一本书,却把整栋楼的书全搬到你桌上——你根本找不到重点。
所以,过滤器必须学会。而且得学透。
Wireshark 里其实有两套过滤器系统,很多人搞混。我刚开始用的时候也踩过这个坑,抓了半天发现想要的包没抓到,不想要的堆成山。嗯,咱们今天就把这事彻底理清楚。
3.1 捕获过滤器 vs 显示过滤器:到底有啥区别?
简单说,捕获过滤器是在抓包之前就设好的,它决定「哪些包进到内存里」。显示过滤器是抓完之后,在已经抓到的包里做筛选,它决定「哪些包显示在屏幕上」。
你想想看,捕获过滤器就像机场安检——没票的人直接拦在外面,根本进不了候机厅。显示过滤器呢,就像候机厅里的指示牌,告诉你哪些人去哪个登机口。
| 对比维度 | 捕获过滤器 | 显示过滤器 |
|---|---|---|
| 执行时机 | 抓包开始前 | 抓包完成后 |
| 语法基础 | BPF(Berkeley Packet Filter) | Wireshark 自定义表达式 |
| 性能影响 | 高——直接减少抓取量 | 低——只影响显示 |
| 能否恢复数据 | 不能——没抓到的永远没了 | 能——原始数据还在 |
| 典型场景 | 高流量环境、磁盘空间有限 | 事后分析、问题排查 |
3.2 BPF 语法入门:其实没那么玄乎
BPF 全称 Berkeley Packet Filter,是捕获过滤器的底层语言。说白了,它就是一套让网卡知道「哪些包我要,哪些包我不要」的指令集。
我个人习惯把 BPF 语法拆成三块来记:
- 协议关键字:
ether、ip、tcp、udp、arp等 - 方向关键字:
src(源)、dst(目的) - 逻辑运算符:
and(&&)、or(||)、not(!)
组合起来就是:[协议] [方向] [地址/端口] [逻辑] [协议] [方向] [地址/端口]
举个例子:
tcp dst port 80 and not src host 192.168.1.1
这句话的意思是:抓所有发往 TCP 80 端口的包,但排除源地址是 192.168.1.1 的包。你看,是不是很直白?
host 可以同时匹配源和目的。如果你只想匹配单向,一定要加 src 或 dst。我见过有人写 host 10.0.0.5,结果抓到了双向流量,自己还纳闷为什么数据量这么大。
3.3 常见过滤表达式:拿来就能用
下面这些是我工作中最常用的,你直接复制就能用。但别光复制,得理解每一条在干什么。
3.3.1 按 IP 过滤
# 只抓某个 IP 的流量(双向)
host 192.168.1.100
# 只抓从某个 IP 发出的流量
src host 192.168.1.100
# 只抓发往某个 IP 的流量
dst host 10.0.0.1
# 排除某个 IP
not host 192.168.1.1
3.3.2 按端口过滤
# 抓所有 HTTP 流量(80 端口)
tcp port 80
# 抓 HTTPS 流量
tcp port 443
# 抓 DNS 流量(UDP 53)
udp port 53
# 抓某个端口范围
tcp portrange 8000-9000
3.3.3 按协议组合过滤
# 只抓 HTTP 或 HTTPS
tcp port 80 or tcp port 443
# 抓所有非 SSH 的 TCP 流量
tcp and not port 22
# 抓 ICMP(ping)流量
icmp
3.3.4 按 MAC 地址过滤
# 抓某个 MAC 地址的流量
ether host 00:1a:2b:3c:4d:5e
# 抓从某个 MAC 发出的流量
ether src 00:1a:2b:3c:4d:5e
🔑 核心原则:捕获过滤器越精确越好。因为一旦抓漏了,数据就永远回不来了。我一般会先做一个「宽松版」的捕获过滤器,比如只按 IP 或端口过滤,然后在显示过滤器里做更细的筛选。
3.4 一张图看懂过滤器体系
下面这张图是我自己画的,把整个过滤器体系串起来了。你盯着看两分钟,应该就能记住。
3.5 显示过滤器的快速入门
虽然本章重点讲捕获过滤器,但显示过滤器也得提一嘴。因为实际工作中,你往往是两者配合着用。
显示过滤器的语法更灵活,也更强大。比如:
# 显示所有 HTTP GET 请求
http.request.method == "GET"
# 显示所有 TCP 重传包
tcp.analysis.retransmission
# 显示所有 DNS 查询中域名为 example.com 的包
dns.qry.name == "example.com"
# 显示所有 IP 源地址在某个子网内的包
ip.src == 192.168.1.0/24
💡 我的习惯:在 Wireshark 里输入显示过滤器时,它会自动提示补全。你输入 tcp. 就会弹出所有 TCP 相关的字段。这个功能特别好用,我建议你多试试。
3.6 避坑指南:我踩过的那些坑
- 坑一:BPF 里不能用
==——BPF 用=或直接写值,比如tcp port 80而不是tcp.port == 80。后者是显示过滤器的写法。 - 坑二:大小写敏感——BPF 里协议关键字都是小写。
TCP不行,得写tcp。 - 坑三:逻辑运算符优先级——
not优先级最高,然后是and,最后是or。如果你不确定,加括号:tcp and (port 80 or port 443)。 - 坑四:捕获过滤器不支持子网掩码——比如你不能写
ip src 192.168.1.0/24。得写成src net 192.168.1.0/24。
好了,过滤器这块就这些。你先把捕获过滤器练熟,尤其是 BPF 那几条常用表达式。下次遇到高流量环境,你就知道该怎么省着抓了。