名字解析诊断
目标
确认名称解析会经过怎样的路径,并亲手制造‘dig 正常但应用程序失败’的情况。
为什么重要
应用程序调用 glibc 的 getaddrinfo(),glibc 则按照 /etc/nsswitch.conf 中 hosts: 行的顺序进行查询(通常是 files dns,即先查 /etc/hosts)。而 dig 会绕过这一切,直接询问 /etc/resolv.conf 中的名称服务器。**如果两个工具的答案不同,问题就不在 DNS 服务器,而在存根解析器这一段。**仅仅理解这一点,就能把‘dig 明明能用,为什么应用程序不行’的排查时间从几小时缩短到几分钟。
步骤
在 /root/dns 目录中工作。
- 将
/etc/resolv.conf中第一个 nameserver 的地址写入/root/dns/nameserver.txt。 - 在
/etc/hosts中把10.99.0.10同时注册为app.labhub.local和短名称app。 - 将
/etc/nsswitch.conf中hosts:项的值(冒号后的全部内容)写入/root/dns/order.txt。文件不存在时写入unavailable。 - 对同一个名称
app.labhub.local,分别用getent和dig +short查询,把结果按以下两行写入/root/dns/compare.txt。如果 dig 没有任何答案,就写none。getent=<결과>dig=<결과 또는 none>
- 将
/etc/resolv.conf中的搜索域列表以空格分隔写入/root/dns/search.txt。不存在时写入none。 - 对
10.99.0.10进行反向查询,把结果名称写入/root/dns/reverse.txt。 - 在
/etc/hosts中用两行注册api.labhub.local。先写10.99.0.21,再写10.99.0.22。然后把getent hosts api.labhub.local实际返回的 IP 写入/root/dns/first.txt。 - 创建
/root/dns/resolve.sh <이름>。解析成功时输出以下两行并返回退出码 0;失败时报告unresolved并返回退出码 3。没有参数时必须返回非 0。name=<이름>ip=<주소>
提示
getent hosts 이름按IP 정식이름 별칭...格式输出。- 使用
dig +short +time=2 +tries=1 이름可以进行简短查询。 - 常见错误 1:第 4 步 dig 结果为空时,不要判定实验失败。只存在于 hosts 中的名称不被 DNS 知道是正常的。
- 常见错误 2:第 7 步交换两行顺序会改变结果。先写的行获胜。
查看解析器地址
将 /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.conf 中 hosts: 项的值(冒号后的全部内容)写入 /root/dns/order.txt。文件不存在时写入 unavailable。
查看 /etc/nsswitch.conf 中的 hosts: 行。只写冒号后的值。
比较 getent 与 dig
对同一个名称 app.labhub.local,分别用 getent 和 dig +short 查询,把结果按以下两行写入 /root/dns/compare.txt。如果 dig 没有任何答案,就写 none。
getent=<결과>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。
name=<이름>ip=<주소>
成功时输出名称和 IP 并返回 0,失败时输出 unresolved 并返回退出码 3。