抓包过滤器入门:让Wireshark只抓你想要的
说实话,我刚用Wireshark那会儿,踩过一个特别蠢的坑。在办公网直接点开始抓包,结果不到30秒,Wireshark就卡死了——抓了上万个包,全是广播、ARP、NetBIOS这些噪音。真正想看的HTTP请求,淹没在数据海洋里,找都找不到。
后来我学乖了。抓包之前,先设个过滤器。这就像你去钓鱼,得先选对鱼塘,而不是把整片海都捞一遍。今天我们就聊聊抓包过滤器——也就是Wireshark里的Capture Filter。
核心概念:抓包过滤器在数据包进入Wireshark之前就生效。它直接告诉网卡:我只收这些包,其他的扔掉。这跟显示过滤器(Display Filter)完全不同,显示过滤器是抓完包之后再筛选。
BPF语法是什么?
Wireshark的抓包过滤器,底层用的是Berkeley Packet Filter(BPF)语法。这玩意儿诞生于90年代初,但到现在依然是网络抓包的事实标准。说白了,BPF就是一套精简的指令集,让网卡驱动在数据包刚到达内核时,就能快速判断“这个包我要不要”。
BPF语法由三部分组成:限定词 + 标识符 + 修饰词。我习惯把它理解成“在什么地方,找什么东西,怎么找”。
| 限定词类型 | 常用值 | 举例 |
|---|---|---|
| 类型(Type) | host, net, port, portrange | host 192.168.1.1 |
| 方向(Dir) | src, dst, src or dst, src and dst | src port 80 |
| 协议(Proto) | ether, ip, ip6, arp, tcp, udp, icmp | tcp port 443 |
举个例子:src host 10.0.0.5 and tcp port 22。翻译成人话就是:“只抓从10.0.0.5发出来的、目标端口是22的TCP包”。嗯,这就是SSH流量。
过滤IP地址:精准定位通信双方
工作中最常用的场景,就是只抓某台机器的流量。比如你怀疑服务器A和服务器B之间有问题,那就只抓它们俩的包。
# 抓取特定主机(双向)
host 192.168.1.100
# 抓取特定源IP
src host 192.168.1.100
# 抓取特定目标IP
dst host 192.168.1.100
# 抓取一个网段(CIDR写法)
net 192.168.1.0/24
# 排除某个IP(用not)
not host 192.168.1.1
我记得有一次排查DNS解析慢的问题。客户说“整个办公室都慢”,但我怀疑是某台打印机的广播流量在捣乱。我直接在抓包机上设了not host 192.168.1.200,把打印机排除掉。结果你猜怎么着?问题还在,但抓包文件从200MB降到了3MB,分析起来轻松多了。
小技巧:如果你只想看某个IP发出的包,用src host;只想看发给它的,用dst host。但大多数时候,host(双向)就够用了。
过滤端口:锁定特定服务
端口过滤,说白了就是“我只想看某个服务的流量”。比如Web服务走80/443,SSH走22,MySQL走3306。
# 抓取特定端口(双向)
port 80
# 抓取源端口
src port 443
# 抓取目标端口
dst port 53
# 抓取端口范围
portrange 8000-8080
# 组合:抓取来自192.168.1.100的HTTP流量
src host 192.168.1.100 and tcp port 80
这里有个坑,我必须要说。很多人以为port 80只抓HTTP,其实它只抓端口号是80的包。如果有人在80端口跑SSH(虽然不常见),你照样会抓到SSH包。所以端口过滤只是“按端口号筛选”,不是“按协议筛选”。
注意:抓包过滤器不支持按服务名过滤。你不能写port http,必须写port 80。Wireshark虽然能识别服务名,但那是在显示过滤器里的事。
过滤协议:只抓你关心的协议
协议过滤是抓包过滤器里最强大的功能之一。你可以指定只抓TCP、UDP、ICMP、ARP等特定协议的数据包。
# 只抓ICMP(ping包)
icmp
# 只抓ARP
arp
# 只抓TCP
tcp
# 只抓UDP
udp
# 只抓IPv6
ip6
# 组合:抓取所有发往DNS服务器的请求
udp port 53
为什么这个功能重要?你想想看,在一个正常的办公网络里,ARP广播和NetBIOS名字解析占了至少30%的流量。如果你只想分析TCP连接问题,直接设tcp,瞬间过滤掉一半以上的噪音。
我曾经帮一个电商团队排查支付接口超时。他们抓了5分钟的包,文件1.2GB。我一看,里面全是Zabbix监控的UDP包和ARP广播。我让他们重新抓,只加了一个tcp and host 10.0.0.50。结果抓了10分钟,文件才80MB。问题很快就定位到了——TCP重传率高达15%。
组合过滤:用逻辑运算符搭积木
真正的生产力,来自组合使用。BPF支持三种逻辑运算符:and(与)、or(或)、not(非)。你可以像搭积木一样,把多个条件拼起来。
# 抓取来自192.168.1.100的HTTP或HTTPS流量
src host 192.168.1.100 and (port 80 or port 443)
# 抓取所有非SSH的TCP流量
tcp and not port 22
# 抓取192.168.1.0/24网段内,发往10.0.0.0/8的DNS查询
src net 192.168.1.0/24 and dst net 10.0.0.0/8 and udp port 53
# 抓取除了广播和多播之外的所有IP包
ip and not broadcast and not multicast
注意括号的使用。BPF的优先级是:not > and > or。如果你不加括号,port 80 or port 443 and host 192.168.1.1会被解析成port 80 or (port 443 and host 192.168.1.1),这很可能不是你想要的。我建议:只要用了or,就加括号。
抓包过滤器 vs 显示过滤器:别搞混了
这是初学者最容易混淆的地方。我专门做个对比表,你一看就明白。
| 对比维度 | 抓包过滤器(Capture Filter) | 显示过滤器(Display Filter) |
|---|---|---|
| 生效时机 | 抓包之前,数据包进入Wireshark之前 | 抓包之后,在已抓取的数据包中筛选 |
| 语法 | BPF语法(简洁、底层) | Wireshark专用语法(丰富、可读性强) |
| 能否恢复数据 | 不能。被过滤掉的包永久丢失 | 能。只是隐藏,数据还在 |
| 性能 | 极高(内核态过滤) | 中等(用户态过滤) |
| 适用场景 | 高流量环境、长时间抓包、嵌入式设备 | 日常分析、事后排查、交互式探索 |
| 示例 | tcp port 80 |
tcp.port == 80 |
我的建议是:能用显示过滤器解决的,就别用抓包过滤器。因为一旦用抓包过滤器过滤掉了某些包,你就再也找不回来了。只有在两种情况下我才会用抓包过滤器:一是流量太大(超过1Gbps),Wireshark扛不住;二是要在嵌入式设备或远程服务器上用tcpdump抓包,带宽有限。
一张图看懂抓包过滤器
下面这张图,是我自己总结的抓包过滤器知识体系。你可以把它当成一个速查地图。
实战:在Wireshark里设置抓包过滤器
光说不练假把式。咱们走一遍实际操作步骤。
- 打开Capture Options:点击Wireshark主界面的齿轮图标,或者菜单栏 Capture → Options。
- 找到输入框:在弹出的窗口里,你会看到一个叫“Capture Filter”的输入框,就在网卡列表的下方。
- 输入BPF表达式:比如你想抓本机与192.168.1.100之间的HTTP流量,就输入
host 192.168.1.100 and tcp port 80。 - 点击Start:开始抓包。你会发现,Wireshark只抓到了符合条件的包,其他的一概不收。
如果你不想每次都手动输入,Wireshark还支持保存常用的过滤器。点击输入框旁边的“Bookmark”按钮(小旗帜图标),就可以把当前过滤器保存下来,下次直接选。
我的习惯:我会把常用的过滤器保存成模板。比如“只抓Web流量”、“只抓DNS”、“排除监控流量”。这样每次排查问题时,直接选模板,省得每次敲一遍。
避坑指南:我踩过的几个雷
最后,分享几个我亲身踩过的坑,你遇到了能少走弯路。
- 坑一:忘了加协议限定。写
port 80没问题,但如果你写host 10.0.0.1,它会同时抓IP和ARP包。因为ARP没有IP地址的概念,host限定词会默认匹配MAC地址。想只抓IP包,记得加ip host 10.0.0.1。 - 坑二:在抓包过滤器里用显示过滤器的语法。我见过有人写
tcp.port == 80,这是显示过滤器的写法。抓包过滤器里要写tcp port 80。两个语法体系完全不同。 - 坑三:过滤条件太宽泛。比如只写
tcp,在高流量环境下依然可能抓爆内存。我建议至少加上IP或端口限定,缩小范围。 - 坑四:忘记括号优先级。前面说过,
not优先级最高,然后是and,最后是or。复杂的表达式,老老实实加括号。
嗯,抓包过滤器就聊到这儿。你只要记住:抓包前先想清楚你要看什么,然后用BPF语法把范围圈定好。这样抓出来的包,干净、精准、好分析。下次我们聊显示过滤器,那个更灵活,但那是后话了。