为什么dig比nslookup更强
很多人在排查DNS(域名系统,负责把域名解析成IP地址)问题时,第一反应就是敲 nslookup。这很正常,nslookup确实能用,而且几乎所有Linux发行版都预装了它。但说实话,当你真正遇到棘手的DNS问题,比如怀疑DNS缓存污染、想追踪递归解析全过程、或者需要批量验证上百个域名的解析结果时,nslookup就有点力不从心了。
dig(Domain Information Groper)的全名看起来挺萌,但它是个非常专业的DNS诊断工具。它的输出结构清晰、信息完整,而且支持几乎所有DNS记录类型的查询。更关键的是,dig直接发送标准的DNS查询请求,几乎不受本地系统解析器缓存的影响,这对排障来说至关重要。
我第一次从nslookup切换到dig时,最大的感受就是"以前查不到的东西现在能看到了"。比如DNS响应中的TTL(生存时间,告诉客户端这个记录可以缓存多久)、权威回答标志位(aa标记),这些在nslookup默认输出里基本看不到,但在dig的输出里一目了然。
dig的基本查询用法
最简单的用法就是直接查一个域名的A记录(IPv4地址记录)。
# 查询 example.com 的A记录(IPv4地址)
dig example.com
这条命令返回的内容很多,我们来拆开看。输出分为几个部分:
第一段是"应答头部",里面有个 status: NOERROR,表示查询成功。如果显示 NXDOMAIN,说明这个域名根本不存在。看到 SERVFAIL 通常说明DNS服务器那边出了问题。
第二段是"问题部分"(QUESTION SECTION),显示你查了什么。
第三段是"答案部分"(ANSWER SECTION),这里面就是我们要的解析结果。注意看每条记录旁边的数字,那是TTL值,单位是秒。比如 300 表示这个结果可以在缓存里存5分钟。
第四段是"权威部分"(AUTHORITY SECTION)和"附加部分"(ADDITIONAL SECTION),显示了谁是这个域名的权威DNS服务器。
如果你只想看"答案部分"的核心结果,不想看那么多头信息,可以用 +short 参数。
# 简洁模式,只输出解析结果
dig example.com +short
这个输出就很干净了,直接就是IP地址。不过我个人建议排障的时候先看完整输出,确认头部状态和权威部分都没有异常,再看简洁结果。直接跳 +short 可能会漏掉关键线索。
查询特定的DNS记录类型
DNS不止有A记录,常见的记录类型包括:
- ·A记录:域名到IPv4地址的映射
- ·AAAA记录:域名到IPv6地址的映射
- ·MX记录:邮件交换记录,指定收邮件的服务器
- ·CNAME记录:别名记录,一个域名指向另一个域名
- ·TXT记录:文本记录,常用于SPF(发件人策略框架)和DKIM(域名密钥识别邮件)验证
- ·NS记录:域名服务器记录,指定谁负责解析这个域
查询MX记录的写法如下:
# 查询 example.com 的MX记录(邮件服务器)
dig example.com MX
同理,查TXT记录:
# 查询 example.com 的TXT记录,通常用于邮件认证
dig example.com TXT
查CNAME别名记录:
# 查询 www.example.com 的CNAME记录
dig www.example.com CNAME
我工作中最常用的是MX和TXT记录。有一次客户说邮件发不出去,我一查MX记录,发现对方域名的MX指向了一个已经废弃的邮件服务器IP,邮件自然就丢了。这条记录在DNS管理后台改掉之后,问题立刻解决。
指定DNS服务器查询
默认情况下dig会使用 /etc/resolv.conf 里配置的DNS服务器。但有时候我们需要绕过本地DNS,直接去查询特定的DNS服务器,比如公共DNS(域名系统开放解析服务,如 8.8.8.8 和 1.1.1.1)或者域名的权威DNS。
# 使用Google公共DNS服务器做查询
dig @8.8.8.8 example.com
# 使用Cloudflare DNS服务器
dig @1.1.1.1 example.com
# 直接查询域名的权威DNS服务器
dig @ns1.example.com example.com
@符号后面跟DNS服务器的IP地址,这个参数在排障时非常有用。比如你发现某个域名在自己机器上解析出来的IP和别人机器上不一样,那可能就是本地DNS缓存的问题。分别用 @8.8.8.8 和 @114.114.114.114 查一次,对比结果,就能知道问题出在哪一方。
还有一种场景是DNS劫持判断。在某些网络环境下,运营商可能会劫持DNS请求返回广告页面。你用 dig @8.8.8.8 查到的结果和用系统默认DNS查到的结果不一样,那就八九不离十了。
dig +trace追踪完整解析链路
这是dig我最喜欢的功能之一,也是nslookup完全做不到的。
当你执行 dig +trace 时,dig会模拟DNS递归解析的完整过程:从根DNS服务器(Root DNS)开始,依次查询顶级域服务器(如 .com 的TLD服务器),最后到达域名的权威DNS服务器,一步步展示整个链路。
# 从根服务器开始,追踪完整的DNS解析链路
dig +trace example.com
输出会像这样分段展示:
1. 首先显示根服务器返回的列表(. 对应的NS记录)
2. 然后显示 .com 顶级域服务器列表
3. 最后显示 example.com 的权威服务器返回的结果
每一跳都会显示查询用时。这个功能在诊断"DNS解析慢"的问题时特别好用。如果某一步耗时异常高,你就知道瓶颈在哪里了。
举个例子,我曾经帮一个朋友排查网站加载慢的问题。网站本身响应很快,但首屏加载要等好几秒。用 dig +trace 一查,发现某个中间DNS服务器响应时间超过2秒,换了DNS提供商后问题就消失了。
反向解析(PTR记录查询)
反向解析就是通过IP地址查域名,这在排查邮件服务器问题时非常常见。很多邮件服务器会检查发件IP是否有反向解析记录,没有的话邮件可能被拒收。
# 反向解析IP地址,查对应的域名
dig -x 8.8.8.8
# 也可以用 PTR 记录方式查询
dig 8.8.8.8.in-addr.arpa PTR
-x 参数会自动帮你把IP地址转换成反向解析格式(in-addr.arpa 域)。结果中的PTR记录(指针记录)就是该IP对应的域名。
邮件服务器的反向解析配置一直是个容易忽略的坑。有个朋友搭建了邮件服务器,发出去的邮件总进垃圾箱。我一查发现他的服务器IP没有PTR记录,联系云服务商配置了PTR之后,邮件投递率明显提升。
批量查询多个域名
运维工作中经常需要同时验证多个域名的DNS解析结果。写脚本循环调用dig就可以了。
# 批量查询多个域名的A记录
for domain in example.com google.com github.com; do
echo "===== $domain ====="
dig $domain +short
done
你也可以把域名列表放在一个文件里,每行一个:
# 从文件读取域名列表批量查询
for domain in $(cat domain-list.txt); do
echo "查询: $domain"
result=$(dig $domain A +short)
if [ -z "$result" ]; then
echo " -> 查询失败或无记录"
else
echo " -> $result"
fi
done
这种批量查询在DNS迁移的时候特别有用。比如你要把一批域名的DNS服务器从一个提供商切换到另一个,迁移完成后可以用脚本批量验证解析是否已经生效。
dig的其他实用选项
下面这些参数虽然不是必须每天用,但关键时刻能救命。
# 只显示应答部分,去掉额外信息
dig example.com +noall +answer
# 控制每次查询的超时时间(默认5秒)
dig +time=3 example.com
# 只查询特定DNS服务器的返回,不做递归
dig +norecurse @ns1.example.com example.com
+norecurse 这个参数可能比较冷门,它的作用是告诉DNS服务器"不要帮我递归查询,如果你本地没有缓存就返回空"。这可以用来检查某个DNS服务器上的缓存状态。
安全提醒
使用dig一般不会对系统造成破坏,但以下几点还是要注意:
第一,不要在公网环境下对第三方DNS服务器发送大量并发查询。虽然dig本身不恶意,但高频查询可能被对方视为DNS放大攻击的一部分,导致你的IP被封。
第二,在排查DNS问题时,不要轻易修改 /etc/resolv.conf 文件。如果改错了,整个系统的DNS解析都会失效,连 apt update 都跑不了。改之前先备份:
# 备份当前的DNS配置文件,防止改错后无法恢复
sudo cp /etc/resolv.conf /etc/resolv.conf.bak
第三,如果你在编写脚本中使用dig,注意处理超时和异常情况。DNS查询偶尔会超时,脚本应该设置合理的重试机制,而不是直接报错退出。
总结
dig是一个DNS排查的利器,日常使用频率可能不如 ping 或 curl 那么高,但一旦遇到域名解析相关的问题,它就是最有用的诊断工具。从最简单的A记录查询,到复杂的链路追踪,dig都能胜任。
从nslookup迁移到dig可能需要适应几天,但一旦习惯了dig的输出格式和灵活的参数组合,你会感谢自己做的这个切换。
相关阅读
- ·
man dig:官方手册,参数说明最全 - ·
man resolv.conf:了解系统DNS解析器配置 - ·
/etc/hosts 文件:本地主机名映射,优先级高于DNS