
1. 项目概述为什么Wireshark过滤DNS是网络分析的必修课刚接触Wireshark的新手面对海量的数据包最常问的问题就是“我怎么只看我想看的” 这感觉就像在嘈杂的菜市场里只想听清隔壁摊位在聊什么。而DNS协议作为互联网的“电话簿”其流量几乎无处不在无论是网站访问、邮件收发还是应用更新第一步往往都是DNS查询。因此精准地从混杂的流量中过滤出DNS协议包是网络排障、安全分析和性能优化的基础技能也是每个网络工程师、安全研究员乃至开发者的必备工具。很多人以为在过滤器里输入“dns”就行了但实战中远不止如此。你可能需要追踪一次完整的域名解析过程需要区分查询和响应需要定位某个特定域名的所有请求甚至需要从加密流量如DoH的元数据中寻找线索。掌握Wireshark过滤DNS的语法就是掌握了从数据洪流中精准“钓鱼”的鱼竿和鱼饵。这篇文章我将结合十多年的抓包分析经验带你从基础语法到实战高阶技巧彻底玩转DNS协议过滤让你下次排查“网页打不开”或“应用连不上”的问题时能直击要害。2. DNS协议与Wireshark过滤基础原理2.1 DNS协议在数据包中的“样貌”在深入语法之前你得知道你在过滤什么。DNS协议主要运行在UDP的53端口有时也会使用TCP/53用于区域传输或当响应数据过大时。在Wireshark中一个标准的DNS查询/响应数据包其协议栈看起来通常是Ethernet - IP - UDP - DNS。Wireshark之所以能让我们用“dns”这个简单的关键字进行过滤是因为它内置了协议解析器Dissector。当它识别到UDP目标或源端口为53或者TCP负载符合DNS报文格式时就会给这个数据包打上一个“DNS”协议的标签。我们过滤时实际上是在匹配这些由Wireshark解析后赋予的协议字段。理解这一点至关重要过滤发生在协议解析之后。这意味着如果一个数据包因为畸形、加密或Wireshark未能正确解析而被误判你的过滤可能会失效。同时这也意味着我们可以利用解析出的丰富字段进行更精细的过滤例如dns.qry.name查询名、dns.flags.response响应标志等。2.2 Wireshark过滤语法的两种核心“武器”Wireshark提供了两处主要的过滤入口用途不同容易混淆显示过滤器Display Filter这是最常用、功能最强大的过滤器。它应用于所有已捕获的数据包仅改变显示结果不会丢弃任何数据。你可以在主窗口顶部的过滤栏中输入。它的语法更丰富支持逻辑运算符和复杂的协议字段匹配。我们本文讨论的核心就是显示过滤器。捕获过滤器Capture Filter在开始抓包前设置“捕获 - 选项”。它基于libpcap/BPF语法在数据包进入捕获缓冲区之前进行过滤被过滤掉的数据包将不会被捕获到磁盘。它的优点是性能高、节省磁盘空间但语法相对简单且无法使用Wireshark解析后的高级协议字段。常用于在已知目标时进行粗筛例如只抓特定主机的DNS流量host 192.168.1.100 and port 53。重要心得除非你非常确定要排除的流量否则建议优先使用显示过滤器。因为捕获过滤器一旦设置就会永久丢失未捕获的数据包。在问题排查初期信息越多越好先用一个宽泛的捕获过滤器甚至不用抓取原始流量再用强大的显示过滤器进行后期分析这是最稳妥的工作流。3. 核心过滤语法实战从入门到精通3.1 基础过滤让DNS流量“现身”最直接的过滤就是让所有DNS流量显示出来。在显示过滤器栏输入dns这会让Wireshark显示所有被识别为DNS协议的数据包。但这样会同时显示查询和响应有时会显得杂乱。如果你想看得更清晰可以区分查询和响应。DNS数据包中有一个标志位dns.flags.response值为0表示查询1表示响应。dns.flags.response 0 // 只显示DNS查询 dns.flags.response 1 // 只显示DNS响应3.2 进阶过滤精准定位目标实际工作中我们很少看所有DNS流量而是聚焦于特定问题。场景一追踪对某个特定域名如www.example.com的所有解析过程。dns.qry.name contains example.com这里使用了contains操作符进行模糊匹配会显示所有查询名中包含“example.com”的请求包括其子域名。如果你需要精确匹配可以使用dns.qry.name www.example.com但注意DNS查询名末尾有一个点根Wireshark有时会显示带点的完全合格域名FQDN。最保险的方式是使用matches操作符配合正则表达式dns.qry.name matches .*\\.example\\.com$这个表达式匹配以“.example.com”结尾的所有查询。场景二排查来自或去往特定IP的DNS问题。假设你的DNS服务器是8.8.8.8你可以这样过滤与它的所有DNS交互(ip.src 8.8.8.8 or ip.dst 8.8.8.8) and dns或者你想看本地主机192.168.1.100产生的所有DNS查询ip.src 192.168.1.100 and dns.flags.response 0场景三分析DNS响应状态。DNS响应中有个重要的dns.flags.rcode字段表示响应码。0表示成功No Error3表示域名不存在NXDOMAIN。排查“找不到服务器”错误时过滤非零响应码非常有用dns.flags.response 1 and dns.flags.rcode ! 03.3 高阶组合过滤还原完整会话网络问题往往需要串联多个数据包来分析。Wireshark的“追踪流”功能很好用但对于DNS我们也可以用手动过滤来模拟。组合查询与响应查看一次完整的DNS事务。DNS报文头有一个dns.id事务ID字段用于匹配查询和响应。首先找到一个你感兴趣的DNS查询包。在包详情面板中展开DNS部分找到Transaction ID字段记下它的值比如0x2a1b。在显示过滤器中输入dns.id 0x2a1b这样这次查询和对应的响应如果有都会显示出来。基于时间的序列分析有时候DNS响应慢你需要看一个时间段内的所有DNS请求。dns and frame.time 2023-10-27 10:00:00 and frame.time 2023-10-27 10:05:00这能帮你定位在某个故障时间点附近系统发出了哪些DNS查询。4. 实战案例拆解排查“网页访问缓慢”假设用户报告访问www.myapp.com时非常慢。你的排查思路是是DNS解析慢还是建立TCP连接慢或是应用本身响应慢第一步就是用Wireshark抓取访问该网站时的流量并聚焦DNS阶段。操作步骤开始捕获在用户主机或网络关键路径上启动Wireshark捕获。捕获过滤器可以设为port 53以减轻负担但如前述我更倾向于先全量抓再过滤。复现问题让用户或你自己访问www.myapp.com。停止捕获应用显示过滤器dns.qry.name contains myapp.com这个过滤会展示所有与myapp.com相关的DNS请求。分析时间线看时序在包列表顶部点击“时间”列确保它显示的是“自从上一个捕获包的时间差”右键点击时间列 - “时间显示格式” - “秒自从上一个捕获包”。这样你能直观看到每个DNS查询之间的间隔。找延迟观察第一个查询通常是A或AAAA记录和它的响应之间的时间差。如果这个差值很大比如超过100ms那么DNS解析就是瓶颈。你可能看到多次查询IPv6 AAAA失败后 fallback 到 IPv4 A这也会增加延迟。看响应检查响应包dns.flags.rcode。如果是3NXDOMAIN说明域名不存在可能是拼写错误或本地HOSTS文件问题。如果是0看dns.count.answers答案数如果为0可能是权威服务器未配置该记录。深入解析如果发现对myapp.com的查询很快但对页面中引用的某个第三方资源域名如cdn.someprovider.com的查询很慢那么问题就出在第三方域名解析上。此时你可以修改过滤器为dns.qry.name contains someprovider.com进行针对性分析。排查技巧在分析延迟时善用Wireshark的“统计” - “对话”功能。切换到“IPv4”或“UDP”标签可以快速看到哪些IP地址之间的DNS流量最多总字节数、包数这有助于发现异常的DNS通信对例如本机在向一个非预期的地址进行大量DNS查询可能中了恶意软件。5. 常见问题与排查技巧实录即使语法熟练实战中还是会遇到各种“坑”。下面是一些常见问题及解决思路。5.1 为什么我的过滤表达式不生效这是新手最常遇到的问题可能的原因有拼写或字段名错误Wireshark的协议字段名是大小写敏感的且有时包含点号。最可靠的方法是在包详情面板中右键点击你感兴趣的字段然后选择“作为过滤器应用” - “选中”。Wireshark会自动将正确的字段名和值填入过滤栏。例如右键点击查询名www.baidu.com选择“…作为过滤器应用 - 选中”你会看到过滤栏自动生成了dns.qry.name www.baidu.com。数据包未被正确解析为DNS如果端口不是标准的53或者数据包是碎片化的Wireshark可能无法识别。你可以尝试用端口过滤udp.port 53。对于非标端口如DoH的443你需要用更底层的字段过滤例如用tls.handshake.extensions_server_name来过滤TLS握手中的SNI服务器名称指示间接分析DoH流量。使用了错误的过滤类型确保你是在“显示过滤器”栏输入而不是“捕获过滤器”栏。两者语法不同。5.2 如何过滤DNS over HTTPS (DoH) 流量DoH将DNS查询封装在HTTPS中传统的dns过滤器对其无效。你需要通过其他特征来识别目标IP和端口已知的公共DoH服务器IP如8.8.8.8,1.1.1.1和TCP/443端口。过滤器(ip.dst 8.8.8.8 or ip.dst 1.1.1.1) and tcp.port 443TLS SNI客户端在TLS握手时会发送DoH服务器的域名如dns.google。过滤器tls.handshake.extensions_server_name contains dns.googleHTTP路径DoH有特定的URI路径如/dns-query。但Wireshark需要在解密TLS后才能看到HTTP层。如果你有会话密钥可以解密TLS后用http.request.uri过滤。5.3 如何统计DNS查询的频次和类型Wireshark内置了强大的统计工具。统计查询类型点击“统计” - “协议分级”。在列表中找到“DNS”展开后可以看到各种DNS报文类型A, AAAA, PTR, MX等的分布和占比。统计查询域名点击“统计” - “对话”选择“UDP”标签。虽然这里主要看IP对话但你可以结合显示过滤器先过滤出DNS响应包dns.flags.response 1然后再打开“对话”统计这样看到的通信对基本就是DNS查询-响应对通过包数量可以判断频率。使用tshark命令行进行离线分析更强大# 统计捕获文件中所有查询的域名及其出现次数 tshark -r your_capture.pcap -Y dns.flags.response 0 -T fields -e dns.qry.name | sort | uniq -c | sort -nr # 统计不同的DNS查询类型 tshark -r your_capture.pcap -Y dns -T fields -e dns.qry.type | sort | uniq -c这条命令会先过滤出DNS查询包-Y相当于显示过滤器然后提取查询名字段-e dns.qry.name最后进行排序、去重和计数。5.4 过滤表达式性能优化当捕获文件非常大几个GB时复杂的显示过滤器可能会让Wireshark界面卡顿。一些优化建议先粗后精先用一个宽泛的过滤器如dns加载出所有DNS包然后在此基础上用and添加更细的条件。Wireshark会对过滤结果进行缓存。避免在超大文件中使用containscontains操作符需要逐包进行字符串匹配非常耗资源。如果可能尽量使用精确匹配或基于数值如dns.id,dns.flags.rcode的过滤。使用捕获过滤器预过滤如果你明确知道分析范围例如只关心与特定DNS服务器的通信那么在抓包时就用捕获过滤器host 8.8.8.8 and port 53可以极大地减小文件体积提升后续分析效率。6. 将过滤能力融入日常工作流掌握了语法和技巧如何让它真正为你所用我分享几个我常用的工作流片段。日常巡检脚本化对于需要定期检查DNS健康状况的场景可以编写脚本利用tsharkWireshark的命令行版本自动分析。#!/bin/bash # 检查pcap文件中是否存在NXDOMAIN错误 TSHARK_OUTPUT$(tshark -r network_capture.pcap -Y dns.flags.rcode 3 -c 5) if [ -n $TSHARK_OUTPUT ]; then echo 警告捕获文件中发现DNS NXDOMAIN错误 echo $TSHARK_OUTPUT fi复杂过滤器的保存与复用在Wireshark显示过滤器栏输入表达式后点击右侧的“”号可以将其保存为一个命名的过滤器配置文件。例如我可以保存一个名为“DNS_Problems”的过滤器内容为dns.flags.response 1 and dns.flags.rcode ! 0。下次需要排查DNS错误时直接从下拉菜单选择即可无需重新输入。与着色规则联动Wireshark的着色规则可以让你一眼锁定特殊包。你可以创建一条新的着色规则规则字段填dns.flags.rcode关系选择值填3然后背景色设置为醒目的红色。这样所有NXDOMAIN响应包在列表中都会以红色高亮显示极大提升分析效率。过滤DNS协议包这项技能的价值远不止于解决“网页打不开”。在安全领域它可以用于检测DNS隧道、域名生成算法DGA流量在性能优化领域它可以帮你分析CDN调度是否合理、本地缓存是否生效。其核心思想是通用的利用协议的结构化特征从混沌中提取信号。当你熟练运用Wireshark的过滤语法后你会发现分析HTTP、TCP、TLS等其他协议思路也是相通的——无非是找到那个关键的字段然后构建你的“捕鱼网”。下次抓包时别急着在密密麻麻的数据里用肉眼搜寻先花十秒钟想想你的过滤器该怎么写。