2. 基于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,语义等价,但可读性略差。
组合表达式的编写与验证
针对“主机 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 443 | OR 导致捕获所有 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,否则会把反向确认包也计入,导致包数量与预期不符。