3. 捕获过滤器实战:用 host、port、net 精准锁定目标流量

说实话,很多刚接触 Wireshark 的朋友,一上来就直接点「开始捕获」。结果呢?几秒钟就抓了几万包,看得眼花缭乱。我刚开始干网络那会儿也犯过这毛病——抓了一堆没用的广播包,真正要找的端口冲突报文反而被淹没了。

所以这一章,咱们专门聊聊捕获过滤器。它跟显示过滤器不一样,是在抓包之前就把不想要的流量挡在门外。说白了,就是给网卡装个筛子,只让符合条件的数据包进来。

核心原则:捕获过滤器基于 BPF(Berkeley Packet Filter)语法,工作在数据链路层。它不能像显示过滤器那样灵活,但胜在效率高——不想要的包压根不进缓冲区。

3.1 捕获过滤器 vs 显示过滤器:别搞混了

我经常在群里看到有人问:「为什么我设了过滤条件,还是抓到一堆无关包?」一问,原来他把显示过滤器当成捕获过滤器用了。这两个东西,定位完全不同。

对比维度 捕获过滤器 显示过滤器
作用时机 抓包之前 抓包之后
语法基础 BPF(类 tcpdump) Wireshark 专有语法
性能影响 降低 CPU/内存负载 只影响显示,不影响捕获
典型场景 高流量环境、长时间抓包 事后分析、交互式排查
能否恢复丢弃的包 不能(丢弃即永久丢失) 能(原始数据仍在)
我的建议:如果你不确定该过滤哪些流量,先用显示过滤器做探索性分析。等摸清规律了,再回头用捕获过滤器做精准采集。别一上来就「一刀切」。

3.2 三大核心关键字:host、port、net

BPF 语法里,最常用的就是这三个关键字。咱们一个一个说。

3.2.1 host:只关心特定主机

假设你怀疑某台服务器(IP 192.168.1.100)占用了端口 8080,你想看看它到底在跟谁通信。这时候,捕获过滤器可以这么写:

host 192.168.1.100

这个过滤器会抓取所有源 IP 或目标 IP 为 192.168.1.100 的包。不管是 TCP、UDP 还是 ICMP,统统收进来。

如果你只想看它发出的包,或者发给它的包,可以加上方向限定:

src host 192.168.1.100   # 只看它发出的
dst host 192.168.1.100   # 只看发给它的

我记得有一次排查一个端口冲突问题,应用日志报「Address already in use」。我直接用 host 10.0.0.5 抓了 30 秒,就发现有两个进程同时在监听 3000 端口。嗯,问题一下就清楚了。

3.2.2 port:锁定特定端口

端口冲突嘛,核心就是端口。如果你已经知道冲突的端口号,比如 8080,直接写:

port 8080

这样只会抓取源端口或目标端口为 8080 的包。配合 host 一起用,效果更好:

host 192.168.1.100 and port 8080

这个组合过滤器,只抓 192.168.1.100 这台机器上 8080 端口的流量。噪音几乎为零。

注意:port 关键字默认匹配 TCP 和 UDP。如果你只想看 TCP 的 8080 端口,要写成 tcp port 8080。同理,UDP 就是 udp port 8080。

3.2.3 net:按网段过滤

有时候你不想只盯着一台机器,而是想看整个网段。比如公司内网是 192.168.1.0/24,你想看看这个段里有没有机器在扫端口:

net 192.168.1.0/24

也可以指定方向:

src net 192.168.1.0/24
dst net 10.0.0.0/8

这个在排查大规模端口扫描或者 DHCP 冲突时特别有用。我曾在一次 IDC 搬迁项目中,用 net 172.16.0.0/16 抓了 5 分钟,就定位到一台新上架的机器 IP 配错了,导致跟另一台核心交换机冲突。

3.3 组合使用:逻辑运算符 and、or、not

单个关键字不够用?那就组合起来。BPF 支持标准的逻辑运算:

  • and(或 &&):两个条件同时满足
  • or(或 ||):满足其中一个条件
  • not(或 !):排除某个条件

举个例子,你想抓 192.168.1.100 的 8080 和 443 端口,但排除 SSH(22 端口):

host 192.168.1.100 and (port 8080 or port 443) and not port 22

括号用来改变优先级,这个跟编程语言一样。我习惯在复杂表达式里加括号,哪怕不加也能算对——为了可读性,值得。

实战组合速查表:
场景 捕获过滤器
单台机器的特定端口 host 10.0.0.1 and port 3306
整个网段的 Web 流量 net 192.168.1.0/24 and (port 80 or port 443)
排除广播和多播 not broadcast and not multicast
只看两个主机间的通信 host 10.0.0.1 and host 10.0.0.2
排除 DNS 流量 not port 53

3.4 捕获过滤器在 Wireshark 中的配置位置

这个其实很简单,但我发现还是有人找不到。两种方式:

  1. 捕获前设置:点击菜单栏「捕获」→「选项」,在「捕获过滤器」栏里输入表达式,然后点「开始」。
  2. 保存常用过滤器:在捕获选项界面,点击「捕获过滤器」按钮旁的「新建」,给过滤器起个名字(比如「Web 服务器排查」),以后直接下拉选择就行。

我个人习惯把常用的几个过滤器保存下来。比如「排除 SSH」「只看 MySQL」「内网全流量」等等。省得每次手打。

小技巧:如果你用的是命令行版的 tcpdump,捕获过滤器语法完全一样。把 Wireshark 里调试好的过滤器,直接复制到 tcpdump 命令里就能用。比如:tcpdump -i eth0 'host 192.168.1.100 and port 8080'

3.5 避坑指南:捕获过滤器常见的坑

我用捕获过滤器踩过不少坑,挑几个典型的说说:

  • 坑一:过滤太严,丢掉了关键包。比如你只抓了 8080 端口,但冲突其实发生在 8081。所以建议先宽后窄——先用 host 抓全量,再逐步加 port 缩小范围。
  • 坑二:忘了 VLAN 标签。在 trunk 链路上抓包,BPF 过滤器可能不识别 VLAN 头。如果你发现抓到的包跟预期不符,试试在过滤器里加 vlan 关键字。
  • 坑三:大小写敏感。BPF 关键字都是小写。写成 HOST 或 Port 会报错。我刚开始就犯过这毛病,还以为是软件坏了。
  • 坑四:括号匹配。复杂表达式里括号没配对,Wireshark 会直接提示语法错误。写完后数一数左括号和右括号数量是否一致。
曾经有一次:我在客户现场排查一个间歇性的端口冲突,抓了一整天都没抓到。后来发现是捕获过滤器里写错了 IP 地址——把 10.0.0.10 写成了 10.0.0.1。白白浪费了 8 个小时。所以,抓包前一定 double-check 你的过滤器表达式。

3.6 本章知识体系:捕获过滤器核心逻辑

下面这张图,帮你把捕获过滤器的核心逻辑串起来。从 BPF 语法出发,到三大关键字,再到组合使用和配置位置,一目了然。

捕获过滤器核心逻辑 BPF 语法 host port net 组合:and / or / not Wireshark 捕获选项 / tcpdump 命令行 核心思路:先确定目标(host/port/net),再用逻辑运算符组合,最后应用到捕获接口

3.7 本章小结

捕获过滤器是端口冲突排查的第一道防线。用好了,能帮你节省 80% 的时间。记住三个关键字:host 锁定机器,port 锁定端口,net 锁定网段。组合使用时,注意括号和逻辑优先级。