linux下dig命令实现dns查询的方法汇总

发布时间:2020-01-07编辑:脚本学堂
有关linux dig命令的用法,在linux系统中用dig命令进行dns查询,Dig可以有效地查询DNS,最常用的查询是A记录,TXT(文本注释),MX记录,NS记录等。

Dig是一个在类Unix命令行模式下查询DNS包括NS记录,A记录,MX记录等相关信息的工具。
Dig的源码是ISC BIND大包的一部分,但是大多编译和安装Bind的文档都不把它包括在内,但是在linux系统下,它通常是某个包的一部分,在Gentos下是bind-tools,在redhat/Fedora下是 bind-utils,或者在Debian下是 dnsutils。

dig命令可以查询什么?

Dig可以有效地查询DNS,最常用的查询是A记录,TXT(文本注释),MX记录,NS记录,或者任意综合查询。

1. 不加参数直接查,会比使用host命令返回的信息要多
 

复制代码 代码示例:

[admin@server190 ~]$ dig www.jb200.com

; <<>> DiG 9.7.3-P3-RedHat-9.7.3-8.P3.el6_2.1 <<>> www.jb200.com

;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34810
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;www.jb200.com. IN A
;; ANSWER SECTION:
www.jb200.com. 17852 IN A 222.92.117.33
;; Query time: 143 msec
;; SERVER: 8.8.4.4#53(8.8.4.4)
;; WHEN: Wed May  8 23:46:30 2013
;; MSG SIZE  rcvd: 47

[admin@server190 ~]$ host www.jb200.com
www.jb200.com has address 222.92.117.33

2、加参数trace使用追踪整个dns解析过程
 

复制代码 代码示例:
[admin@server190 ~]$ dig +trace www.jb200.com
; <<>> DiG 9.7.3-P3-RedHat-9.7.3-8.P3.el6_2.1 <<>> +trace www.jb200.com
;; global options: +cmd
. 7607 IN NS a.root-servers.net.
. 7607 IN NS b.root-servers.net.
. 7607 IN NS c.root-servers.net.
. 7607 IN NS d.root-servers.net.
. 7607 IN NS e.root-servers.net.
. 7607 IN NS f.root-servers.net.
. 7607 IN NS g.root-servers.net.
. 7607 IN NS h.root-servers.net.
. 7607 IN NS i.root-servers.net.
. 7607 IN NS j.root-servers.net.
. 7607 IN NS k.root-servers.net.
. 7607 IN NS l.root-servers.net.
. 7607 IN NS m.root-servers.net.
;; Received 228 bytes from 8.8.4.4#53(8.8.4.4) in 135 ms
com. 172800 IN NS h.gtld-servers.net.
com. 172800 IN NS j.gtld-servers.net.
com. 172800 IN NS g.gtld-servers.net.
com. 172800 IN NS l.gtld-servers.net.
com. 172800 IN NS m.gtld-servers.net.
com. 172800 IN NS k.gtld-servers.net.
com. 172800 IN NS d.gtld-servers.net.
com. 172800 IN NS e.gtld-servers.net.
com. 172800 IN NS c.gtld-servers.net.
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
com. 172800 IN NS i.gtld-servers.net.
com. 172800 IN NS f.gtld-servers.net.
;; Received 503 bytes from 192.36.148.17#53(i.root-servers.net) in 10194 ms
jb200.com. 172800 IN NS dns1.iidns.com.
jb200.com. 172800 IN NS dns2.iidns.com.
jb200.com. 172800 IN NS dns3.iidns.com.
jb200.com. 172800 IN NS dns5.iidns.com.
jb200.com. 172800 IN NS dns4.iidns.com.
jb200.com. 172800 IN NS dns6.iidns.com.
;; Received 247 bytes from 192.42.93.30#53(g.gtld-servers.net) in 10209 ms
www.jb200.com. 36000 IN A 222.92.117.33
;; Received 47 bytes from 113.105.148.222#53(dns1.iidns.com) in 10174 ms

3、查找yahoo.com的A记录:(此处一定是域而不是主机,如yahoo.com)
 

dig yahoo.com A +noall +answer

查找yahoo.com MX记录的列表:
 

dig yahoo.com MX +noall +answer

查找yahoo.com的权威DNS:
 

dig yahoo.com NS +noall +answer

查询上面所有的记录:
 

dig yahoo.com ANY +noall +answer

在现在这种IPv4和IPV6混用的情况下,你也可以使用AAAA的选项查询主机的IPv6 AAAA记录:
 

dig www.isc.org AAAA +short


如果你要查询的域允许转发,你也可以查询到相关的信息,比如DNS记录在internet上的生存周期,但是,现
在只有很少的DNS允许无限制转发。

怎样查询?获得精简答案?
当需要一个快速回答时,+short选项:
 

[admin@server190 ~]$ dig www.jb200.com +short
222.92.117.33

获得一个不是十分精简的答案?
精简答案和只有一个答案是不一样的,获得没有附加信息的详细答案的方法是使用+noall选项,这样就只保留你想要的输出。
下面是只有一个答案的精简查询,最后包含所有的配置信息,包括TTL数据,格式化的BIND配置信息。
 

$ dig fsf.org mx +short
20 mx20.gnu.org.
30 mx30.gnu.org.
10 mx10.gnu.org.
$ dig +nocmd fsf.org mx +noall +answer
fsf.org.                3583    IN      MX      30 mx30.gnu.org.
fsf.org.                3583    IN      MX      10 mx10.gnu.org.
fsf.org.                3583    IN      MX      20 mx20.gnu.org.

获得一个详细答案?
通过它的man page,你可以通过+multiline选项获得冗长的多行模式人性化注释的DSN的SOA记录,一般来说,
用+multiline选项获得的信息可以显示很多,就像BIND配置文件一样。
 

$ dig +nocmd ogi.edu any +multiline +noall +answer
ogi.edu.   14267 IN A 129.95.59.31
ogi.edu.   14267 IN MX 5 cse.ogi.edu.
ogi.edu.   14267 IN MX 15 hermes.admin.ogi.edu.
ogi.edu.   14267 IN SOA zeal.admin.ogi.edu. hostmaster.admin.ogi.edu. (
                   200408230  ; serial
                   14400      ; refresh (4 hours)
                   900        ; retry (15 minutes)
                   3600000    ; expire (5 weeks 6 days 16 hours)
                   14400      ; minimum (4 hours)
                   )
ogi.edu.   14267 IN NS zeal.admin.ogi.edu.
ogi.edu.   14267 IN NS cse.ogi.edu.
ogi.edu.   14267 IN NS fork.admin.ogi.edu.

查找PTR记录?
可以用 -x的选项查找IP地址的主机名。
 

$ dig -x 204.152.184.167 +short
mx-1.isc.org.
 

在这个循环中,脚本很灵活地在给出的子网中映射出名字。
 

#!/bin/bash
NET=18.7.22
for n in $(seq 1 254); do
  ADDR=${NET}.${n}
  echo -e "${ADDR}t$(dig -x ${ADDR} +short)"
done

查询一个不同的命名服务器
查询命令:
 

dig @ns1.google.com www.google.com
 

使用/etc/resolv.conf里面的记录查询
主机将从/etc/resolv.conf文件里面自动查询DNS记录
 

$ host www
www.madboa.com has address 65.102.49.170
 

但是,默认情况下,dig会产生出一些意想不到的输出。如果你想查询本地主机名而不是全域名时候,使用+search 选项
 

dig www +search

处理大部分的查询?
如果你想查询大量的主机名,你可以把它们存放在一个文本文件中(一条记录一行),使用带-f参数的dig来依
次查询。
 

# 查询大量的主机名
dig -f /path/to/host-list.txt
# 相同的,更明确的输出
dig -f /path/to/host-list.txt +noall +answer
 

但是我要告诉你的是,dig 9.2.3以及以后的版本都不支持使用-f的选项反向查询了。
验证DNS映射
不正确的DNS配置会给你带来很多苦恼,你可以通过如下两种方式验证你的DNS配置:
1.每个主机名应该被解析到一个IP地址,而且那个IP地址也应该反指向那个主机名。
2.如果你子网上一个地址被反指向一个主机名,那么那个主机名也必须指向这个IP。
对于这两条规则来说,还有一些例外情况,比如CNAME应该首先解析到另外一个主机名,而且只能指向一个IP,有时多个主机名指向了相同的IP地址,但是那个IP只能有一个PTR记录。
综上,这些有助于你检查你的DNS映射是否像你想象的那样工作。
你也可以编写一个测试脚本写入你已知的主机名,如下所示,内容很简单;它执行时当捕捉到一个CNAME时它就会中断,如果多个主机名指向同一个IP地址它会报错。我们假设这个文件包含你的主机名叫做named-hosts。
 

复制代码 代码示例:
#!/bin/bash
#
# test DNS forward- and reverse-mapping
#
# edit this variable to reflect local class C subnet(s)
NETS="192.168.1 192.168.2"
# Test name to address to name validity
echo
echo -e "tname -> address -> name"
echo '----------------------------------'
while read H; do
  ADDR=$(dig $H +short)
  if test -n "$ADDR"; then
    HOST=$(dig -x $ADDR +short)
    if test "$H" = "$HOST"; then
      echo -e "okt$H -> $ADDR -> $HOST"
    elif test -n "$HOST"; then
      echo -e "failt$H -> $ADDR -> $HOST"
    else
      echo -e "failt$H -> $ADDR -> [unassigned]"
    fi
  else
    echo -e "failt$H -> [unassigned]"
  fi
done < named-hosts
# Test address to name to address validity
echo
echo -e "taddress -> name -> address"
echo '-------------------------------------'
for NET in $NETS; do
  for n in $(seq 1 254); do
    A=${NET}.${n}
    HOST=$(dig -x $A +short)
    if test -n "$HOST"; then
      ADDR=$(dig $HOST +short)
      if test "$A" = "$ADDR"; then
        echo -e "okt$A -> $HOST -> $ADDR"
      elif test -n "$ADDR"; then
        echo -e "failt$A -> $HOST -> $ADDR"
      else
        echo -e "failt$A -> $HOST -> [unassigned]"
      fi
    fi
  done
done

有趣的dig
创建属于你自己的named.root文件
任何连接到internet 的DNS服务器肯定会有InterNIC的named.root文件的拷贝,文件列出所有internet的根
DNS,如果你不怕麻烦的话,你可以经常从InterNIC的ftp服务器上把它下载下来,或者,你可以使用dig命令
创建属于你自己的时髦的named.root
 

# compare with ftp://ftp.internic.net/domain/named.root
dig +nocmd . NS +noall +answer +additional
 

你的TTL值在这边可能会很小,但是它是你找到最新的named.root文件!

跟踪dig的查询路径
你可能是个traceroute的狂热爱好者,经常喜欢查看如何从点A连接点B。那你可以使用dig +trace选项做类似
的事。
 

dig gentoo.de +trace
 

你可以在dig输出的头部分看到根DNS,然后找到负责解析所有*.de的DNS,最后找到gentoo.de的域名IP。

获取SOA记录
作为一个DNS管理员,我有时会(对DNS配置)做一些改变,并且想知道我的DNS解析是否推送的还是旧数据,
这个+nssearch选项可以给你的公众服务器提供清楚的统计信息。
 

# the unvarnished truth
dig cse.ogi.edu +nssearch
# the same, displaying only serial number and hostname
dig cse.ogi.edu +nssearch | cut -d' ' -f4,11

解释TTL数值
我喜爱google有很多原因,其中一个原因就是它在我的WEB日志中提供了精确的链接,它会使我很容易地指出哪种类型的查询引导人们来访问这个站点的页面。
出乎意料的是,我已经看到很多请求要求查询TTL数值,我从来没想到TTL会成为最受欢迎的东东,但是你每天都在学习新东西,所以,应大家的要求,这里稍微介绍一下TTL。
如果你从本地DNS查询互联网地址,服务器指出从哪里获得权威的答案并获得地址,一旦服务器获知答案,它将这个答案保存在本地缓存中以免你在稍后的时间内再次查询同样的地址,这样它就会很快地从缓存中获取你要的答案,比你再次从internet查询要快很多。
当域管理员配置DNS记录时,他们可以决定这个记录可以在缓存中保存多长时间,这就是TTL数值(通常用多少秒来表示)。
通常地,远端服务器一般对记录的缓存只保存TTL数值长的时间。时间过期后,服务器会刷新它的本地缓存并重新查询一个权威答案。
当你用dig来查询DNS服务器某条记录时,服务器会告诉dig这条记录可以在缓存中保持的时间长短。
举个例子,像上面写的那样,gmail.com域的MX记录的TTL值是300s,gmail.com域的管理员要求远端服务器缓存它的MX记录不能高于5分钟,所以当你第一次查询那个记录(gmail.com的MX记录)时,dig会告诉你一个300的TTL。
 

$ dig +nocmd gmail.com MX +noall +answer
gmail.com.        300     IN      MX      20 gsmtp57.google.com.
gmail.com.        300     IN      MX      10 gsmtp171.google.com.
 

如果你一段时间后再去查,你会发现TTL值减少为280(中间隔了20s)。
 

$ dig +nocmd gmail.com MX +noall +answer
gmail.com.        280     IN      MX      10 gsmtp171.google.com.
gmail.com.        280     IN      MX      20 gsmtp57.google.com.
 

如果你的时间计算得足够好,你会获取这条记录的最后生存时间。
 

$ dig +nocmd gmail.com MX +noall +answer
gmail.com.        1       IN      MX      10 gsmtp171.google.com.
gmail.com.        1       IN      MX      20 gsmtp57.google.com.
 

在那之后,你查询的DNS服务器会“忘记”这个问题的答案,在你下次查询这条记录时,整个循环又将开始(本例子中是300s)。

总结

1、使用@指定服务器 使用-p指定非标准端口  使用-t来指定查询类型

2、使用+[no]question或者+[no]authority来过滤某些返回数据

3、使用  +[no]short 运行简短输出

4、使用  +[no]trace 跟踪域名解析过程

5、使用 +[no]vc  来指定是否使用TCP传输。(dns使用UDP传输时包大小最大是512字节,超过512是应指定tcp方式)

6、使用-x 查询反向解析(PTR)

7、使用AXFR来检查是否存在任意区域传送。

8、使用CHAOS TXT version.bind 来查看DNS服务器版本