
排查网络问题这件事我向来不愿意只靠 ping 一通就下结论。前阵子处理一个 DNS 解析慢到 5 秒的现场故障我掏出 Microsoft Network Monitor 抓了两分钟包先用一条抓包筛选器把 53 端口相关流量单独圈出来再切到显示筛选器看查询和响应的往返时间问题范围一下就锁定了。这篇文章就把我在 Netmon 里折腾 Capture Filter 和 Display Filter 的完整经验理一遍重点覆盖 DNS、IP、ICMP 这三类日常最常用的过滤场景。如果你手上还有旧 Windows 环境或者出于合规要求不能随便装第三方工具又恰好有 Netmon 可用这文章能帮你少走不少弯路。就算你平时主力用 WiresharkNetmon 这套筛选器设计思路也值得对比着看很多概念是相通的细节上又坑得很不一样。1. 老工具的新价值为什么现在还有人用 NetmonMicrosoft Network Monitor 3.4 是微软当年免费提供的抓包分析工具现在已经很多年没有更新了。但停止更新不等于不能用。我在不少客户现场见过它的身影系统是老的 Windows Server安全策略又特别严外网工具根本装不进去可 Netmon 偏偏就在那台机器上好好地躺着。这种时候它就是唯一的抓手。它依然有价值的地方我总结下来有三个场景受管控环境下的应急排查。生产内网机器不让装 Wireshark或者装驱动需要审批Netmon 作为微软官方组件反而可能已经预置能用就先用上。离线分析现有抓包文件。Netmon 打开 .cap/.etl 文件的速度不错多窗口并列也很顺手适合做离线复盘。学习协议解析和筛选器语法。它的字段浏览器和协议树做得直观拿它入门协议字段怎么组织这件事反而比看文档更快。和 Wireshark 放在一起说两者的差异其实很明显。Netmon 的字段命名风格是协议缩写点属性名比如IPv4.SourceAddress、TCP.SourcePortWireshark 则是全小写加下划线那套像ip.src、tcp.srcport。这对从 Netmon 转过去的用户来说最大的障碍不是思路而是字段名记忆。另一个差异是协议解析器的更新速度Wireshark 社区活跃新协议基本几个月内就有解析器Netmon 则停在老时间线QUIC、TLS 1.3 细节这类新东西基本指望不上。所以我对 Netmon 的定位很明确它是老环境里的救急工具也是理解抓包筛选器概念的好教材。真正跑新项目、做深度协议分析我还是会切回 Wireshark。但会 Netmon 的筛选器这件事本身不会白学因为 Capture Filter 和 Display Filter 的边界思维、组合过滤的逻辑在哪个抓包工具里都一样。2. 两类筛选器的边界先搞清楚再动手很多新手拿着 Netmon 就开始抓包抓完发现文件巨大于是跑到 Filter 栏里敲一条条件以为这样文件就变小了。这是对两类筛选器最大的误解。Capture Filter 和 Display Filter 虽然语法长得像但作用时机和本质完全不同。Capture Filter 在驱动层面工作。也就是说抓包过程中不符合条件的数据包根本不会被保存到文件里。它发生在数据还没进入分析器之前是个物理截断的操作。这样做的好处是省磁盘、省内存抓一个上百兆流量的接口时Capture Filter 能让你只落盘感兴趣的流量。代价是过滤掉的信息永远回不来了后续想分析什么都得重新抓。Display Filter 则纯粹是视觉隐藏。所有帧都已经在抓包里了显示筛选器只是把不符合条件的帧藏起来数据文件本身没有变化。你随时可以删掉筛选器所有帧又全部回来了。所以它再花哨也解决不了文件体积和抓包性能的问题。下面这个表可以快速理解两者的差异对比项Capture FilterDisplay Filter作用时机抓包前/抓包中抓包后分析时是否丢弃数据是不符合条件的帧不落盘否只隐藏显示对抓包性能影响能减少负载无影响适用场景高流量环境、存储受限精确分析、逻辑组合语法支持范围受驱动限制字段较少几乎所有已解析字段我个人的选择原则就一句话没把握就抓全。因为绝大多数排障不是一个端口、一个协议能圈定的。你以为问题在 UDP 53抓完发现客户端确实发了大量 UDP 53 查询但响应是通过 TCP 53 回来的可 Capture Filter 里只写了 UDP于是关键证据一个没落下——不对是一个都没有。重抓不仅浪费时间还可能错过故障复现时机。时序上也很有意思。Capture Filter 只对设置之后新抓到的帧生效Display Filter 对历史文件也能随便用。这意味着你完全可以在第一次抓包时用一个很宽的 Capture Filter 兜底比如只限定TCP || UDP等抓到足够数据后再用 Display Filter 反复琢磨。真要为了省那几百兆存储把过滤写死后面八成会后悔。磁盘便宜复现昂贵这个账要算清楚。3. Capture Filter 实操抓之前把范围圈定Netmon 的 Capture Filter 编辑入口在开始抓包的界面上有一个专门的编辑区域支持两种方式可视化点选和直接写表达式。可视化方式比较适合记不住字段名的人。左侧会列出协议树你勾选 TCP、UDP再填地址、端口点 Add 就会追加到表达式列表里。这种方式生成的表达式不一定最简但至少不会写错大小写。直接输入方式则更快前提是你记得住字段名。Netmon 3.x 的 Capture Filter 语法和 Display Filter 很像但可用字段受驱动限制通常集中在 IP、端口、协议这些核心信息。常见的写法有IPv4.SourceAddress 192.168.1.100 TCP UDP (UDP.SourcePort 53 || UDP.DestinationPort 53) IPv4.SourceAddress 10.0.0.5 || IPv4.DestinationAddress 10.0.0.5这里有几句要特别说明。第一句表示只抓来源地址是 192.168.1.100 的 TCP 包。第二句表示抓所有 UDP 53 端口的流量无论它是源端口还是目的端口。如果你只写UDP.DestinationPort 53那么就只会抓到发往 53 端口的查询请求而响应报文是从 53 端口发出来的源端口是 53目的端口是随机高位端口结果响应全被过滤掉了。这个坑我踩过一次之后凡是端口过滤一律用源或目的的写法。Capture Filter 里的逻辑运算和大多数筛选器一致表示 AND||表示 OR!表示 NOT括号可以控制优先级。比如要抓指定 IP 的非 DNS 流量IPv4.SourceAddress 192.168.1.100 !(UDP.SourcePort 53 || UDP.DestinationPort 53)这种组合表达式在排查某台机器除了 DNS 之外还有什么异常连接时特别有用。这一节最后说三个很容易翻车的细节。第一Capture Filter 输错了不会像代码那样报红。Netmon 不会告诉你你这个字段名写错了而是很可能直接给你抓一个空文件你还以为是网卡没流量。所以每次开始抓包前我习惯随手发一个 ping确认帧数在跳再进入正式抓包。第二Windows 下必须右键以管理员身份运行。Netmon 抓包依赖底层驱动权限不够时网卡列表可能为空或者点开始抓包后一直显示不出数据这时候先别怀疑网卡检查权限。第三Capture Filter 能用的字段远少于 Display Filter。某些在显示筛选器里很好用的文本字段比如域名在捕获阶段根本不能用因为驱动没有做深层协议解析。想按域名抓包只能退而求其次用 IP 或端口先圈住抓完再靠 Display Filter 去细化。4. Display Filter 实操海量帧里定位问题Display Filter 才是日常用得最频繁的筛选器。抓完一个文件动辄几万帧你要做的就是在顶上那根 Filter 输入框里敲表达式把目标流量拎出来。Netmon 显示筛选器的基本结构是字段名 运算符 值。常见运算符包括等于!不等于大于、小于contains包含某个字符串matches用正则匹配组合逻辑和 Capture Filter 一样用、||、!和括号。随便举几个例子// 只看 443 端口相关流量 TCP.SourcePort 443 || TCP.DestinationPort 443 // 只看某个 IP 发出的 HTTP 请求 IPv4.SourceAddress 192.168.1.100 HTTP ! NULL // 排除所有 DNS 报文 ! DNS注意这里的和||都是两个字符不能像编程里那样想当然用一个。同字段多值比较最好用括号包起来比如上面 443 端口的写法能有效避免歧义。Netmon 有一个特别好用的功能叫字段浏览器。当你打开一个抓包文件双击任意一帧会看到非常详尽的协议树。把鼠标悬停或者点到某个字段上字段浏览器区域就会显示它的完整字段名。这一手极为关键因为 Netmon 不同版本的字段命名有细微差别你记不住没关系字段浏览器会告诉你准确写法。比如 DNS 报文的查询名我印象里字段名是DNS.DnsQueryName但只要我双击一个 DNS 帧选中名称那一行字段名就明明白白列在那。先选中、再插入到筛选器全程不会出现大小写或拼写错误。这个习惯对新手非常友好是你从背字段名升级成查字段名的分水岭。contains 和 matches 是文本过滤的利器。比如某个内网客户端在上报数据你想找出所有与update-server域名相关的流量DNS.DnsQueryName contains update-servermatches 则支持正则适合批量匹配一段 IP 或一类 URLIPv4.SourceAddress matches 192\.168\.1\.[0-9]不过实际用下来我很少把正则用得特别花哨。网络抓包文件里乱码多、分段多复杂正则的效果往往不如多条件组合来得直观。它更适合处理一批地址段这种明确需求。显示筛选器的常见错误也很集中。一个是比较符写成单Netmon 不会报错但结果永远是空或者全部让人摸不着头脑。另一个是字符串值忘加引号尤其是域名和 URL一旦漏引号表达式会变成非法语法。再一个就是括号不配对尤其当表达式一长串的时候我建议在文本编辑器里先折叠好层级再粘进去能减少很多无谓的挫败感。5. DNS 过滤把解析慢变成可视化证据DNS 是几乎所有上不了网类故障绕不开的环节而且它报文短、数量多、时间敏感非常适合用筛选器去聚焦。Netmon 里看 DNS 流量最基础的一条就是DNS只输入协议名就能把所有 DNS 查询和响应滤出来。如果想继续收紧到某个域名用 containsDNS.DnsQueryName contains example想锁定某台 DNS 服务器可以配合 IP 过滤IPv4.SourceAddress 8.8.8.8 || IPv4.DestinationAddress 8.8.8.8这三个表达式基本覆盖了按协议、按域名、按服务器三个维度的 DNS 过滤需求。实际排查时我习惯先看时间偏移这一列。在 Netmon 中把 Time Offset 列调出来然后过滤 DNS整个视图会变成一行行查询/响应记录。接下来重点找两类现象。一类是解析慢。最典型的画面是客户端连续发出多次同样的查询但每一次响应都姗姗来迟甚至间隔越来越长。这种情况下问题往往不在网络上而在客户端或缓存服务器。如果客户端发了一次查询对面立刻回了回包却停在网卡附近出不去那就是本地网络或者防火墙的问题。反过来查询发出去了石沉大海没有任何响应同时你又没看到 ICMP 错误报文那么路径上的某个节点极有可能在静默丢弃 UDP 53 报文。另一类是解析失败。筛选出目标域名的所有 DNS 帧之后点开响应帧看 DNS 标志位里的返回码。如果返回的是 NXDomain说明域名本身不存在得去查拼写、查 DDNS 配置如果返回的是 ServerFailure那问题在递归服务器上游可能是转发配置或者根区访问受限。这俩方向完全不同没有抓包数据你很难判断用户报的解析不了到底是哪一种。这里还要强调一个非常容易被忽略的细节DNS 不止 UDP 53还有 TCP 53。大响应、区域传送都走 TCP。你抓包时如果 Capture Filter 只写了 UDP那么超过 512 字节的 DNS 响应就全丢了而这些恰恰可能是问题所在。更稳妥的写法是把 4 个条件一起写上(UDP.SourcePort 53 || UDP.DestinationPort 53) || (TCP.SourcePort 53 || TCP.DestinationPort 53)最后提一下耗时测算。在 Netmon 里右键列头可以添加 Time Offset 字段它表示每帧相对开始抓包时间的偏移量。你只需要找到同一个查询 ID 对应的请求帧和响应帧两者时间偏移相减就是这个查询的响应耗时。这比你在界面上肉眼翻帧找快得多。6. IP 过滤按地址切开会话IP 过滤是排障中最常用的手术刀。它的作用不是展示所有流量而是把目标机器的所有行为从茫茫帧海里切出来。最基础的是单 IP 双向过滤也就是不管这个 IP 是源还是目的只要跟它有关的都给我看IPv4.SourceAddress 192.168.1.100 || IPv4.DestinationAddress 192.168.1.100这句话在 Netmon 里怎么强调都不过分因为很多人第一反应是只写IPv4.SourceAddress 192.168.1.100结果只看到这台机器发出去的包看不到对方回给它的包整个会话在视图里变成了单行道分析自然跑偏。如果你只看这台机器发出去的数据那当然可以只留 SourceAddressIPv4.SourceAddress 192.168.1.100但更常见的需求是两个 IP 之间的完整会话那我推荐把双向关系写成括号加 OR 的完整形式(IPv4.SourceAddress 192.168.1.100 IPv4.DestinationAddress 192.168.1.200) || (IPv4.SourceAddress 192.168.1.200 IPv4.DestinationAddress 192.168.1.100)这一长串看着啰嗦但它能保证你看到的每一帧都属于这两个 IP 之间的通信不会混进第三个 IP 的旁路流量。在实际排障时这比关心所有跟某 IP 有关的流量更精确。IPv6 的写法完全一致只是字段名换成IPv6.SourceAddress和IPv6.DestinationAddressIPv6.SourceAddress fe80::1 || IPv6.DestinationAddress fe80::1IP 过滤通常还要叠加协议和端口。比如要查一台数据库客户端为什么连接超时可以先过滤客户端 IP再叠加TCP接着进一步指向目标端口IPv4.SourceAddress 10.0.0.5 || IPv4.DestinationAddress 10.0.0.5这是第一层保底全部流量然后根据分析进度在显示筛选器里追加IPv4.SourceAddress 10.0.0.5 || IPv4.DestinationAddress 10.0.0.5等等这里有个实操技巧Netmon 的筛选器是可以分步叠加的你可以先输入一个大的 IP 条件回车然后再在已有结果基础上追加第二个条件。这样做的好处是每一轮都能确认当前范围没有过度收缩而不是一步到位写了三个条件结果一片空白根本不知道哪一步写错了。我遇到过一次很典型的场景某服务从别的机器访问不通但从本机访问正常。抓包后先按服务端 IP 过滤很快就看到 TCP 三次握手只有 SYN 发出没有 SYN-ACK 回来。再叠加源端口和目标端口定位到是防火墙策略只放行了内网网段外部访问全被静默丢弃。整个过程从抓包到定位不超过五分钟靠的就是 IP 过滤先把范围切到最小再一层层加条件。7. ICMP 过滤ping 不通不能只看表面ping 大概是所有人第一个会的网络命令但 ping 不通的原因千奇百怪。ICMP 过滤能帮你把ping 不通这个模糊描述拆成一个具体的技术原因。Netmon 里只看 ICMP 流量的筛选器就一个词ICMP但光看 ICMP 还不够因为 ICMP 有很多类型不同类型代表完全不同的含义。日常排障最常用的是下面几个ICMP 类型含义常见场景0Echo Replyping 响应3Destination Unreachable目标不可达下面还有细分 Code5Redirect路由重定向8Echo Requestping 请求11Time ExceededTTL 超时典型是有路由环路只过滤 ping 请求ICMP.Type 8只过滤 ping 响应ICMP.Type 0过滤所有目标不可达ICMP.Type 3目标不可达这个类型下面还带 CodeNetmon 里可以继续用ICMP.Code细分。Code 为 0 表示网络不可达Code 为 1 表示主机不可达Code 为 4 表示需要分片但设置了不分片标志。这个信息在判断问题方向时极有价值。我自己的排查逻辑是这样的。抓包过程中 ping 一直不通先过滤 ICMP看有没有 Type 8 的 Echo Request 发出。如果连发出去的请求都看不到那问题在本地要么网卡断了要么本地防火墙没放行 ICMP。如果能看到 Echo Request但看不到 Echo Reply也没有任何 ICMP 错误报文那基本可以判断是路径上某个设备把 ICMP 静默丢弃了。这时候再去看有没有 Type 11如果有说明是 TTL 耗尽导致的中途丢弃需要查路由环路如果有 Type 3 Code 1说明路由已经到了目标网段但目标主机本身没有响应。这个看 ICMP 类型码再下结论的习惯帮我避免了很多次误判。有一次用户报网络断了抓包一看全是 Type 3 Code 1说明路由是通的只是目标主机没有回应最后查出来是那台服务器上的网卡驱动挂了跟交换机一点关系都没有。如果在抓包阶段就想缩小范围可以用 Capture Filter 只抓出入目标 IP 的 ICMPICMP (IPv4.SourceAddress 192.168.1.1 || IPv4.DestinationAddress 192.168.1.1)另外提醒一句Windows 默认 ping 会连续发送最长可以无限循环。抓包时如果用 Capture Filter 只抓 ICMP文件可能很快被刷屏。我建议先把 ping 次数设成 5 到 10 个包比如 Windows 下用ping -n 10 目标IP抓完即停干净利落。8. 组合场景与收尾一次完整的过滤式排障前面几节是把三类过滤拆开讲实际工作中它们几乎总是混在一起用。我以一个客户端访问数据库服务持续超时的案例演示完整的组合过滤流程。第一步设置捕获筛选器。因为要处理的机器很大概率在远程我不想把无关流量也抓到本地所以在 Capture Filter 里做最宽松的限制IPv4.SourceAddress 10.0.0.5 || IPv4.DestinationAddress 10.0.0.5第二步开始抓包。与此同时让用户重新执行一次数据库连接操作大概 30 秒后停止抓包。这时候文件已经很小了因为 Capture Filter 把范围圈在了那台客户端 IP 上。第三步用显示筛选器逐步收窄。先整体看一眼这台机器的流量分布IPv4.SourceAddress 10.0.0.5 || IPv4.DestinationAddress 10.0.0.5然后盯连接数据库服务的端口IPv4.SourceAddress 10.0.0.5 || IPv4.DestinationAddress 10.0.0.5最后叠加 TCP 和具体端口TCP (TCP.SourcePort 1433 || TCP.DestinationPort 1433)这一串下来视线就集中到了客户端到数据库服务器 1433 端口的 TCP 会话上。如果 SYN 重传频繁、迟迟没有 SYN-ACK问题基本锁定在网络中间链路或防火墙放行策略。事实也正是如此最终查出来是防火墙只放行了应用服务器的网段客户端所在 VLAN 不在白名单里。组合过滤里还有个小技巧Netmon 允许把常用筛选器保存下来。Display Filter 输入框旁边一般有保存按钮你可以把 DNS、ICMP、按 IP 查会话这类固定表达式存成模板下次直接下拉选择。团队协作时也可以把筛选器文本直接贴在工单里对方复制就能用省得每次重新敲。关于工具的未来我也想说点实在话。Netmon 已经是很多年前的老家伙了新环境、新协议、新网卡支持都跟不上我不会把它当主力工具推荐。但筛选器这套方法论是不过时的Capture Filter 管留什么Display Filter 管看什么两者边界理清之后你在 Wireshark 里也就是换一套字段名的区别。我在 Wireshark 里想过滤来源 IP会习惯性敲ip.src但思路还是从 Netmon 的IPv4.SourceAddress迁移过来的。如果非要说一条最值得记住的经验那就是抓包前宁可把 Capture Filter 放宽一点抓包后多花几秒钟在 Display Filter 上精挑细选。我见过太多次因为 Capture Filter 写太紧而重抓的案例包括我自己。筛选器不是越窄越好它首先要保证关键证据不漏其次才是范围越小越好。能把这两句话想明白Netmon 这套工具在你手里就算真正玩明白了。