4. 显示过滤器进阶:基于协议、IP、端口的组合过滤
上一章我们聊了基础过滤,说白了就是单个条件查问题。但实际抓包时,你很少只关心一种因素。比如端口占用了,你得同时看IP对不对、协议是不是TCP、端口是不是那个冲突的端口。这时候就需要组合过滤了。
我个人习惯,遇到复杂问题从来不用单一过滤器。为什么?因为网络流量太杂了。你只过滤一个条件,结果里可能混进来一堆不相干的数据包,反而干扰判断。组合过滤就像给数据包做“安检”,多个条件一起上,精准定位。
4.1 逻辑运算符:and、or、not
Wireshark的显示过滤器支持三种逻辑运算:and(与)、or(或)、not(非)。它们的作用很简单:
| 运算符 | 含义 | 示例 | 说明 |
|---|---|---|---|
and |
同时满足 | ip.src==192.168.1.1 and tcp.port==80 |
源IP为192.168.1.1且端口为80 |
or |
满足其一 | tcp.port==80 or tcp.port==443 |
端口为80或443 |
not |
排除条件 | not arp |
排除ARP协议 |
嗯,这里要注意:and 的优先级高于 or。如果你混用,最好加括号明确顺序。比如:(tcp.port==80 or tcp.port==443) and ip.src==192.168.1.1。不加括号的话,Wireshark会先算and,结果可能不是你想要的。
(ip.src==192.168.1.1) and (tcp.port==80)。
4.2 实战组合:协议 + IP + 端口
端口占用排查时,最常用的组合就是“协议 + IP + 端口”。举个例子:
假设你发现服务器192.168.1.100的8080端口被占用了,你想看看是谁在连它。过滤器可以这样写:
ip.addr==192.168.1.100 and tcp.port==8080
这个过滤器会显示所有涉及192.168.1.100且端口为8080的TCP包。但注意,ip.addr 同时匹配源IP和目标IP。如果你只想看某个方向的流量,可以用 ip.src 或 ip.dst。
我在项目中遇到过一个问题:客户说服务器端口被占用了,但抓包一看,全是广播包和ARP请求。后来我加了 not arp 和 not icmp,瞬间清净了。过滤器长这样:
ip.addr==192.168.1.100 and tcp.port==8080 and not arp and not icmp
4.3 避坑指南:常见的组合过滤错误
我曾经在排查一个数据库连接问题时,写了这么个过滤器:
tcp.port==3306 or tcp.port==3307 and ip.src==192.168.1.50
结果出来的数据包乱七八糟。后来才发现,Wireshark先算了 tcp.port==3307 and ip.src==192.168.1.50,然后和 tcp.port==3306 做or运算。也就是说,所有3306端口的包都出来了,不管IP是谁。
正确的写法应该是:
(tcp.port==3306 or tcp.port==3307) and ip.src==192.168.1.50
另一个常见错误是混淆 ip.addr 和 ip.src/ip.dst。比如你想看从192.168.1.1发往80端口的包,写成:
ip.addr==192.168.1.1 and tcp.dstport==80
这会把192.168.1.1作为目标IP的包也包含进来。正确做法:
ip.src==192.168.1.1 and tcp.dstport==80
ip.addr 是“IP地址字段包含”,不是“等于”。它匹配源IP和目标IP。如果你只想匹配一个方向,用 ip.src 或 ip.dst。
4.4 组合过滤的进阶用法
除了基本的and/or/not,你还可以用括号嵌套更复杂的逻辑。比如:
(ip.src==192.168.1.0/24 and tcp.port==80) or (ip.dst==10.0.0.1 and udp.port==53)
这个过滤器会显示:来自192.168.1.0/24网段且目标端口为80的TCP包,或者发往10.0.0.1且端口为53的UDP包。你想想看,这种组合在排查跨网段问题时特别有用。
我个人习惯在排查端口冲突时,先用一个宽泛的过滤器看全局,比如:
tcp.port==8080
然后根据结果逐步加条件。比如发现某个IP的流量异常,就加上 and ip.addr==x.x.x.x。这样一步步缩小范围,比一次性写一个超长过滤器要靠谱。
4.5 知识体系:组合过滤的核心逻辑
下面这张图总结了组合过滤的核心逻辑,你可以把它当作一个决策树来用:
从图上可以看出,组合过滤是一个“层层递进”的过程。先过滤协议,再过滤IP,最后过滤端口。每一步都在缩小数据包的范围,最终得到你真正关心的那部分。
4.6 实战案例:用组合过滤定位端口冲突
最后,我分享一个真实案例。有一次,客户反馈应用连不上数据库,报错“端口被占用”。我抓包后,先用基础过滤器看了下:
tcp.port==3306
结果发现大量来自不同IP的SYN包。但问题是我需要确认到底是哪个IP在“占用”端口。于是我加了IP过滤:
tcp.port==3306 and ip.src==192.168.1.100
嗯,还是很多。我又加了状态过滤:
tcp.port==3306 and ip.src==192.168.1.100 and tcp.flags.syn==1 and tcp.flags.ack==0
这下只显示SYN包了。但问题还没完——我发现同一个源IP发起了大量SYN,但服务器没回SYN-ACK。这说明端口确实被占用了,但占用者不是这个IP。后来我改用 not 排除这个IP:
tcp.port==3306 and not ip.src==192.168.1.100
终于找到了真正的“元凶”——一个异常进程在疯狂重连。你看,组合过滤用好了,排查效率能翻好几倍。