3、抓包过滤器:捕获过滤器语法(BPF)、常见过滤场景、实战案例

抓包这件事,说白了就是「在车水马龙的网络里,只盯住你想看的那几辆车」。如果没有过滤器,Wireshark 会把所有经过网卡的数据包都扔给你——你想想看,一个正常办公的网络,每秒几百上千个包是常事,光 ARP 广播就能刷屏。所以,学会用过滤器,是抓包的第一道基本功。

我个人习惯把过滤器分成两类:捕获过滤器和显示过滤器。这一章我们先啃捕获过滤器,它是在数据包进入 Wireshark 之前就做筛选,说白了就是「抓的时候就只抓我想要的」,而不是「先全抓进来再挑」。好处很明显——节省磁盘、降低 CPU 负载,尤其在流量大的生产环境,这招能救命。

3.1 BPF 语法:捕获过滤器的核心

捕获过滤器的底层是 BPF(Berkeley Packet Filter),一种在内核态运行的包过滤机制。你写的过滤表达式会被编译成 BPF 字节码,由内核直接执行。效率极高,但语法也相对「原始」。

BPF 的核心逻辑就三要素:类型(Type)、方向(Dir)、协议(Proto)。我刚开始学的时候总觉得它像简化版的 C 语言条件判断,其实没那么复杂。

要素 关键字 示例 说明
类型 host / net / port / portrange host 192.168.1.1 指定主机、网段、端口或端口范围
方向 src / dst / src or dst src host 10.0.0.5 限定源或目标,默认双向
协议 ether / ip / tcp / udp / icmp / arp tcp port 80 按协议类型过滤

组合起来就是:[协议] [方向] [类型] [值]。比如 tcp src port 443,意思就是「只抓从 443 端口发出的 TCP 包」。嗯,这里要注意:BPF 的协议关键字和方向关键字顺序是固定的,写反了会报错。

小技巧:BPF 表达式里可以用逻辑运算符 and(&&)、or(||)、not(!)组合条件。比如 tcp and not port 22,就是「抓所有 TCP 包,但排除 SSH 流量」。

3.2 常见过滤场景:只抓 HTTP、只抓特定 IP

理论说完了,直接上实战场景。我挑三个最常用的,你在工作中大概率都会遇到。

场景一:只抓 HTTP 流量

HTTP 默认跑在 80 端口,所以过滤条件很简单:

tcp port 80

但注意,这只抓了 80 端口的 TCP 包。如果你还想抓 HTTPS(443 端口),可以这样:

tcp port 80 or tcp port 443

或者更简洁:

tcp port 80 or 443

我曾经在调试一个 Web 应用时,只写了 tcp port 80,结果发现客户端的请求走了代理,端口是 8080。嗯,那一次排查浪费了半小时。所以,如果你不确定端口,可以先抓全量,再用显示过滤器缩小范围。

场景二:只抓特定 IP 的流量

这个更常用。比如你只想看某台服务器 192.168.1.100 的通信:

host 192.168.1.100

如果只抓它发出的包:

src host 192.168.1.100

只抓发给它的包:

dst host 192.168.1.100

组合一下,抓某个 IP 的 HTTP 流量:

host 192.168.1.100 and tcp port 80
避坑指南:我曾经在生产环境上直接写 host 192.168.1.100 就开始抓包,结果发现抓下来的 pcap 文件有 2GB——因为那台服务器是数据库节点,流量巨大。后来我学乖了,先加端口限制,再考虑 IP 过滤,或者直接用 tcpdump -c 1000 限制包数量。

场景三:抓取特定网段的广播或多播

net 192.168.0.0/24

这个在排查 DHCP 或 ARP 问题时特别有用。比如只抓某个子网的 DHCP 请求:

udp port 67 or udp port 68

3.3 实战案例:只抓取本机与服务器的通信

好,我们直接上一个完整的实战案例。假设你的本机 IP 是 10.0.0.2,服务器 IP 是 10.0.0.100,你想抓它们之间的所有 TCP 通信。

捕获过滤器表达式:

host 10.0.0.2 and host 10.0.0.100 and tcp

或者更严谨一点,用 src 和 dst 明确方向:

(src host 10.0.0.2 and dst host 10.0.0.100) or (src host 10.0.0.100 and dst host 10.0.0.2)

我个人习惯用第一种,简洁。但如果你在抓包时发现 Wireshark 没有捕获到任何包,可以检查一下:

  • IP 地址是否写反了?
  • 本机是否真的在和服务器通信?(用 ping 测试一下)
  • 网卡是否选对了?(无线网卡和有线网卡别搞混)

下面这张图展示了整个过滤逻辑的流程:

捕获过滤器工作流程 捕获过滤器工作流程 原始网络流量 BPF 内核态过滤 匹配条件? 是 否 捕获到 Wireshark 丢弃(不捕获) 说明:BPF 过滤器在内核态执行,只有匹配条件的包才会被复制到用户态的 Wireshark 缓冲区

在实际操作中,你只需要在 Wireshark 的「Capture Options」窗口里,把表达式填进「Capture Filter」输入框,然后点「Start」就行。如果你用的是命令行,tcpdump 的语法和 BPF 完全一致:

tcpdump -i eth0 -w server_comm.pcap "host 10.0.0.2 and host 10.0.0.100 and tcp"

这个命令会把本机和服务器之间的 TCP 通信直接保存到 server_comm.pcap 文件里。我经常在远程服务器上这么干,抓完再把 pcap 文件拖回本地用 Wireshark 分析。

核心要点:捕获过滤器是「事前过滤」,一旦设置,不符合条件的包根本不会进入 Wireshark。所以,如果你不确定要抓什么,宁宽勿窄——先抓全量,再用显示过滤器慢慢筛。否则漏掉了关键包,你还得重抓。

3.4 常见 BPF 表达式速查表

最后,我整理了一份常用表达式清单,你可以直接复制粘贴用:

需求 BPF 表达式
只抓 HTTP tcp port 80
只抓 HTTPS tcp port 443
只抓特定 IP host 192.168.1.1
只抓特定 IP 的 HTTP host 192.168.1.1 and tcp port 80
排除 SSH not tcp port 22
只抓 DNS udp port 53
只抓 ICMP(ping) icmp
只抓广播/多播 broadcast or multicast
抓取非本机流量 not host 10.0.0.2