4、抓包过滤器:捕获过滤器语法、常见过滤表达式、MAC地址过滤、IP地址过滤、端口过滤、协议过滤

说实话,很多新手一上来就急着点「开始」按钮抓包。结果呢?几秒钟就抓了几千个包,看得眼花缭乱。我刚开始学Wireshark时也犯过这毛病——抓了一大堆数据,真正有用的没几个。

后来我才明白,会抓包不如会过滤。过滤器就是你的「筛子」,帮你把想要的数据从海量流量里捞出来。今天咱们就聊聊捕获过滤器——它是在数据进入Wireshark之前就进行筛选的,能大大减少抓包文件的大小。

核心概念:捕获过滤器(Capture Filter)在数据包被Wireshark捕获之前就进行过滤,不符合规则的数据包根本不会被记录。这跟显示过滤器(Display Filter)是两码事——显示过滤器只是把已经抓到的包藏起来,数据其实还在内存里。

4.1 捕获过滤器语法基础

捕获过滤器用的是BPF(Berkeley Packet Filter)语法。说白了,就是一套非常精简的规则语言。它的基本结构是:

[协议] [方向] [类型] [具体值]

举个例子:

host 192.168.1.1

这条规则的意思是:只抓取源IP或目标IP是192.168.1.1的数据包。简单吧?

BPF语法支持以下几种核心元素:

元素类型 关键字 说明
协议 ether / ip / tcp / udp / arp / icmp 指定要捕获的协议类型
方向 src / dst / src or dst 指定数据包的流向
类型 host / net / port / portrange 指定匹配的地址或端口范围
逻辑运算符 and / or / not 组合多个条件

小技巧:我个人习惯在写复杂过滤规则时,先用括号把条件分组。比如 host 192.168.1.1 and (port 80 or port 443),这样逻辑更清晰,不容易出错。

4.2 常见过滤表达式

下面这些是我工作中最常用的过滤表达式,几乎每天都会用到:

过滤需求 捕获过滤器表达式 说明
抓所有流量 (空) 不设置过滤器,抓取所有数据包
只抓某个主机 host 192.168.1.100 抓取与该主机相关的所有流量
只抓某个网段 net 192.168.1.0/24 抓取整个子网的流量
只抓某个端口 port 80 抓取HTTP流量
排除某个主机 not host 10.0.0.1 排除特定主机的流量
抓DNS查询 port 53 抓取DNS请求和响应
抓DHCP交互 port 67 or port 68 抓取DHCP客户端和服务器的通信

你想想看,如果公司网络突然变慢,我怀疑是某台机器在疯狂发包。这时候我只需要在捕获过滤器里写上 host 192.168.1.200,然后开始抓包。几秒钟就能看到这台机器到底在干什么——是正常的业务流量,还是中了病毒在往外发数据。

4.3 MAC地址过滤

MAC地址过滤在局域网排障时特别有用。比如公司里有人私接路由器,导致网络环路——这时候用IP地址查不到,因为那个设备可能还没拿到IP。但MAC地址是硬件绑定的,跑不掉。

语法格式:

ether host aa:bb:cc:dd:ee:ff
ether src aa:bb:cc:dd:ee:ff
ether dst aa:bb:cc:dd:ee:ff

举个例子:

ether host 00:1a:2b:3c:4d:5e

这条规则只抓取MAC地址为 00:1a:2b:3c:4d:5e 的设备发出的或接收到的所有数据包。

注意:MAC地址过滤只在以太网层有效。如果数据包经过了路由器,源MAC和目标MAC都会被改写。所以跨网段排障时,MAC过滤就不太灵了。我曾经有一次排查一个跨三层交换机的丢包问题,用MAC过滤抓了半天没抓到,后来才发现数据包经过路由器后MAC地址变了——白忙活一场。

4.4 IP地址过滤

IP地址过滤是最常用的。语法也很直观:

host 192.168.1.1          # 抓取与192.168.1.1相关的所有流量
src host 192.168.1.1      # 只抓取源IP为192.168.1.1的流量
dst host 192.168.1.1      # 只抓取目标IP为192.168.1.1的流量
net 10.0.0.0/8            # 抓取整个10.0.0.0网段的流量
src net 172.16.0.0/12     # 只抓取源IP属于172.16.0.0/12网段的流量

我记得有一次帮客户排查一个奇怪的问题:内网某台服务器每隔5分钟就会向外网发送大量数据包。用 src host 10.0.0.50 一抓,发现它在跟一个国外的IP频繁通信。后来确认是中了挖矿病毒——要不是用源IP过滤精准定位,光靠肉眼翻几千个包根本发现不了。

4.5 端口过滤

端口过滤用来抓取特定应用层的流量。比如:

port 80                  # 抓取HTTP流量
port 443                 # 抓取HTTPS流量
port 22                  # 抓取SSH流量
portrange 8000-9000      # 抓取8000到9000端口范围内的流量
src port 53              # 只抓取源端口为53的流量(通常是DNS响应)
dst port 8080            # 只抓取目标端口为8080的流量

组合使用效果更好:

host 192.168.1.100 and port 443

这条规则只抓取 192.168.1.100 这台机器的HTTPS流量。嗯,这里要注意:如果你只想看某个Web服务的请求,用这个组合过滤能帮你省下大量时间。

4.6 协议过滤

协议过滤直接指定要抓取哪种协议的数据包:

ip                      # 只抓取IP数据包
tcp                     # 只抓取TCP数据包
udp                     # 只抓取UDP数据包
arp                     # 只抓取ARP数据包
icmp                    # 只抓取ICMP数据包(ping包)
ether                   # 只抓取以太网帧

协议过滤也可以组合:

tcp or udp              # 抓取TCP和UDP数据包
ip and not arp          # 抓取IP数据包,排除ARP广播

实战经验:我排查网络延迟问题时,经常先用 icmp 过滤抓ping包。如果ping包延迟正常,说明网络层没问题,问题大概率出在应用层。如果ping包都丢,那就得从物理层和链路层查起了。这个思路帮我省了不少冤枉路。

4.7 综合实战:一个完整的过滤场景

假设你现在要排查一个问题:公司内网有一台Web服务器(IP: 192.168.1.10,端口8080),客户端(IP: 192.168.1.100)访问它时偶尔超时。你想抓取它们之间的HTTP通信,同时排除其他干扰流量。

捕获过滤器可以这样写:

host 192.168.1.100 and host 192.168.1.10 and port 8080

或者更简洁一点:

host 192.168.1.100 and port 8080

因为目标服务器只有一台,而且端口8080是唯一的,所以第二个写法也能达到目的。但如果你网络里有多台服务器都用了8080端口,那就得把两个IP都写进去,避免抓到别人的流量。

下面这张图帮你理清捕获过滤器的选择逻辑:

捕获过滤器选择逻辑 开始设置过滤器 按什么条件过滤? MAC地址 IP地址 端口 协议 ether host XX:XX:XX host / net / src / dst port / portrange tcp / udp / icmp 用 and / or / not 组合条件 开始抓包!

4.8 避坑指南

最后分享几个我踩过的坑:

  • 捕获过滤器不支持「模糊匹配」。比如你想抓所有以 .example.com 结尾的域名流量——抱歉,捕获过滤器做不到。你得用显示过滤器里的 dns.qry.name contains "example.com"。
  • 捕获过滤器不支持「按数据包内容过滤」。比如你想抓HTTP请求里包含 password 字段的包——捕获过滤器搞不定。得用显示过滤器的 http contains "password"。
  • 捕获过滤器一旦设置,不符合条件的数据包就彻底丢了。所以如果你不确定要抓什么,我建议先不设过滤器,全量抓一小段时间,然后用显示过滤器慢慢分析。全量抓包虽然文件大,但至少不会漏掉关键数据。
  • 注意大小写:BPF语法里关键字都是小写的。写成 HOST 或 Port 会报错。我第一次用的时候就因为写了 Port 80 导致过滤器不生效,查了半天才发现是大小写的问题。

重要提醒:在Wi-Fi网络上使用捕获过滤器要格外小心。因为Wi-Fi接口在监控模式下才能抓到其他设备的数据包,而普通模式下只能抓到发给自己和自己的广播包。我曾经在咖啡厅帮朋友排查Wi-Fi慢的问题,抓了半天只抓到自己的流量——后来才想起来网卡没开监控模式。嗯,这个坑我替你们踩过了。