前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一次完整的 DNS 访问故障分析实录

一次完整的 DNS 访问故障分析实录

作者头像
挖坑的张师傅
发布2024-06-19 20:24:49
570
发布2024-06-19 20:24:49
举报
文章被收录于专栏:张师傅的博客

最近我们边缘集群服务遇到了一个 DNS 访问故障问题,现象是在边缘服务器上无法访问 DNS 服务器(10.7.0.1), 发出去的 DNS 请求包没有收到任何回应。

由于这是第一次遇到这种问题,因此我记录了详细的故障排查过程,让我们一起来看看是如何一步步逼近真相,找到问题根源的。

首先简单介绍一下我们的部署架构,这个 DNS 服务器(10.7.0.1)主要用来为我们的存储节点提供负载均衡服务。我们有 4 台存储服务器, 总容量达 2PB。边缘计算服务器会根据 DNS 服务器返回的 IP 地址挂载对应的存储服务器。

arp-dns

初步排查

经过初步的排查,我们发现:

  • 从边缘服务器 ping 10.7.0.1 是通的
  • 访问 10.7.0.1 的 80 端口也没问题
  • 但是访问 53 端口(DNS)时, 请求一直没有响应。

起初我们怀疑是 DNS 服务本身出了问题。但检查发现 10.7.0.1 上 53 端口处于正常监听状态:

本机执行 DNS 查询也一切正常。这样就可以排除 DNS 服务异常的可能性了。

接下来我们分析是否 10.7.0.1 的防火墙限制了 53 端口的访问。但经过仔细检查 iptables 规则后, 我们同样没有发现异常。

这就有点奇怪了,防火墙没有拦截,DNS 服务也正常,但请求却没有响应。接下来想到要抓包分析一下。

然而这台 DNS 服务器无法访问外网,没有办法通过简单的 apt-get 包管理器安装 tcpdump,这也不是啥大问题,我们可以在其他机器上编译一个静态链接的 tcpdump, 然后拷贝过来使用。

静态编译的 tcpdump

由于 DNS 服务器是 arm64 架构, 静态编译 tcpdump 花了我一点时间。我们可以选择

  • 在 x86-64 机器上交叉编译一个 arm64 版本
  • 找一台 arm64 架构的机器直接编译
  • 搞一个容器来编译

幸运的是公司内网有 arm64 的机器可以使用,我直接登录上去进行编译。首先从 tcpdump 的官网下载对应的源码,然后执行以下命令完成静态编译:

代码语言:javascript
复制
cd libpcap-1.10.4
CFLAGS=-static ./configure  --with-pcap=linux
make

cd tcpdump-4.99.4
CFLAGS=-static ./configure --without-crypto 
make

最终我们得到了一个静态链接的 tcpdump 可执行文件:

代码语言:javascript
复制
$ file tcpdump
tcpdump: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=e1cbb8879d17fd80aa0153da4e4e42ffe4593d96, for GNU/Linux 3.7.0, not stripped

此时运行 tcpdump 就可以执行抓包了。

将这个文件拷贝到 DNS 服务器上, 就可以执行抓包了。

抓包分析

我们在 DNS 服务器(10.7.0.1)上运行 tcpdump 抓包, 然后从边缘业务服务器(10.7.0.46)向其发送 ping 和 DNS 请求。

代码语言:javascript
复制
tcpdump -i any host 10.7.0.46 -nn

但令人意外的是, tcpdump 抓不到任何来自 10.7.0.46 的网络包,这说明请求压根就没有到达 DNS 服务器。

arp-dns1

问题根源:ARP 记录居然是错误的

为了再次确认, 我们回到业务服务器(10.7.0.46)上, 查看它的 ARP 表:

代码语言:javascript
复制
ip n

发现业务机上 10.7.0.1 对应的 mac 地址居然是错误的,而且状态还是 REACHABLE ,这意味着 10.7.0.46 确实是与局域网中的某一台 10.7.0.1 的主机在通信。

正确的 mac 地址是 bc:99:30:89:e0:f0

为了验证我们的判断,先在业务机(10.7.0.46)上删除错误的 ARP 表项,然后增加一条静态 permanent 的 arp 表项,指向正确的 MAC 地址:

代码语言:javascript
复制
ip n del 10.7.0.1 dev eth0

ip n add 10.7.0.1 lladdr bc:99:30:89:e0:f0 dev eth0 nud permanent

修改后再次从 10.7.0.46 访问 DNS 服务, 一切恢复正常:

所有与 10.7.0.46 的通信都恢复正常了,tcpdump 的抓包结果如下:

至此问题已经解决,但我们还是想找出 IP 冲突的元凶, 避免类似问题再次发生。

社会工程学找到「凶手」

通过之前 ARP 记录的 REACHABLE 状态,可以判断 IP 冲突的主机目前仍在线。

我们尝试扫描了这个 IP 的常用端口, 发现 22 和 80 端口是开放的, 但仍无法判断具体是什么服务。

这时我无意中翻到存储服务器的监控看板上的一个告警, 提示在「2024-05-09 18:32」发现 10.7.0.1 IP 冲突。

这个时候开始社会工程,让老铁们帮忙回忆这个时间点启动了什么服务,或者做了什么变更。

然后真的有铁子回忆到这个时间点启动了一台运行 jumpserver 的虚拟机:

在「嫌疑人」的配合下, 我们确认了这台虚拟机的 IP 的确错误地配置成了 10.7.0.1, 导致了 IP 冲突。

最后, 我们下线了这台虚拟机, 彻底修复了故障,至此破案。

小结

这次故障排查过程还是比较顺利的, 虽然中间编译 tcpdump 工具花了点时间。整个过程是逐步排除各种不可能的选项, 最终锁定问题根源的。期间用到的一些小技巧包括:

  • 编译静态链接的 tcpdump 方便在受限环境排查
  • 留意 ARP 表中记录的状态
  • 适当运用「社会工程学」, 发动集体回忆

希望通过分享这个案例, 能给你一些故障排查思路上的启发。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 张师傅的博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初步排查
  • 静态编译的 tcpdump
  • 抓包分析
  • 问题根源:ARP 记录居然是错误的
  • 社会工程学找到「凶手」
  • 小结
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档