该dig +short
命令(如“挖掘仅显示答案“) 非常适合将名称批量处理为 IP 地址。它完成了一项简单的工作,并且做得很好。
不幸的是,CNAME 甚至+short
不够短。例如:
$ dig +short docs.sbonds.org
ghs.google.com.
173.194.69.121
我试过了+noall
,但似乎并没有改变的行为+short
。我也试过指定-t a
以确保它不认为我指的是 A 记录或 CNAME,但这(毫不奇怪)什么也没有改变。
$ dig +noall +short docs.sbonds.org
ghs.google.com.
173.194.69.121
我正在使用 RedHat 7 dig
:
# dig -v
DiG 9.9.4-RedHat-9.9.4-73.el7_6
我可以使用 trusty 过滤掉 CNAME grep
,但 dig 似乎应该有某种方式来提供“仅 IP,女士”。
那是什么方式?
答案1
dig
是一个故障排除工具,因此它会发送 DNS 查询并接收 DNS 答案,正如 Andreas 所说,答案是 CNAME 和 A 记录,正如设计的那样。您希望提供“仅 IP,女士。”,因此这不是 DNS 故障排除,它“仅”是解决方案,这dig
太过分了。
nslookup
nslookup
不如dig
但仍然会给你太多:
$ nslookup docs.sbonds.org
Server: 192.0.2.254
Address: 192.0.2.254#53
Non-authoritative answer:
docs.sbonds.org canonical name = ghs.google.com.
Name: ghs.google.com
Address: 172.217.4.179
主持人
host
更简单,但仍然会返回“太多”(但请注意,它还会返回 IPv6 地址,这很好):
$ host docs.sbonds.org
docs.sbonds.org is an alias for ghs.google.com.
ghs.google.com has address 172.217.15.83
ghs.google.com has IPv6 address 2607:f8b0:4004:815::2013
盖特恩
根据您的 Unix 系统,getent
可以使用。但请注意,这可能会或可能不会执行 DNS 查询,因为您在/etc/nsswitch.conf
每个服务的数据源中配置了 DNS,并且它可能是两者(这是古老的)和 DNShosts
的混合。files
/etc/hosts
$ getent hosts docs.sbonds.org
2607:f8b0:4007:801::2013 ghs.google.com docs.sbonds.org
还要注意,在正确的 Unix 设置中,它将优先使用 IPv6 而不是 IPv4,所以这对你来说可能是一个问题(这应该取决于配置/etc/gai.conf
)
事实上,hosts
不遵守/etc/gai.conf
,你需要改用ahosts
,这将使用getaddrinfo
,因此gai.conf
。观察你得到一个列表(其顺序取决于gai.conf
配置):
$ getent ahosts docs.sbonds.org
172.217.4.179 STREAM ghs.google.com
172.217.4.179 DGRAM
172.217.4.179 RAW
2607:f8b0:4007:801::2013 STREAM
2607:f8b0:4007:801::2013 DGRAM
2607:f8b0:4007:801::2013 RAW
Perl
如果允许您编写一个简单的脚本,您有很多解决方案,例如:
$ perl -MSocket -E 'say inet_ntoa(inet_aton("docs.sbonds.org"))'
172.217.4.179
卫生部
或者将任何 DOH(HTTPS 上的 DNS)端点(或类似端点)与任何 HTTP 客户端一起使用。示例:
$ curl --silent 'https://dns.google.com/resolve?name=docs.sbonds.org&type=A' | jq -c '.Answer[] | select(.type == 1) | .data'
"172.217.3.83"
$ curl --silent -H 'accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=docs.sbonds.org&type=A' | jq -c '.Answer[] | select(.type == 1) | .data'
"172.217.12.147"
系统化
Systemd 有自己的解析器应用程序:
$ systemd-resolve docs.sbonds.org
docs.sbonds.org: 172.217.9.51
2607:f8b0:4009:801::2013
(ghs.google.com)
-- Information acquired via protocol DNS in 239.1ms.
-- Data is authenticated: no
您仍然需要以某种方式对其进行解析,但它确实提供了直接的最终 IP 地址(调用它时会有一个标志,使其不遵循CNAME
需要它的用例的记录)
答案2
CNAME 和相应的 A(或您要求的任何类型)都属于答案部分。因此,没有 dig 选项(至少在 RHEL7 的 dig 中没有)可以过滤掉 CNAME 响应。
我认为您必须依靠dig +short [...] | grep -v '\.$'
删除 CNAME 响应。