2. 基于BPF过滤器的精准流量捕获

基于BPF过滤器的精准流量捕获 学习卡片

BPF过滤器的匹配模型

BPF(Berkeley Packet Filter)过滤器在抓包工具中充当“内核态预筛选器”:表达式在数据包进入用户态之前逐包求值,只有结果为真的报文才会被写入捕获缓冲区。要精准捕获“指定主机 + 端口 + 协议”的组合流量,关键是理解 BPF 的限定词结构:类型(type)决定看哪一层字段,方向(dir)决定源/目的,协议(proto)决定匹配哪种报文。

例如表达式 tcp and host 192.168.10.20 and port 443 的含义是:先限定 TCP 协议,再限定 IP 地址为 192.168.10.20(源或目的),最后限定端口为 443(源或目的)。三个条件之间是逻辑与关系,必须同时满足才被捕获。若写成 tcp port 443 and host 192.168.10.20,语义等价,但可读性略差。

数据包 逐包进入 BPF 过滤器 tcp and host 192.168.10.20 and port 443 条件1:proto = tcp 匹配 IP 头协议字段 = 6 条件2:host = 192.168.10.20 源IP 或 目的IP 匹配 条件3:port = 443 源端口 或 目的端口 匹配 三个条件逻辑与(AND) 全部 满足? 是 写入 捕获缓冲 否 丢弃 不进入用户态 BPF 在内核态完成筛选,减少用户态拷贝与处理开销

组合表达式的编写与验证

针对“主机 192.168.10.20 与 10.0.0.5 之间、端口 443 的 TCP 流量”这一目标,可写出如下表达式:

tcp and port 443 and host 192.168.10.20 and host 10.0.0.5

注意:两个 host 条件之间是 AND,表示报文的源和目的地址必须分别命中这两个主机(顺序无关)。如果只想捕获“从 192.168.10.20 发往 10.0.0.5”的单向流量,应使用方向限定词:

tcp and src host 192.168.10.20 and dst host 10.0.0.5 and dst port 443

验证过滤结果时,不能只看“抓到了多少包”,而要同时检查漏包与误包。推荐做法是:先用宽表达式(如 host 192.168.10.20)抓一段完整流量作为基准,再用目标表达式抓同一时段,对比两者中目标流量的包数量是否一致;若目标表达式数量偏少,说明存在漏包;若目标表达式里出现了非目标主机或非 443 端口的包,说明存在误包。

使用 tcpdump -d 可以查看 BPF 表达式编译后的指令序列,确认限定词是否按预期组合;使用 tcpdump -c N 限制抓包数量,便于快速验证表达式行为。

常见误配与修正

误配表达式问题修正写法
host 192.168.10.20 or port 443OR 导致捕获所有 443 端口流量,误包大量增加host 192.168.10.20 and port 443
port 443未限定协议,UDP 443 也会被捕获tcp port 443
src port 443只捕获服务端发出的包,漏掉客户端请求port 443 或 src or dst port 443
host 192.168.10.20 and host 10.0.0.5未限定端口,同主机对之间其他端口流量被误捕追加 and port 443
BPF 的 host 默认同时匹配源和目的,port 默认同时匹配源和目的。若业务只关心单向流量,必须显式使用 src 或 dst,否则会把反向确认包也计入,导致包数量与预期不符。