LabHub
学习 学习路径 课程

Linux 网络诊断

名字解析诊断

在 LabHub 中继续学习

目标

确认名称解析会经过怎样的路径,并亲手制造‘dig 正常但应用程序失败’的情况。

为什么重要

应用程序调用 glibc 的 getaddrinfo(),glibc 则按照 /etc/nsswitch.confhosts: 行的顺序进行查询(通常是 files dns,即先查 /etc/hosts)。而 dig 会绕过这一切,直接询问 /etc/resolv.conf 中的名称服务器。**如果两个工具的答案不同,问题就不在 DNS 服务器,而在存根解析器这一段。**仅仅理解这一点,就能把‘dig 明明能用,为什么应用程序不行’的排查时间从几小时缩短到几分钟。

步骤

/root/dns 目录中工作。

  1. /etc/resolv.conf第一个 nameserver 的地址写入 /root/dns/nameserver.txt
  2. /etc/hosts 中把 10.99.0.10 同时注册为 app.labhub.local 和短名称 app
  3. /etc/nsswitch.confhosts: 项的值(冒号后的全部内容)写入 /root/dns/order.txt。文件不存在时写入 unavailable
  4. 对同一个名称 app.labhub.local,分别用 getentdig +short 查询,把结果按以下两行写入 /root/dns/compare.txt。如果 dig 没有任何答案,就写 none
    • getent=<결과>
    • dig=<결과 또는 none>
  5. /etc/resolv.conf 中的搜索域列表以空格分隔写入 /root/dns/search.txt。不存在时写入 none
  6. 10.99.0.10 进行反向查询,把结果名称写入 /root/dns/reverse.txt
  7. /etc/hosts 中用两行注册 api.labhub.local先写 10.99.0.21,再写 10.99.0.22。然后把 getent hosts api.labhub.local 实际返回的 IP 写入 /root/dns/first.txt
  8. 创建 /root/dns/resolve.sh <이름>。解析成功时输出以下两行并返回退出码 0;失败时报告 unresolved 并返回退出码 3。没有参数时必须返回非 0。
    • name=<이름>
    • ip=<주소>

提示

查看解析器地址

/etc/resolv.conf第一个 nameserver 的地址写入 /root/dns/nameserver.txt

查看 /etc/resolv.conf 中的 nameserver 行。如果有多个,只写第一个。

在 hosts 文件中注册名称

/etc/hosts 中把 10.99.0.10 同时注册为 app.labhub.local 和短名称 app

在同一行的 IP 后写多个名称,它们都会成为别名。请用 getent 确认。

查看名称服务顺序

/etc/nsswitch.confhosts: 项的值(冒号后的全部内容)写入 /root/dns/order.txt。文件不存在时写入 unavailable

查看 /etc/nsswitch.conf 中的 hosts: 行。只写冒号后的值。

比较 getent 与 dig

对同一个名称 app.labhub.local,分别用 getentdig +short 查询,把结果按以下两行写入 /root/dns/compare.txt。如果 dig 没有任何答案,就写 none

使用两个工具查询同一个名称,思考结果为何不同。如果 dig 没有得到任何答案,就写 none。

查看搜索域

/etc/resolv.conf 中的搜索域列表以空格分隔写入 /root/dns/search.txt。不存在时写入 none

查看 resolv.conf 中的 search 行。不存在时写 none。

反向查询

10.99.0.10 进行反向查询,把结果名称写入 /root/dns/reverse.txt

向 getent hosts 传入 IP,就会执行反向查询。

同名两行,哪一行生效

/etc/hosts 中用两行注册 api.labhub.local先写 10.99.0.21,再写 10.99.0.22。然后把 getent hosts api.labhub.local 实际返回的 IP 写入 /root/dns/first.txt

顺序会改变结果。请先写 21。

创建名称解析辅助脚本

创建 /root/dns/resolve.sh <이름>。解析成功时输出以下两行并返回退出码 0;失败时报告 unresolved 并返回退出码 3。没有参数时必须返回非 0。

成功时输出名称和 IP 并返回 0,失败时输出 unresolved 并返回退出码 3。