DNS报文分析实战:从字节流到网络故障排查的完整指南

发布时间:2026/9/16 23:40:03
DNS报文分析实战:从字节流到网络故障排查的完整指南 说到 DNS 报文分析我估计不少人在头歌上卡在这一关不是因为不会点 Wireshark而是对着一堆十六进制字节不知道该怎么“翻译”成人话。我当年第一次用 tcpdump 抓到 DNS 请求时也是一脸懵满屏的0x5c5c、0x1c 0x0c看着跟乱码似的。后来真正把 DNS 报文从头到尾拆过一遍才发现这东西一旦看懂了对后面排查网络问题、理解域名劫持、甚至做安全分析都特别有用。这篇内容就围绕 DNS 报文分析来写重点拆解报文里每个字段到底在说什么头部标志位怎么读问题区域和回答区域是怎么组织的以及怎么用工具真正抓到一条完整的 DNS 报文并逐段解出来。不管你是正在刷头歌的在校学生还是工作中需要自己抓包排障的运维、开发这篇都可以直接当操作手册用。1. 内容整体设计与思路拆解这一关叫“DNS 报文分析”说白了就是把 DNS 协议从抽象的理论变成具体的字节流然后让你看懂每一个字节的含义。很多同学在前面几关背了 DNS 报文格式图知道头部有 Transaction ID、Flags、QDCOUNT 这些字段但到了分析题就懵了原因只有一个没把“格式图”和“真实报文”对应起来。1.1 为什么一定要会看真实报文学习 DNS 最忌讳的就是只记结论不碰字节。协议格式图是静态的但真实网络环境里的报文是有各种变化的比如域名用指针压缩、响应里附带多条 A 记录、EDNS0 扩展字段、TC 位被置 1 导致需要 TCP 重查这些东西格式图上往往画不全只有亲手解析过真实报文才能有体感。我在排查线上问题的时候遇到过好几次类似的情况开发说“域名解析有时快有时慢”你 ping 域名都正常但实际请求就是超时。后来抓包一看发现响应报文里带了 6 条 A 记录其中一条指向了早已下线的机房 IP客户端随机选到那个 IP 就卡住了。这种问题不看报文根本定位不了。另外一个理由是安全方向。DNS 报文分析是理解缓存投毒、域名劫持、放大攻击的基础。你连响应包里多出来的一条 CNAME 都看不出来那别人给你返回一个恶意 IP 你也不可能发现。所以别觉得这关只是刷学分它其实是敲门砖。1.2 从头歌第 3 关反推整个 DNS 知识体系头歌实训通常不会单独出“报文分析”这一关它前面一般有 DNS 基础概念、域名解析过程、DNS 服务器配置等铺垫。第 3 关放在中间位置正好是“理论 → 实操”的转折点你要开始用抓包工具去验证前面学的解析过程。所以学这一关之前建议先把这几个概念过一遍DNS 默认跑在 UDP 53 端口TCP 53 用于区域传送和超大响应、域名是分层结构从根到叶子、A 记录是域名到 IPv4、AAAA 记录是域名到 IPv6、CNAME 是别名、NS 记录是负责某域的权威服务器。这些都是前面关卡的内容如果忘了现在补也来得及。实操层面你需要准备的工具就三样抓包软件Wireshark 或者 tcpdump 都行、dig/nslookup 命令、一个十六进制查看器其实抓包软件的字节面板就够了。不会用 Wireshark 也没关系后面我会从怎么选网卡开始讲。2. 核心细节解析与实操要点DNS 报文的结构一句话总结就是“头部 问题区域 回答区域 权威区域 附加区域”。五个部分只有头部是必须存在的后面四个区域根据查询和响应的不同数量会变化。理解这种“变长”结构是解析报文的第一步。2.1 报文头部12 字节定乾坤一条 DNS 报文最开头固定是 12 字节的头部不管查询还是响应都一样。这 12 个字节包含这些字段Transaction ID事务 ID、Flags标志位、QDCOUNT问题数、ANCOUNT回答数、NSCOUNT权威记录数、ARCOUNT附加记录数。Transaction ID 占 2 字节用来把请求和响应配对。你发一个查询客户端会在本地记住这个 ID等响应回来时看 ID 一致才认领。如果事务 ID 能被预测或者被伪造就容易引发缓存投毒这也是为什么后来有了随机化事务 ID、0x20 编码等防御手段。Flags 字段占 2 字节是解析的重点。它里面有 QR 位0 表示查询、1 表示响应、Opcode通常为 0 表示标准查询、AA 位权威回答、TC 位截断标志、RD 位期望递归、RA 位递归可用、RCODE响应码4 位。在 Wireshark 里这些是折叠展开的但如果你用 tcpdump 拿到的是十六进制就得自己手动拆二进制。比如0x8180拆成二进制是1000 0001 1000 0000QR1、Opcode0、AA0、TC0、RD1、RA1、RCODE0含义就是“这是一个设置了 RD 和 RA 的标准响应无错误”。Qdcount、Ancount 等四个计数器用于说明后面各区域记录的数量。比如你看 Ancount 是 0说明这条报文里没有回答记录那它八成是一条“请求”或者“NXDOMAIN域名不存在”的响应。2.2 问题区域域名是怎么按“长度 字节”编码的问题区域的结构比很多人想象中简单就三样东西QNAME查询的域名、QTYPE查询类型、QCLASS查询类别。难点在 QNAME 的编码方式。QNAME 不是直接写“www.example.com”而是分段存储的每段前面用一个字节表示该段的长度段里的字符按 ASCII 顺序排列最后以0x00表示域名结束。比如www.example.com的 QNAME 就是03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00。注意这里的03是十六进制的 3对应后面 3 个字符“www”07对应 7 个字符“example”。QTYPE 占 2 字节常见值对应如下1 是 A 记录IPv4、28 是 AAAA 记录IPv6、5 是 CNAME、15 是 MX邮件交换、2 是 NS、12 是 PTR反向解析、255 是 ANY查询所有类型。QCLASS 一般就是 1表示互联网地址类几乎不会看到别的值。在头歌第 3 关里经常会给一段十六进制让你补全 QNAME 对应的域名或者反过来给你域名让你写出 QNAME 字节。核心就是记住“长度 标签 零结尾”这套规则特别是别数错长度一个字符数错整段就乱了。2.3 回答区域资源记录的通用模板回答区域、权威区域、附加区域里装的都是“资源记录”Resource RecordRR格式是统一的NAME2 字节或指针、TYPE2 字节、CLASS2 字节、TTL4 字节、RDLENGTH2 字节、RDATA变长。NAME 字段有个坑它不一定重复写完整域名而是可能使用“指针压缩”。比如响应里第一条记录的名字跟问题区域的域名一致就会写成c0 0c表示“从报文的第 12 个字节开始读域名”这样能省不少空间。Wireshark 会自动翻译指针你看到www.example.com其实在字节层面对应的是c0 0c。分析报文时如果看到c0开头且最高两比特是11就得用指针跳转去拼接域名。TTL 字段是 4 字节无符号整数单位是秒表示这条记录在缓存里能存活多久。安全分析中特别关注异常低的 TTL比如恶意软件常把 CNAME 的 TTL 设成 0 或者几十秒方便随时切换上游地址。RDLENGTH 告诉你 RDATA 有多少字节根据 TYPE 不同RDATA 内容也不同。A 记录的 RDATA 固定 4 字节就是 IPv4 地址AAAA 记录固定 16 字节NS 记录的 RDATA 是一个域名也可能用指针压缩。3. 实操过程与核心环节实现说完了理论终于到动手环节。这里我把整个 DNS 报文分析流程拆成四步准备环境、抓包、解析、对照验证。每一步我都会写成可以直接照着操作的形式用的工具是 Wireshark dig这两个在任何主流系统上都能跑。3.1 准备环境抓包前必须做的三件事第一件事是把网卡选对。笔记本上一般有有线网卡、无线网卡、虚拟网卡装 VMware 或 VirtualBox 后会多出几个Wireshark 启动界面会让你选。抓普通上网流量就选你正在使用的那个网卡不确定的话可以先抓一下看看有没有包再决定。第二件事是关闭流量加密干扰。DNS 本身大多数情况是明文 UDP 53 端口不用解密也能看。但如果你的系统开了 DoHDNS over HTTPS那就抓不到传统 DNS 报文只能看到 443 端口的加密流量。我建议测试时把浏览器的安全 DNS 关掉或者直接用命令行工具 dig 来产生 DNS 流量。第三件事是配置显示过滤器。启动抓包后在过滤栏输入dns回车就只显示 DNS 协议相关的包。这样不会混入大量 TCP 握手、TLS 证书等无关流量。如果想精确一点可以输入dns.qr 0只看请求dns.qr 1只看响应。3.2 实操抓包用 dig 触发一条真实 DNS 请求环境准备好了打开终端输入dig www.example.comWireshark 里立刻会出现至少两条新的 DNS 包一条是请求一条是响应。选中那条请求包在中间的协议树里展开“Domain Name System (query)”你会看到事务 ID、Flags、Question 等信息。再点左下角的字节面板就能看到十六进制和 ASCII 对照显示。我第一次做这个操作的时候习惯性只看协议树觉得字节面板没什么用。后来工作中需要写抓包解析脚本才发现协议树是 Wireshark 帮你翻译好的并不是原始字节。要真正“分析”报文还得学会看字节。这里给个实操技巧在字节面板里把光标移到03这个字节上右边树会自动高亮到对应的 QNAME 字段你就知道这个字节对应协议的哪个元素了。多拖动几次格式图和真实报文就自然建立联想了。3.3 手动解析一个 DNS 查询报文假设抓到请求包从第 42 个字节开始是 DNS 头部前面是以太网头 IP 头 UDP 头字节形如ab cd 01 00 00 01 00 00 00 00 00 00 03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 01 00 01逐段拆解ab cd事务 ID这是个随机值。01 00Flags。拆成二进制就是0000 0001 0000 0000QR0、Opcode0、AA0、TC0、RD1、RA0、RCODE0说明是一条“期望递归”的标准查询。00 01QDCOUNT问题数为 1。00 00ANCOUNT回答数为 0。00 00NSCOUNT权威记录数为 0。00 00ARCOUNT附加记录数为 0。03 77 77 77第一个标签长度 3内容为“www”。07 65 78 61 6d 70 6c 65第二个标签长度 7内容为“example”。03 63 6f 6d第三个标签长度 3内容为“com”。00根标志域名结束。00 01QTYPE值为 1表示 A 记录。00 01QCLASS值为 1表示互联网类。这条查询的完整含义就是用事务 ID0xabcd查询域名www.example.com的 A 记录查询类别为互联网类客户端期望递归解析。3.4 手动解析一个 DNS 响应报文响应报文比查询稍微复杂因为多了资源记录。假设响应报文的关键字节如下省略 IP/UDP 头直接从 DNS 部分开始ab cd 81 80 00 01 00 02 00 00 00 00 03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 01 00 01 c0 0c 00 01 00 01 00 00 00 3c 00 04 c0 a8 01 01 c0 0c 00 01 00 01 00 00 00 3c 00 04 c0 a8 01 02ab cd事务 ID跟请求一致。81 80Flags拆开是1000 0001 1000 0000QR1、Opcode0、AA0、TC0、RD1、RA1、RCODE0表示标准响应无错误。00 01QDCOUNT问题数为 1。00 02ANCOUNT回答数为 2说明有两条 A 记录。后面 3 个字节的 QNAME、2 字节 QTYPE、2 字节 QCLASS 就是回显了请求里的查询问题。c0 0c指针压缩指向报文的第 12 字节也就是“www.example.com”。00 01TYPEA 记录。00 01CLASSIN。00 00 00 3cTTL60 秒。00 04RDLENGTH4 字节。c0 a8 01 01IPv4 地址192.168.1.1。第二条记录结构完全一样只是最后地址变成192.168.1.2。如果你在头歌上是做代码填空题大概率就是让你补全类似这样的一段解析逻辑根据 QDCOUNT 跳过问题区域再按 ANCOUNT 循环读取资源记录。理解上面这个示例代码怎么写心里就有数了。3.5 实操现场记录一次完整的“非正常”响应分析有一次我用 tcpdump 抓一个内部系统的 DNS 解析发现响应速度有问题于是顺手把包保存下来分析。抓包命令是sudo tcpdump -i eth0 -s 0 -w dns_issue.pcap port 53模拟故障复现后停止抓包用 Wireshark 打开 dns_issue.pcap过滤dns.flags.response 1我发现其中一条 ACK 记录特别有意思Ancount 是 3但第一条回答是 CNAME指向一个新域名后两条是 A 记录。乍一看一切正常但仔细看 TTL 只有 5 秒而正常内网解析一般是 300 秒以上。这就说明这条 DNS 记录被动态更新过很可能是故障切换产生的。再深入看响应包的附加区域里多了 OPT 记录版本号是 0说明客户端和服务器之间协商了 EDNS0。有些老旧的中间设备见到 OPT 记录会直接丢弃导致解析卡住。这就是为什么抓包分析时不能只看“回答区域”有没有答案还要看附加区域里带了什么。很多 DNS 疑难杂症其实是 EDNS0、DNSSEC、TCP 重查这些“非核心”字段引起的。4. 常见问题与排查技巧实录做 DNS 报文分析时我一开始踩过不少坑。很多问题不是你不会看格式而是工具、环境、输入条件不对。下面这几个问题我基本隔三差五就能在教学群或者工作群里看到整理成一个速查表顺便把排查思路写清楚。4.1 明明抓到了 DNS 包但看不到域名很多人抓包后发现协议树里没有“Question”或“Answers”只有 Transaction ID 和 Flags。这种情况最常见的原因是这是 DNS over TCPDoT或者 DNS over HTTPSDoH的流量负载是加密的Wireshark 看不到明文域名。排查方法先看端口号tcp.port 853是 DoTtcp.port 443且应用层协议标为TLS的基本就是 DoH。如果想要明文 DNS 报文建议用 dig 指定传统 DNS 服务器比如dig 8.8.8.8 www.example.com注意这里用的是 8.8.8.8 作为示例公共 DNS实际测试可以换成你单位分配的 DNS 地址。要是你对明文传输格外敏感那 DoH 反而是更好的选择报文分析时直接用浏览器开发者工具看解析结果就行不要用抓包的方式。还有一个容易忽略的原因DNS 报文可能被分片了。当响应报文很大比如带了很多附加记录或 DNSSEC 签名UDP 报文超过 MTU就可能被 IP 分片。此时第一个分片里可能只有头部和部分问题区域第二个分片里才有完整域名。Wireshark 默认会重组 IP 分片但如果抓包时设置了-s抓包长度截断就可能只抓到 96 字节导致重组失败。解决办法是用-s 0抓完整包。4.2 事务 ID 对不上请求被“缓存”了有同学抓包时发现响应的事务 ID 跟请求不一样。这种情况大概率不是 DNS 故障而是你抓的流量跨越了 NAT 或代理。有些网络环境里的 DNS 代理会改写出站请求的 ID并在内部维护一个映射表这种情况在分析时要注意区分“客户端看到的 ID”和“服务端看到的 ID”。另一种可能是你开了某种网络加速工具它拦截了 DNS 请求自己作为“伪 DNS 服务器”返回结果此时事务 ID 自然对不上。排查方法很简单在 Wireshark 里过滤dns.id ! 0xabcd替换成你请求包里的事务 ID看有没有异常响应。在实际生产中我还遇到过 DNS 缓存服务器返回的响应里Question 区域变成 0 的情况。这种通常属于“非标准响应”某些开源缓存软件为了省流量会移除回显的问题区域。做报文解析器时必须兼容这种报文不能想当然地认为响应里一定有 Question。4.3 响应码 SERVFAIL 和 NXDOMAIN 怎么区分RCODE 字段是排查 DNS 问题的第一道线索。常见的取值有 0无错误、1格式错误、2服务器故障、3域名不存在、5服务器拒绝。很多人分不清 SERVFAIL2和 NXDOMAIN3我一般这样解释NXDOMAIN 是权威服务器明确告诉你“这个域名不存在别再问了”SERVFAIL 是 DNS 服务器自己也拿不到答案可能上游超时、权威服务器挂了或者 DNS 服务配置有误。抓包看到 SERVFAIL 时重点看响应的源头是谁。如果响应来自你的本地 DNS 服务器说明是它向上游查询失败如果响应直接来自权威服务器那要检查权威服务器自身的数据库或网络状态。有一次我排查一组域名间歇性无法解析抓包发现权威服务器返回 SERVFAIL 前先看到了大量 TCP 重传——原来是权威服务器和它后端数据库之间的网络出了问题导致查询处理不过来。4.4 响应超大导致客户端报错但抓包看上去没问题UDP 下 DNS 响应的理论最大长度是 65535但实际能传输多少取决于路径 MTU。如果响应报文太大又没有设置 DNSSEC 或 EDNS0 的缓冲区大小就可能触发 TC 位截断客户端收到 TC1 后会用 TCP 重新查询。如果客户端或者中间防火墙封了 TCP 53解析就会失败。排查时看响应包的 Flags 里 TC 位是否为 1同时观察响应包的 UDP length。如果 length 超过 1500 附近基本就是触发了分片或截断问题。解决方向要么扩大 EDNS0 的 UDP payload size常见设为 1232 或 4096要么确保 TCP 53 出方向放通。很多网络环境大面积配置完 DNSSEC 后出现解析超时最后查下来都是这个原因。5. 从报文分析到实用场景看完第 3 关的内容我建议你别急着关电脑趁热打铁做点延伸练习。我根据自己的经验把 DNS 报文分析能直接应用到的几个场景列一下这些场景里用到的分析思路跟头歌关卡是一脉相承的。5.1 本地 DNS 解析慢的排查思路当你觉得“打开网页慢、但 ping IP 正常”时可以抓 DNS 报文看耗时。方法是用 Wireshark 设置“显示时间列”然后看请求包和响应包的时间差。正常情况下局域网内 DNS 响应应该在 1 到 10 毫秒如果超过 50 毫秒甚至 100 毫秒就要怀疑本地 DNS 服务器性能不足、上游链路排队、或者响应报文过大导致重组耗时。我自己常用的命令是dig 127.0.0.1 www.example.com noall stats这个命令会输出查询耗时。如果耗时高再抓包看是不是每条查询都走了“本地缓存服务器 → 根提示 → 权威服务器”的递归全流程而缓存服务器没有做有效缓存。相同域名反复查还每次都触发完整递归那就是缓存策略配置有问题能和报文分析对上。5.2 发现并防御异常 DNS 响应从安全角度说DNS 报文分析能帮你发现两类异常一是响应里出现了你没请求过的类型或 IP二是 CNAME 链指向了可信域名之外的地址。比如你请求api.example.com响应里却先返回一条 CNAME 指向some-random-domain.xyz随后是some-random-domain.xyz的 A 记录这就非常可疑。防御层面我建议在 DNS 服务器上开启 DNSSEC 校验同时定期抓包做抽样审计。看是否有人故意构造大量不同类型的大响应给客户端因为历史上出现过的扫描手法就是通过大量 TXT 记录做数据外带或反射放大。报文分析在这里的作用是让你能第一时间发现“响应报文形状异常”并在自动化规则里识别“响应类型数量超过阈值”的流量。5.3 后渗透排查中的 DNS 通道识别如果你将来做服务器运维或者攻防演练大概率会接触 DNS 隧道检测。恶意程序有时会把数据切碎塞进 DNS 查询的 QNAME 前缀里比如abc123def456.evilserver.com。这种流量在抓包里看起来就是一串串毫无规律的子域名解析请求。判断指标很典型单次会话内 QNAME 长度远超正常、子域名层级多、每个查询间隔固定且频繁。遇到这种情况不能光靠手工看我会用 Zeek 或 Suricata 的 DNS 分析模块把 QNAME 长度、熵值、请求频率等字段做成统计表超过阈值就告警。第 3 关学的报文解构能力在这些工具的日志里其实都有体现——无非是工具把资源记录解析成字段了而已。6. 一个常见误区把“会抓包”当成“会分析”最后我想单独提一个问题也是我在带实习同学时反复纠正的很多人抓包特别熟练过滤条件用得很溜但让他不看 Wireshark 协议树直接解释一个响应包为什么有 3 条 A 记录、为什么 TTL 不一样、为什么有两条 CNAME他就说不清楚了。这其实就是前面基础没打好。报文分析的核心不是“打开抓包软件”而是“知道你在看什么”。我建议你每次做完头歌第 3 关的题都顺手做一次“不看协议树”练习把 Wireshark 里的字节面板截图然后自己在纸上或者编辑器里手动拆一遍写出每个字节对应的意义。一开始会非常慢拆一个包可能要十分钟但拆完三十个包以后基本就能在任何排障现场快速定位问题了。根据我个人的经验DNS 报文分析是最适合练手法的协议因为它结构相对简单、端口固定、明文字母多拆包的成就感也来得特别快。把这关吃透以后你再去看 TCP 三次握手、TLS 证书握手这些更复杂的协议会发现套路其实是相通的——无非都是“固定头部 变长字段 一堆状态标志位”。希望这篇内容能帮你把第 3 关的疑难点清掉也让你以后再看到c0 0c这种指针时能条件反射地笑起来。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询