4、Wireshark高级过滤:过滤表达式语法、协议过滤、字段过滤、逻辑运算符组合过滤
说实话,很多搞网络的人用了好几年Wireshark,还停留在「点一下菜单栏,输入个http」的水平。嗯,这其实挺可惜的。Wireshark真正的威力,藏在那个小小的过滤栏里。今天我就带你把这层窗户纸捅破。
4.1 过滤表达式语法:你得先懂这个骨架
Wireshark的过滤语法,说白了就两套体系:一套是显示过滤器(Display Filter),另一套是捕获过滤器(Capture Filter)。我们日常99%的场景都在用显示过滤器,所以我重点讲这个。
显示过滤器的基本语法长这样:
协议.字段 运算符 值
举个例子:
ip.src == 192.168.1.1
意思就是「只看源IP是192.168.1.1的包」。你想想看,这比在菜单里翻来翻去快了多少倍?
常用的运算符有这些:
| 运算符 | 含义 | 示例 |
|---|---|---|
| == | 等于 | ip.src == 10.0.0.1 |
| != | 不等于 | ip.src != 10.0.0.1 |
| > | 大于 | frame.len > 1000 |
| < | 小于 | frame.len < 64 |
| contains | 包含字符串 | http.host contains "baidu" |
| matches | 正则匹配 | http.user_agent matches "Chrome" |
4.2 协议过滤:快速锁定你关心的流量
协议过滤是最基础的,也是最常用的。你直接在过滤栏输入协议名就行:
dns
http
tcp
arp
icmp
tls
就这么简单。但这里有个坑——协议名是大小写敏感的。你输入HTTP可以,输入http也可以,但输入Http就不行。我曾经因为这个在客户现场排查了半小时,最后发现是大小写写错了……嗯,尴尬。
如果你想过滤某个协议的子类,比如只看HTTP的GET请求:
http.request.method == "GET"
或者只看DNS的A记录查询:
dns.qry.type == 1
这里1代表A记录,2代表NS记录,15代表MX记录。记不住没关系,Wireshark的自动补全会帮你。
4.3 字段过滤:深入到协议内部去
协议过滤只是第一层。真正的高手,会直接操作协议字段。比如:
tcp.port == 443
ip.addr == 192.168.1.1
eth.addr == 00:11:22:33:44:55
frame.time_delta > 0.1
这些字段从哪里来?你点开任何一个包,展开协议树,看到的每一行都是一个字段。比如TCP协议下面有src port、dst port、sequence number、acknowledgment number等等。你右键点击某个字段,选择「作为过滤器应用」,Wireshark会自动帮你生成过滤表达式。
我个人习惯是:先点开一个包看看结构,再手动写过滤表达式。这样既能理解协议细节,又能快速定位问题。
4.4 逻辑运算符组合过滤:这才是真正的杀手锏
单个条件过滤太简单了。实际工作中,你往往需要组合多个条件。Wireshark支持三种逻辑运算符:
- and(&&):两个条件都满足
- or(||):满足其中一个条件
- not(!):取反
举个例子,我想看「从192.168.1.1发往百度服务器的HTTP流量」:
ip.src == 192.168.1.1 and http.host contains "baidu.com"
或者我想看「除了SSH以外的所有TCP流量」:
tcp and not tcp.port == 22
再复杂一点,我想看「DNS查询失败或者HTTP返回500的包」:
dns.flags.rcode != 0 or http.response.code == 500
你想想看,这种组合过滤能帮你多快定位问题?
4.5 实战案例:一次真实的网络故障排查
我记得有一次,客户反馈某个业务系统访问特别慢。我抓了包,先用这个过滤表达式:
tcp.analysis.retransmission or tcp.analysis.fast_retransmission
结果发现大量重传包。进一步过滤:
tcp.analysis.retransmission and ip.dst == 10.0.0.100
锁定目标IP后,再用:
tcp.analysis.retransmission and ip.dst == 10.0.0.100 and tcp.port == 443
最终发现是SSL握手阶段频繁重传。再深入:
tls.handshake.type == 1 and ip.dst == 10.0.0.100
找到了问题根源——客户端发送的Client Hello包被中间设备截断了。整个过程,从抓包到定位,不到10分钟。
你看,这就是高级过滤的威力。没有这些组合过滤,你只能在一堆数据里大海捞针。
4.6 几个我常用的过滤表达式
最后,分享几个我工作中高频使用的过滤表达式,你可以直接拿去用:
| 场景 | 过滤表达式 |
|---|---|
| 查看TCP三次握手 | tcp.flags.syn == 1 and tcp.flags.ack == 0 |
| 查看TCP挥手 | tcp.flags.fin == 1 |
| 查看所有重传 | tcp.analysis.retransmission |
| 查看HTTP POST请求 | http.request.method == "POST" |
| 查看特定端口的UDP流量 | udp.port == 53 |
| 查看ICMP超时 | icmp.type == 11 |
| 排除广播和多播 | not (eth.dst == ff:ff:ff:ff:ff:ff or ip.dst == 224.0.0.0/4) |
好了,关于Wireshark高级过滤,今天就聊这么多。说白了,过滤表达式就是你和数据包之间的翻译官。你学得越深,它就越懂你。下一章,我会讲怎么用这些过滤技巧做离线数据分析,到时候咱们再接着聊。