ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Netmon筛选器实战:DNS、IP、ICMP过滤与NPL语法详解

2026/9/15 7:14:46 拓冰建站 浏览量
Netmon筛选器实战:DNS、IP、ICMP过滤与NPL语法详解 在Windows环境下做网络抓包分析绕不开一个老牌工具Microsoft Network Monitor。虽然微软在2010年后就不再更新它官方推荐迁移到Message Analyzer后者也早就退役但在很多老系统和离线环境里Netmon依然是一把好手。尤其是它的Capture Filter和Display Filter两套筛选机制设计思路和Wireshark完全不同很多从Wireshark转过来的朋友一上来就会被它的NPL语法劝退。这篇内容先不聊怎么装怎么抓专门把筛选器这件事讲透——DNS、IP、ICMP这些最常见的过滤场景在Netmon里到底应该怎么写、为什么要这么写以及我在实际抓包排障中踩过的坑。1. 核心概念拆解Netmon的两套筛选器到底谁在管谁很多人分不清Capture Filter和Display Filter的区别这其实是Netmon最重要的一个设计逻辑。简单来说Capture Filter发生在抓包之前它像一个门卫只让你指定的流量进到捕获缓冲区Display Filter发生在抓包之后它更像一个检视窗口针对已经抓下来的数据包做二次筛选。前者影响“你拿到了什么数据”后者影响“你当前看到了什么数据”。什么叫“前者影响数据本身”举个例子你要排查某台服务器的DNS解析故障如果在Capture Filter里只保留DNS流量比如DNS这个协议标识那么抓包文件里就只有DNS报文其它HTTP、TCP握手、ARP全部被丢弃。这样文件体积小、噪音少分析时思路清晰。但代价是如果抓完之后你突然想看当时那个TCP连接的三次握手对不起数据根本没进缓冲区找不回来了。而Display Filter就不一样它在抓包结束后随时切换。你可以先用Capture Filter把大流量压缩到可处理的范围再在Display Filter里反复变换条件比如先看IPv4全量再切到ICMP最后只留某个IP的对答。整个过程不修改底层数据只是换了个“看的方式”。这两者的分工决定了你在一开始抓包前就得想清楚我这次要解决什么问题需要什么粒度的数据如果问题定位不明确Capture Filter宁可放宽靠Display Filter做精筛。我在实际排障中吃过一次亏——当时为了定位一个间歇性DNS超时Capture Filter里只留了DNS结果抓到的确实全是DNS报文但发现解析失败的根因其实和TCP会话被重置有关。因为没抓到TCP握手和RST包花了很长时间才从防火墙日志里找到线索。自那以后我的原则是Capture Filter只做粗粒度裁剪把精细筛选交给Display Filter。1.1 Capture Filter的生效机制它是靠协议解析器驱动的Netmon的抓包筛选器不是简单的端口匹配它是基于协议解析器Parser的驱动机制。也就是说当你在Capture Filter里写DNSNetmon会调用DNS解析器对每个经过的帧做深度解码确认这是DNS报文后才放行。这和Wireshark的BPFBerkeley Packet Filter完全是两套思路——BPF是在内核里做偏移量级别的快速匹配速度快但不懂协议语义Netmon的Capture Filter更“聪明”但代价是CPU消耗更大。这就引出一个很重要的实操结论如果在高流量环境下做全量捕获Capture Filter写得越“高级”丢包的概率越高。我建议高流量环境里优先用端口类条件比如TcpPort 53它的解析开销远小于DNS这个协议级关键词。因为端口匹配在链路层和网络层就能完成不需要把整个DNS报文完整解析出来。而协议级关键词需要把包完全解码后做语义判断性能差距在实际抓包中非常明显。另外注意一点Capture Filter只在抓包会话启动时生效。Netmon允许你在开始捕获之前配置一条Capture Filter但一旦点击开始捕捉这个过滤器就固定了中途不能修改。如果抓到一半想换条件只能停止抓包、重新配置、再次启动。Windows下的netsh trace有类似的限制。所以执行长时间抓包之前一定要把Capture Filter先想清楚。1.2 Display Filter的表达式语法Netmon的NPL语言Netmon的Display Filter是用一种名为NPLNetwork Packet Language的语言写的。语法结构看起来有点像C#的属性和方法调用核心逻辑是协议类型.属性名 值。比如IPv4.DestinationAddress 10.10.10.1表示筛选所有目的IP为10.10.10.1的IPv4包DNS.QNAME www.example.com表示筛选DNS查询名恰好等于该域名的数据包。NPL支持逻辑运算符AND、||OR、!NOT也支持括号分组。字符串值必须用双引号包裹数字不需要。注意大小写其实是可以放宽的Netmon的解析器不区分大小写但属性名和协议名的拼写必须准确如果写错了它会提示语法错误。有一个很容易踩的坑NPL的等值判断是单等号是赋值运算符写错会直接报语法错误。还有字符串匹配默认是精确匹配想模糊匹配要用contains关键字而不是。比如我要看所有包含example.com的DNS查询应该写DNS.QNAME.Contains(example.com)如果写成DNS.QNAME example.com那么www.example.com和api.example.com都匹配不到。2. 两套筛选器的选型与优势对比什么时候该用谁这一节把两套筛选器的应用场景拉出来单独对比不是因为我喜欢做表格而是因为实际排障中很多人在这一步就迷失了。选错筛选器轻则抓不到想要的包重则整个抓包会话白做。维度Capture FilterDisplay Filter生效时机抓包启动前配置中途不可修改抓包结束后任意切换不影响底层数据性能压力解析器随每个包运行高流量下有丢包风险只处理已捕获的数据无丢包风险灵活性低条件固定后不能反复调节高随时改写表达式立即刷新结果适用场景大流量环境中做粗粒度裁剪缩小数据范围精细化排查多角度观察同一份抓包数据语法差异支持协议名和NPL表达式但可用功能有限完整NPL语法支持属性、逻辑组合、字符串匹配从这张表能看出Capture Filter和Display Filter不是竞争关系而是流水线上的两道工序。我自己的习惯是Capture Filter只写一两个粗粒度条件比如只抓指定IP或指定端口Display Filter负责一切精细筛选。这样既保证了抓包性能又保留了数据的可回溯性。这里有两点补充。第一如果你的抓包机器流量非常大比如核心交换机镜像口Capture Filter必须做减法否则抓包文件会瞬间膨胀到几个GB不仅磁盘撑不住分析工具也会卡死。第二如果问题本身是“不知道流量异常出在哪里”那Capture Filter就先别过滤太多全量抓一小段时间再用Display Filter慢慢拆。2.1 为什么选DNS/IP/ICMP这三个场景DNS、IP、ICMP看起来是三个独立的协议但在实际排障里它们往往是一条线。举个例子你发现某台电脑上不了网第一步ping网关不通ICMP然后怀疑是DNS解析有问题导致域名解析失败DNS最后定位到是路由策略或防火墙拦截了某个网段的流量IP。这三个协议在链路里正好构成了网络可用性排查的最小闭环。DNS解决的是“名字到IP的映射”IP解决的是“数据包从哪来到哪去”ICMP解决的是“链路通不通、路径上有没有异常”。把这三个协议过滤玩熟练已经能应付90%以上的家庭网络和小型企业网络排障需求。而且这三个协议在Netmon里的字段层级清晰、属性完整是学习NPL语法的最佳切入点。3. 核心实操DNS、IP、ICMP过滤的写法与原理现在进入最实战的部分我会把DNS、IP、ICMP这三类过滤的常用写法、字段含义、以及Netmon特有的语法坑点全部过一遍。每一个写法我都会说明为什么这么写而不是丢一个表达式让读者自己猜。3.1 DNS过滤从协议名到QNAME属性DNS过滤在Netmon里的门槛不高但语法细节多。最基本的写法是直接写DNS只要帧被解析为DNS报文就命中。这里“解析为DNS报文”的判断逻辑是Netmon的DNS解析器会检查传输层的端口号默认UDP/TCP 53同时验证报文结构是否符合DNS格式。所以如果你抓到了源端口或目的端口是53的非DNS报文比如某些P2P软件使用53端口做通讯Netmon依然会把它标记为DNS。这个细节要注意它说明Netmon的DNS过滤是“协议解析器驱动”的不是纯端口匹配。精确到域名的过滤是用DNS.QNAME属性。QNAME就是DNS查询里的查询名Query Name例如查询www.example.comQNAME值就是www.example.com。写法是DNS.QNAME www.example.com。这里有个常见疑问为什么不是DNS.NAME或者DNS.QueryName因为NPL的属性名是固定的QNAME是DNS解析器内部约定好的属性名写成别的就会报错。模糊匹配子域名要用DNS.QNAME.Contains(example.com)。注意Contains是大小写不敏感的而且只要字符串子串匹配即可所以www.example.com.cn也会被筛出来——它不是匹配域名后缀而是匹配子串。如果你只想要“以example.com结尾”的域名需要用正则或者多条件OR组合。Netmon的NPL支持正则表达式写法是DNS.QNAME.Matches(.*example\\.com$)但这个语法在Display Filter里支持得好Capture Filter里不一定识别实际使用时要先测试。DNS按响应类型过滤也有用。比如只看DNS响应报文写DNS.Flags.Response 1。这里的Flags.Response是DNS报文头部的标志位字段1表示响应0表示查询。只看DNS查询报文则写DNS.Flags.Response 0。如果你想查DNS解析失败的数据包可以结合DNS.Flags.RCODE字段RCODE非0表示出错。比如看NXDOMAIN域名不存在RCODE3的响应报文写DNS.Flags.Response 1 DNS.Flags.RCODE 3。3.2 IP过滤IPv4和IPv6的坑Netmon里IP过滤最容易被坑的一点是协议名不叫IP叫IPv4或IPv6。如果你写IP.DestinationAddress 10.0.0.1Netmon会直接报语法错误。因为Netmon的解析器把IP协议拆成了IPv4和IPv6两个独立类型没有单独的IP协议名。正确的写法是IPv4.DestinationAddress 10.0.0.1或者IPv6.DestinationAddress ::1。源地址是IPv4.SourceAddress协议类型字段是IPv4.Protocol。这里IPv4.Protocol的取值对应IANA的协议编号1是ICMP6是TCP17是UDP。所以想看某个IP的所有ICMP流量可以写IPv4.Protocol 1 IPv4.DestinationAddress 10.0.0.1。从效率角度看IP层过滤其实是最划算的筛选方式。因为所有上层协议TCP、UDP、ICMP都承载在IP之上只要匹配了IP地址就能把整个主机的流量筛出来。如果你同时需要看这台主机的DNS和HTTP流量不需要分别写DNS和HTTP只需要写IPv4.DestinationAddress 10.0.0.1或者IPv4.SourceAddress 10.0.0.1就能看到全貌。还有一个常用技巧用IPv4.Address 10.0.0.1来匹配源地址或目的地址中的任意一个。Netmon的IPv4.Address属性是一个汇总字段它同时包含源和目的地址。这个写法在查看“某台主机参与的所有流量”时非常方便不用写IPv4.SourceAddress 10.0.0.1 || IPv4.DestinationAddress 10.0.0.1这样一长串。3.3 ICMP过滤类型码和方向判断ICMP过滤在Wireshark里用icmp.type在Netmon里没有直接的ICMP.Type快捷匹配方式但可以用ICMP.MessageType或者通过IPv4层做间接匹配。原因在于Netmon的ICMP解析器把类型码和代码码拆成了两个独立字段命名是ICMP.MessageType对应类型码和ICMP.Code对应代码码。最常见的ICMP场景是ping。Echo Request的类型码是8Echo Reply的类型码是0。想只看ping请求写ICMP.MessageType 8只看ping回应写ICMP.MessageType 0。想看某台目标主机是否回应了ping可以结合IPv4层过滤ICMP.MessageType 0 IPv4.SourceAddress 10.0.0.2。这里说一个我实际用的很顺手的组合IPv4.Protocol 1 ICMP.MessageType 3。这表示筛选所有ICMP目的不可达报文。当你怀疑网络中有路由黑洞、端口不可达、或者MTU问题的时候这些报文就是关键证据。比如ping大包不通、小包能通十有八九和ICMP类型3代码4需要分片但DF标志置位有关。ICMP还有一个Netmon特有的坑协议名必须写ICMP但它的完整称呼其实是ICMPv4——在Netmon的协议列表里ICMP和ICMPv6被分开建模。如果环境里有IPv6流量还得额外写ICMPv6。我最开始从Wireshark转过来时写ICMPv4.MessageType 8直接报错后来才意识到Netmon的协议名是ICMP而不是ICMPv4。这个问题在过去几年里坑过很多人今天专门提出来。4. 实操过程实录从Capture到Display的完整链路光看语法还不够咱们真实走一遍抓包排障的完整流程。场景是这样的一台局域网内的Windows客户端IP 192.168.1.100无法访问外网域名www.sample.com但可以直接通过IP访问外部服务器。基本判断是DNS解析出了问题接下来用Netmon定位根因。4.1 第一步配置Capture Filter保留粗粒度数据启动Netmon后在主界面找到左侧的“Capture Filter”面板如果没显示通过“Filters”菜单调出右键选择“Edit Filter”或者直接新建一个筛选器。这里我配置的Capture Filter是IPv4.Address 192.168.1.100 DNS这个表达式的含义是所有进出192.168.1.100的IPv4报文并且包含DNS解析结果。这样DNS可以看TCP连接也能保留部分方便后续分析。为什么不直接写DNS因为我想保留出问题前后TCP层的线索但不想把整个局域网内的广播报文全抓下来。这里的是逻辑与必须同时满足两个条件。配置完成后点击应用然后在主工具栏点击“New Capture”开始抓包。在客户端上执行ping www.sample.com如果DNS解析失败会提示“找不到主机”。执行完命令后等待几秒点击“Stop Capture”停止抓包。4.2 第二步用Display Filter精确定位DNS查询抓包结束后Netmon会按照帧顺序展示所有捕获的数据包。这个时候点开“Display Filter”输入框在主界面显示的Frame Summary工具栏里输入以下表达式DNS IPv4.SourceAddress 192.168.1.100这表示只看本机发出去的DNS请求。回车后帧列表会被过滤成一系列DNS查询报文。双击任意一条帧下方的Frame Details面板会展开该帧的完整协议树依次是Ethernet、IPv4、UDP、DNS。这时候重点看DNS层。如果本机发出的DNS查询QNAME是www.sample.com但后面没有任何DNS响应报文回来基本可以判断是DNS服务器没有响应或者请求根本没有到达DNS服务器。这时再换一个Display Filter看响应方向DNS IPv4.SourceAddress DNS服务器IP如果DNS响应报文存在则说明客户端和DNS服务器的通信是通的问题出在响应内容上——比如RCODE为非0值。如果响应不存在再把范围扩大到UDP 53端口UDP TcpPort 53这里多说一句TcpPort这个名字迷惑性很强它其实不只是TCP端口Netmon用同一个字段名来表达UDP的源端口和目的端口。写TcpPort 53会筛选出TCP或UDP中任意一个端口为53的报文。如果只想筛UDP 53需要写UDP TcpPort 53。同理端口范围是TcpPort 1024 TcpPort 65535这样的写法。4.3 第三步顺着ICMP和IP链路查找故障区间如果DNS请求和响应都正常但域名就是解析不出正确结果那问题可能出在更底层。这时候要看ICMP报文确认链路是否可达IPv4.Protocol 1 ICMP这条表达式把所有ICMP报文都筛出来包括Echo Request、Echo Reply、Dest Unreachable等。如果里面有大量的MessageType 3目的不可达报文说明中间路由器返回了异常如果只有Echo Request、没有Echo Reply说明对端没有正常回应ping可能是对端防火墙拦截了ICMP流量。换一个思路如果问题表现是“ping外网IP也超时”那说明链路层IP路由就有问题根本走不到DNS解析这一步。这时候用IP地址过滤直接看所有相关流量IPv4.Address 192.168.1.100 || IPv4.Address 网关IP看是否有ARP报文在尝试解析网关MAC地址、是否有TCP连接失败后的重传。多数情况下问题在ARP层就已经暴露了。4.4 第四步保存证据与导出筛选结果排障结束后建议把关键帧导出。Netmon支持把Frame Summary的内容复制到剪贴板也可以在“File”菜单下保存捕获文件.cap格式。如果你需要与他人协作推荐导出为.txt或.csv格式的帧摘要这样同事不需要安装Netmon也能查看关键信息。另外Netmon的Display Filter表达式本身也可以保存方便下次遇到同类问题时直接用。我自己会维护一个筛选器模板库比如“无法解析域名.df”、“单IP全量.df”、“Ping通断检测.df”排障时直接加载省得每次重敲。5. 常见问题与高频报错速查Netmon这些年用下来遇到过的坑十个指头数不完。这里挑几个高频的、有代表性的问题列成表希望帮后来者少走弯路。问题现象可能原因解决方案写IP.DestinationAddress …报语法错误Netmon没有IP协议只有IPv4和IPv6改用IPv4.DestinationAddress或IPv6.DestinationAddress写了条件但抓包结果为空Capture Filter用的协议关键词性能开销大高流量下丢包改用端口过滤TcpPort 53或UdpPort 53用DNS.QNAME example.com筛不到www.example.comNPL的是精确匹配不含子域名改用DNS.QNAME.Contains(example.com)抓包文件很大Display Filter操作卡顿Capture Filter没有做粗粒度裁剪重新用端口类条件抓包或考虑分段抓包写ICMPv4报错Netmon协议名是ICMP而不是ICMPv4改用ICMP注意是IPv4的ICMPIPv6的是ICMPv6Display Filter没问题但Capture Filter相同表达式报错Capture Filter的NPL支持功能比Display Filter少检查是否用了较新的属性或正则匹配尽量用协议名端口粗过滤5.1 一个真实的“抓不到包”案例2017年左右我处理过一个工单用户反映某业务系统间歇性出现数据库连接超时。按常规思路我在数据库服务器的镜像端口上用Netmon抓包Capture Filter写的是IPv4.Address 数据库IP TCP看这个条件挺合理的IP固定、协议固定。但抓了一个小时文件只有几百MB而且抓到的大多数帧是TCP Keep-Alive根本看不到业务SQL流量。后来排查发现一个关键问题数据库服务器同时承载了多套业务业务流量本身不大但因为镜像端口在核心交换机上同时镜像了后台同步流量、存储心跳流量等大量非业务数据。Capture Filter里的IPv4.Address 数据库IP虽然把IP筛掉了但TCP层的数据包量依然非常大Netmon的性能瓶颈导致业务SQL帧大量丢失。那次之后我的做法是尽量靠端口区分业务。如果数据库跑在1433端口SQL ServerCapture Filter就写成IPv4.Address 数据库IP TcpPort 1433这样能精确命中业务流量把其它TCP连接全部挡在门外。尽管Netmon不推荐在Capture Filter里用端口号来“模拟”协议识别但在高流量环境下这是保住关键数据的无奈之举。5.2 从Wireshark迁移过来的语法对照很多读者是从Wireshark转到Netmon的这里放一张速查对照表把最常见的筛选器写法一一对应需求Wireshark Display FilterNetmon Display Filter按IP过滤ip.addr 10.0.0.1IPv4.Address 10.0.0.1按端口过滤tcp.port 80TcpPort 80区分TCP/UDP需再加协议DNS查询名匹配dns.qry.name contains exampleDNS.QNAME.Contains(example)ICMP类型icmp.type 8ICMP.MessageType 8仅看DNS流量dnsDNS逻辑与或and或AND字符串精确匹配值用双引号包裹字符串模糊匹配contains.Contains()方法6. 几条排障心得与使用建议除了具体的语法Netmon的使用习惯和方法论也值得多说几句这些是我用了几轮Netmon之后才慢慢总结出来的经验。要有“分层筛选”的思维。无论碰到什么网络问题不要想着一条Display Filter把问题直接定位出来。先用IPv4.Address把主机关联流量全拉出来再用TCP或DNS缩小范围最后用端口或关键字精确定位。这种层层逼近的方式比一次性猜测精准得多。然后是抓包前先评估流量。一句话宁可过滤宽一点不可漏掉关键数据。不确定时我建议第一轮只做IP过滤先看整体流量分布心里有数之后再决定第二轮要不要加上协议条件。若一开始就精确过滤反而容易让判断“朝一个方向跑偏”。Netmon虽然停止了更新但它在Windows平台的兼容性依然有很强的历史价值。很多老设备的管理接口只提供Windows下的MIB和调试工具Netmon反而是最稳妥的抓包切入点。用熟Netmon的NPL语法之后再去看微软后续的Message Analyzer和现在的KQLKusto Query Language会发现很多概念是一脉相承的——协议字段层级、逻辑运算符、类型属性反射。在这个基础上学习新的抓包语言门槛会低很多。最后分享一个我自己维护“筛选器模板”的习惯。面对DNS解析类问题我常用一条组合表达式把查询、响应、异常全部串起来DNS (IPv4.SourceAddress 192.168.1.100 || IPv4.DestinationAddress 192.168.1.100)这条表达式重点不是语法多高深而是它保证了你既能看到从这台机器发出的DNS查询也能看到返回给这台机器的DNS响应。在一个繁忙的网络里这比单纯写DNS要干净得多。遇到ICMP类问题我往往直接配合IPv4.Protocol 1和!DNS一起使用把DNS的干扰和ICMP放在不同的Display Filter里切换。这些小习惯对于多轮次、长时间的网络排障是真的能明显提升效率。对于初次接触Netmon的读者我强烈建议先把这篇文章里的每一条表达式在真实抓包里跑一遍体会一下“协议解析器驱动的过滤”和“BPF驱动的过滤”之间的差别。Netmon也许不是最强的抓包工具但它的NPL设计在逻辑表达上是自洽且灵活的深入理解它之后你在网络排障这条路上会多一件趁手的兵器。