简介:《Wireshark 数据包分析实战(第3版)》10.5.2节案例分析文档,围绕分支机构工作站访问总部应用服务器时产生的DNS解析故障展开。文档以抓包数据为线索,逐步分析DNS A记录查询、服务器故障响应、TCP SYN无回应等异常现象,并涉及工作站、分公司DNS服务器、总部应用服务器及中心办公室首选DNS等多个节点,最终定位到中心办公室路由器仅放行UDP 53端口、阻止TCP 53端口导致DNS区域传送失败这一配置错误。该案例完整呈现了从异常抓包到根因确认的排查过程,帮助网络运维、安全分析及协议学习者理解DNS、TCP/UDP的工作原理,掌握依据数据包特征反向定位故障的实操思路,同时厘清DNS常规使用UDP、区域传送等场景切换到TCP的协议细节。资源为1个PDF文件,大小644KB,内容精炼,便于碎片化查阅。目前已有327人学习下载,适合需要快速建立Wireshark实战分析能力的读者。
1. 引论:一次DNS大面积解析失败,暴露的不只是网络问题
分公司一个普通工作日早上,工位上的用户突然打不开总部应用系统。应用服务器IP拼得通吗?拼不通。服务器宕机了吗?没宕机,是你根本没能把它的域名解析成IP。真正让人头疼的是这种故障的排查路径:先在客户端抓包,看到第一个数据包是DNS请求,查的是应用服务器的A记录,响应却直接扔回来一个「服务器故障(SERVFAIL)」,连解析结果都没有——这行字几乎把所有初学者的排查方向都带偏了。
这套方案要解决的就是这类「看着像服务器挂了、实际死在DNS链路」的隐蔽故障。以《Wireshark 数据包分析实战(第 3 版)》中的一个真实场景为例,完整走一遍:客户端 172.16.16.101 访问总部应用服务器 172.16.16.200,中间隔着分公司DNS 172.16.16.251 与总部DNS 172.16.16.250,抓包定位出区域传送被路由器ACL拦截,最终恢复服务。适合正在做网络协议分析课程设计的人,也适合被DNS故障折腾过的运维,按这套方法可以直接照搬排查流程。
2. 抓包前期设计:镜像端口、过滤规则与pcap文件组织
2.1 先把嗅探器放对位置,再谈分析
很多人抓包翻车,不是不会用Wireshark,而是流量根本没走到抓包网卡上。这个案例里有一个关键动作:为了从分公司DNS服务器捕获合适流量,把嗅探器留在原地,只改变端口镜像设置,让DNS服务器的流量被镜像到嗅探器。这一步说明,抓包位置决定了你能不能在故障发生时拿到有效数据,而不是事后补抓。
通常的做法是我会先在交换机的上行口配置SPAN(端口镜像),把目标端口流量复制一份到接嗅探器的监听口。这里有个血泪经验:镜像口不要接成普通接入端口,否则会参与业务转发,抓包数据量一大,交换机CPU和镜像链路都容易被打满。正确姿势是配置一个专门的监听VLAN,只做流量收包,不转发业务报文。配置层面提供两个思路,一是直接在交换机上做SPAN,二是用TAP分光器物理分流,项目里要求不高的话用SPAN就够了。
# 交换机SPAN配置示意(不同厂商命令有差异,思路一致) Switch(config)# monitor session 1 source interface gi1/0/1 both Switch(config)# monitor session 1 destination interface gi1/0/24关键参数说明:source interface指定被镜像的端口(这里接分公司DNS服务器),both表示进出双向都复制;destination interface是嗅探器接入端口。配置完成后,用Wireshark在监听口上随便抓几秒流量,确认能看到DNS服务器的ARP和查询报文,再放长线抓故障流量。如果看不到,不是镜像方向配反了,就是源端口选择有误,这是抓包前必须验证的一步,别等故障复现了才发现数据没进来。
2.2 抓包与显示过滤器:别把所有流量都收进来
案例中提到捕获文件里「开头是我们之前看到的查询和响应,但还有一个额外的数据包」,说明这个场景下流量很干净,但这不代表抓包时不用做过滤。我还是建议在任何抓包之前把捕获过滤器设置好,减少无关注入,降低文件体积和后期分析负担。
这个项目里最合适的捕获过滤器是这样:
# 只抓与DNS服务器交互相关的流量 host 172.16.16.101 or host 172.16.16.251 or host 172.16.16.250 or host 172.16.16.200 # 也可以再加端口限定,比如: host 172.16.16.250 and (port 53 or port 80)这个过滤器背后的逻辑是:我们的目标是判断「工作站 → 分公司DNS → 总部DNS → 应用服务器」这条链路上哪个环节断了,所以只要关注这四个IP之间的交互即可。捕获过滤器是BPF语法,在Wireshark的Capture Options里设置,它的好处是数据包在进入软件之前就被丢弃,适合高流量环境;缺点是过滤条件太长容易误伤,实际项目里我一般用一条host限定就够,更细的过滤交给显示过滤器做。
显示过滤器则是事后分析神器。比如案例中判断DNS响应是否异常,用dns.flags.rcode == 1可以直接标出所有SERVFAIL的响应包;判断TCP连接是否建立,用tcp.flags.syn == 1 && tcp.flags.ack == 0找出所有SYN包。我在判读数据包时,通常先按IP分组,再按协议分类,最后用时间戳把两个文件(客户端侧和DNS服务器侧)对齐,这样谁先谁后、谁没回复,一眼就能看出来。
2.3 pcap文件的组织与命名:让复盘和交接不吵架
案例中两次捕获文件分别命名为默认文件(第一次)和stranded_branchdns.pcap(第二次),这个命名习惯值得学。第一次是工作站侧抓包,说明故障发生在「工作站与分公司DNS之间」或「分公司DNS再往上」;第二次抓包前只改了端口镜像,抓到的是分公司DNS的收发流量,文件命名直接点出「分支DNS」这个位置。
我一般做这种多段排查时,文件命名会带上三要素:位置、时间、方向。比如branchdns_client_query_1016.pcap、hqdns_server_syn_1016.pcap。这样一旦连续抓了七八个文件,整理报告时不至于对着文件名发愣。另外,抓包时提前在Wireshark里设置好环形缓冲(每个文件50MB,共10个文件),防止流量一大把磁盘写满,这个故障场景虽然只产生几个包,但生产环境上一旦涉及TCP重传,数据量会迅速膨胀,后悔药得提前备好。
3. 故障判读全流程:从DNS失败响应到SYN疑点
3.1 第1个包:A记录查询与「服务器故障」响应
打开第一次捕获文件,第一个数据包是工作站 172.16.16.101 发给 172.16.16.251 的DNS查询,查询类型是A记录,查询名称是应用服务器 172.16.16.200 对应的域名。这个包的特征很标准:客户端向本地DNS服务器发起递归查询,期望拿到目标域名对应的IPv4地址。到这里为止,一切正常。
问题出在响应包上。响应里没有返回A记录,而是直接标记为服务器故障(SERVFAIL,响应码1)。在DNS协议中,SERVFAIL通常表示服务器在递归查询过程中遇到上游故障或自身处理异常,属于临时性错误,和NXDOMAIN(域名不存在)完全是两回事。注意案例里强调「这个数据包只是一个错误,并没有响应查询结果」——这说明分公司DNS替客户端去上级查询时失败了,它自己也不知道这个域名该指向哪里。
用tshark可以直接把这个响应码打出来:
# 把DNS响应里rcode字段拿出来看 tshark -r branch_client_first.pcap -Y "dns.flags.response == 1" \ -T fields -e frame.number -e ip.src -e ip.dst -e dns.flags.rcode输出里第1个响应包如果rcode为1,就说明是SERVFAIL。这个字段在Wireshark的DNS协议树里显示为Response code: Server failure (1)。看到这个结果,基本上可以把排查范围从「应用服务器是否宕机」收窄到「DNS解析链路是否中断」。这也解释了用户为什么访问不了:工作站连域名都解析不出来,自然无法发起HTTP请求。
3.2 启动二段抓包:分公司DNS侧那一串奇怪的SYN包
为了确认分公司DNS到底出了什么问题,把嗅探器留在原地,只改端口镜像设置,让分公司DNS服务器的流量镜像过来,得到stranded_branchdns.pcap。打开后能看到开头依然是之前那对查询/响应,但多了第三个包:分公司DNS服务器(172.16.16.251)主动向总部首选DNS服务器(172.16.16.250)的53端口发出一个SYN包,协议是TCP,而不是常规的UDP。
很多人看到TCP 53会觉得奇怪——DNS不是用UDP吗?为什么会出现TCP连接?这里要回到DNS协议的机制:UDP是主用传输协议,适合单个小查询;但当响应数据超过512字节(扩展机制下可到4096),或者进行区域传送(zone transfer)时,必须改用TCP保证数据完整性和顺序性。区域传送就是把整个DNS区域文件从主服务器同步到从服务器,资源记录数量多、数据量大,只能用TCP。
这个SYN包就是区域传送请求的连接建立包:分公司DNS作为从属服务器,定期向总部主服务器请求同步区域数据。案例里明确指出,分公司DNS是总部DNS的从属服务器,而应用服务器的权威记录在总部DNS上,所以分公司必须从总部把资源记录同步过来,才能真正解析这个域名。SYN包发出后无人应答,说明TCP握手都建立不起来,区域传送彻底失败。
3.3 链路推演:从客户端到总部DNS的四段判定
把抓包数据按通信链路排一遍,这套故障的逻辑会非常清晰。客户端到分公司DNS这一段是通的,因为查询请求和SERVFAIL响应都回来了,说明客户端能到达本地DNS服务器,本地DNS也正常回了包。分公司DNS到总部DNS这一段是断的,TCP SYN发出去没人理,说明分公司试图向总部同步区域资源的路径已经阻塞。
链路推演到这里有两个可能断点:中间的路由器规则拦截,或总部DNS根本没有收到报文。案例里特别提了一句「我没有给出总部DNS服务器的流量捕获文件,因为根本就没有」,并指出SYN包从来没有到达服务器。这句话说明排查人员实际上嗅探了总部DNS流量,确认请求根本没进来,于是断点锁定在路由器。最后技术人员检查路由器配置,发现ACL只放行了端口53的UDP流量,而阻止了TCP流量,这就是区域传送失败的直接原因,也是最容易让人忽略的地方。
用Wireshark做链路定位时,我一般会在显示过滤器里这样逐步筛选:
# 只看客户端发往分公司DNS的查询 ip.src == 172.16.16.101 && ip.dst == 172.16.16.251 && dns # 只看分公司DNS发往总部DNS的TCP同步包 ip.src == 172.16.16.251 && ip.dst == 172.16.16.250 && tcp.flags.syn == 1 # 对比两段,看请求是否被中途丢弃 dns.qry.name contains "你的应用域名"每次过滤出来的包都要记录时间和seq号,这些是答辩验收时证明「我确实分析了数据包」的实锤证据。注意:TCP的SYN重传次数和时间间隔也值得看,比如第一次SYN发出后1秒、3秒、7秒的重传,能进一步确认是丢包而不是对端处理慢。
4. 排查陷阱与避坑:DNS区域传送故障最常见的翻车点
4.1 陷阱一:把DNS解析失败直接归因为应用服务器宕机
现象:用户在客户端ping应用服务器域名失败,于是结论写成「应用服务器不可用」,开始检查服务器进程和端口监听,折腾一两个小时一无所获。原因:混淆了「域名解析失败」和「IP不通」两个概念,根本没有看第一步DNS查询的结果。解决:任何应用访问故障的第一张抓包,先从DNS报文看起,响应码是SERVFAIL还是无响应、有没有返回A记录,这两个细节直接决定了排查方向,也是案例分析里第一个强调的判断点。
4.2 陷阱二:只过滤UDP 53流量,把TCP 53的SYN全滤掉了
现象:抓到了分公司DNS和总部DNS之间的流量,用udp.port == 53过滤后只看到常规查询,找不到任何异常,结论写成「网络正常」。原因:默认印象里DNS只用UDP,忽略了区域传送这种要跑TCP的场景。解决:过滤条件改成port 53而不加协议限定,把所有53端口的TCP和UDP包都拉出来看。这个案例里最关键的第三个包就是TCP SYN,单看UDP的话它就是隐形故障。血泪经验是,凡是涉及DNS的排查,都要同时看TCP 53,主从DNS结构尤其如此。
4.3 陷阱三:不区分递归DNS与权威DNS的职责边界
现象:分公司DNS报SERVFAIL,技术人员把矛头指向总部DNS「服务未启动」,反复重启服务,问题依旧。原因:没搞清楚递归查询和权威查询的分工。总部DNS是应用服务器域名的权威服务器,分公司DNS是从服务器,它必须主动向总部拉取区域数据才能应答本地客户端的查询。把从服务器和主服务器的依赖关系忽略掉,就会错误地在错误的位置找根因。解决:画一张拓扑图,标清楚谁是谁的上游,谁依赖谁同步数据,再决定每个节点的抓包位置。
4.4 陷阱四:只在客户端抓包,却试图判断服务器端行为
现象:在客户端抓了长时间流量,看到SYN重传但不知道服务器收没收到,只能猜是服务器忙。原因:单个位置的抓包只能证明「本机发出了什么、收到了什么」,无法覆盖网络上其他节点的行为。解决:遵循案例里「逐级镜像」的思路,先抓客户端侧,再抓DNS服务器侧,必要时在路由器两侧同时抓。确认SYN到底有没有越过路由器的ACL,这个断点判断必须在边界两侧各放一个嗅探点,否则你永远在猜黑匣子里发生了什么。
4.5 陷阱五:修改ACL后不做区域传送回归验证
现象:把路由器配置改成允许TCP 53后,客户端能解析域名了,故障宣告解决,但一个小时后区域数据同步失败告警再次出现。原因:只验证了客户端解析结果,没验证服务器间的区域传送是否成功。解决:修复后不只是ping通域名,还要在分公司DNS服务器上主动触发一次区域传送,或等一个更新周期后查看serial number是否和主服务器一致。验证命令也很简单,手动执行一次区域传送请求,看TCP 53流量是否正常交互、SOA记录的序列号是否递增,这步看起来多余,实际能挡掉一大半配置残留问题。
5. 验收与答辩:怎么证明你真正解决了故障
5.1 验收标准的设定
这套方案是否真正闭环,不要凭「用户说能打开网页了」来判断,要有明确的四层验收步骤。第一层是客户端验证:在工作站上用nslookup或dig查询应用服务器域名,必须返回172.16.16.200,响应码为NOERROR。第二层是链路验证:在分公司DNS服务器上发起到总部DNS的TCP 53连接,确认三次握手完成。第三层是区域传送验证:对比主从DNS服务器的SOA序列号,必须一致,也就是数据完成了同步。第四层是回归抓包:走一遍当时的抓包流程,确认原来的TCP SYN包能收到SYN-ACK响应,响应码从SERVFAIL变成正常解析结果,这一步在答辩时最有说服力。
# 手动触发一次区域传送并观察结果 dig @172.16.16.250 你的应用域名 axfr # 或者用nslookup验证客户端解析 nslookup 你的应用域名 172.16.16.2515.2 答辩演示清单
如果这是一份课程设计答辩或项目汇报,建议按时间线准备三张材料。第一张是抓包文件列表,标清楚每个文件抓自哪个位置、覆盖了哪段时间,与原始文件一一对应。第二张是故障分析链路图,从客户端DNS查询到SERVFAIL响应,再到分公司DNS的TCP SYN,每一步都配上包序号和过滤时的显示过滤器表达式,说明你是如何排除干扰项、逐步逼近路由器ACL这一根因的。第三张是修复前后对比表,修前看到SERVFAIL与SYN超时,修后看到NOERROR与TCP握手完成。这三张材料拿出来,答辩老师或主管就基本不会再追问「你参与了多少」这类问题,因为每一步都有数据支撑。
5.3 一个答辩技巧
汇报时不要把结论前置,而是顺着排查顺序讲:先讲发现SERVFAIL,再讲排除应用服务器故障,然后讲看到TCP 53 SYN的疑惑,接着讲区域传送机制,最后讲路由器配置确认。这个「还原现场」的过程本身就是技术含量所在,比直接给结论更能体现你掌握了DNS协议和抓包分析能力。从那以后我每次做协议类故障排查,都强制自己把每一个决策点对应到具体的包、时间戳和过滤器,养成这个习惯之后,写报告和答辩都轻松很多,希望帮到你。
本文还有配套的精品资源,点击获取