我目前正在尝试编写一个脚本来验证附加到某个名称的给定记录是否可通过负责该名称的所有名称服务器获得。
例如我想检查该域的所有条目中是否有可用A
的记录(和)foo.example.com
NS
example.com
a.iana-servers.net
b.iana-servers.net
该脚本的工作原理是首先查询NS
给定名称的记录(如果失败,则查询其父级;例如,由于foo.example.com.
没有条目NS
,我们尝试example.com.
下一个和最后一个.com.
),然后检查A
所有名称服务器的记录。
name=foo.example.com
# get the nameservers for ${name}
sname=${name}
until [ -z "x${sname}" ]; do
dns=$(dig +short NS "${sname}")
if [ "x${dns}" != "x" ]; then
break
fi
sname=${sname#*.}
done
# now that we have a list of nameservers in $dns, we query them
for ns in $dns; do
dig +short A "${name}" @$"{ns}"
done
这种作品,除非这姓名实际上是CNAME
。在这种情况下, adig NS
将返回CNAME
记录(而不是NS
记录或不记录)
$ dig +noall +answer NS foo.example.com
foo.example.com. 300 IN CNAME bar.example.com.
$ dig +short NS foo.example.com
bar.example.com.
$ dig A foo.example.com @bar.example.com
;; global options: +cmd
;; connection timed out; no servers could be reached
$
相反,我想要的是类似的东西:
$ dig +short NS foo.example.com
$ dig +short NS example.com
a.iana-servers.net.
b.iana-servers.net.
$ dig +short A foo.example.com @a.iana-servers.net.
93.184.216.34
$
所以我的问题是:我怎样才能dig
强制仅有的返回NS
记录,而不是指向非名称服务器主机的其他记录?
一个明显的解决方案是解析输出dig +noall +answer
以查看它是否实际包含NS
记录,但这看起来相当笨拙且容易出错......
答案1
如果你对 Perl 很熟悉,那么你可以通过将测试编写为插件来省去大量繁琐的工作区域管理员。其框架已经有(正确的)代码来找到正确的名称服务器集并向所有名称服务器发送查询。
答案2
这是您脚本的修改版本,应该可以工作。虽然不是特别好,但应该可以工作。
警告-作为安德鲁·BPerl 答案中的评论建议,这可能是错误的方法。除了 CNAME 之外,可能还有其他极端情况。
#!/bin/bash
domain=$1
soa_len=0
# first we find SOA to get domain for which we will find name servers
until [[ -z "${domain}" ]] || [[ "$soa_len" -gt 1 ]] ; do
SOA=$(dig +short SOA "${domain}")
soa_len=$(echo $SOA | awk '{ print NF }')
# Returned SOA is not SOA but CNAME
if [ "$soa_len" -eq 1 ]; then
# set returned SOA (CNAME) as new domain and check again
domain=$SOA
# SOA is Empty
elif [ "$soa_len" -eq 0 ]; then
# remove one subdomain and check again
domain=${domain#*.}
fi
done
# Get NS records
NS=$(dig +short NS "${domain}")
# Print NS records each record on new line
for ns in $NS; do
echo $ns
done