3、捕获过滤器实战:BPF语法基础、基于IP/端口/协议的捕获过滤、捕获过滤器的局限性

各位好,欢迎来到第三章。前两章我们把Wireshark界面和基础操作捋了一遍,从这章开始,咱们要真正动手抓“对”的包了。

你想想看,在一个繁忙的生产环境里,网卡每秒可能经过成千上万个数据包。如果不加筛选地全抓下来,Wireshark很快就会因为内存爆炸而卡死,你也会被海量无关数据淹没。这时候,捕获过滤器就是你最需要的工具。

3.1 BPF语法:捕获过滤器的灵魂

Wireshark的捕获过滤器,底层用的其实是伯克利包过滤(Berkeley Packet Filter,BPF)语法。说白了,这就是一套让网卡在数据包进入操作系统内存之前,就决定“要不要”的指令集。

我个人习惯把BPF语法拆成三部分来理解:原语(Primitive)、限定词(Qualifier)和逻辑运算符。

  • 限定词:告诉过滤器你要看什么。比如 host、net、port、proto。
  • ID(标识符):具体的值。比如 192.168.1.1、80、tcp。
  • 逻辑运算符:组合多个条件。比如 and、or、not。

核心公式: [限定词] [ID] [逻辑运算符] [限定词] [ID]

举个例子,host 192.168.1.1 and port 80,意思就是“只抓取源或目标IP是192.168.1.1,并且端口是80的流量”。

嗯,这里要注意,BPF语法是大小写敏感的,而且必须用英文半角符号。我曾经见过有同事把 and 写成了 AND,结果过滤器直接报错,抓了半天空包。

3.2 基于IP地址的捕获过滤

这是最常用的场景。你想盯住某台服务器,或者排除某个IP的干扰。

需求 BPF表达式 说明
抓取特定主机 host 10.0.0.5 匹配源或目标IP为10.0.0.5
抓取源IP src host 10.0.0.5 只抓从此IP发出的包
抓取目标IP dst host 10.0.0.5 只抓发往此IP的包
排除某个IP not host 10.0.0.5 抓取除了此IP以外的所有流量
抓取整个网段 net 192.168.1.0/24 抓取该子网内的所有通信

我的经验: 在排查DDoS攻击时,我习惯先用 not host 我的管理IP 把自己排除掉,避免SSH会话本身的流量干扰分析。

3.3 基于端口和协议的捕获过滤

很多时候,你只关心某种应用层协议,比如HTTP或DNS。这时候端口过滤就派上用场了。

# 只抓HTTP流量(假设使用标准80端口)
port 80

# 抓取DNS查询和响应
port 53

# 抓取所有HTTPS流量
port 443

# 抓取非标准端口的HTTP(比如8080)
port 8080

你可能会问,为什么不用协议名直接过滤?比如 tcp 或 udp?

其实是可以的。BPF支持直接指定协议类型:

# 只抓TCP包
tcp

# 只抓UDP包
udp

# 只抓ICMP包(比如ping)
icmp

# 抓取非HTTP的TCP流量(排除80端口)
tcp and not port 80

我记得有一次,客户反馈某个应用间歇性断连。我直接用 tcp and port 8080 抓了五分钟,很快就发现了大量的TCP重传和零窗口通告——典型的服务器处理不过来,把客户端“噎住”了。

3.4 组合过滤:逻辑运算符的妙用

单个条件往往不够用。BPF支持 and、or、not 以及括号分组。

# 抓取从192.168.1.10发往任何主机的HTTP或HTTPS流量
src host 192.168.1.10 and (port 80 or port 443)

# 抓取除了DHCP(端口67/68)之外的所有UDP流量
udp and not (port 67 or port 68)

# 抓取两个特定主机之间的所有流量
host 10.0.0.1 and host 10.0.0.2

避坑指南: 我曾经在写复杂表达式时,忘了加括号,导致逻辑优先级出错。比如 host A and port 80 or port 443 会被解释为 (host A and port 80) or port 443,结果抓了一堆无关的443流量。记住,and 优先级高于 or,不确定时就加括号。

3.5 捕获过滤器的局限性

讲到这里,我得给你泼盆冷水。捕获过滤器虽然快,但它有很大的局限性。

第一,它只能做“粗粒度”过滤。 BPF工作在网卡驱动层,它只能看到L2到L4的信息(MAC、IP、端口、协议类型)。你没法用它过滤HTTP的URL、TCP的特定标志位组合,或者某个应用层关键字。

第二,语法表达能力有限。 比如你想抓“TCP SYN包”,用捕获过滤器是做不到的。你得用 tcp[tcpflags] & tcp-syn != 0 这种偏移量写法,但说实话,这已经超出BPF的舒适区了,而且容易写错。

第三,一旦设置错误,可能抓不到任何数据。 因为过滤器是在数据进入系统之前就丢弃了,你没法事后补救。我见过有人把 host 拼成 hose,结果抓了一整天空文件。

对比维度 捕获过滤器(BPF) 显示过滤器
工作时机 数据包进入内存前 数据包已存入内存后
性能影响 极低(硬件/内核级) 较高(用户态处理)
过滤粒度 L2-L4(MAC/IP/端口/协议) L2-L7(可深入应用层)
能否事后修改 不能,抓了就是抓了 能,随时调整过滤条件
典型用途 减少抓包文件体积,保护磁盘 精准定位问题,分析协议细节

我的建议: 在不确定该抓什么的时候,宁可用宽泛的捕获过滤器(比如只按IP过滤),也不要过度限制。抓大一点,事后用显示过滤器慢慢筛。磁盘空间比错过关键证据要便宜得多。

3.6 知识体系:BPF捕获过滤器全景图

为了帮你把这一章的知识点串起来,我画了一张图。你可以把它当作一个速查地图。

BPF捕获过滤器知识体系 BPF 捕获过滤器 限定词 (Qualifier) 逻辑运算符 局限性 host / net port / proto src / dst ether / vlan and / or / not 括号分组 ( ) 仅支持 L2-L4 过滤 无法事后修改条件 语法错误导致空抓 核心原则:宽进严出 捕获过滤器尽量宽松,显示过滤器负责精准

这张图把BPF的三大块——限定词、逻辑运算符、局限性——都串起来了。你可以把它当作一个速查地图。下次写过滤器之前,先看一眼,思路会清晰很多。