Назад | Перейти на главную страницу

Как мне попросить «копать», чтобы вернуть IP только из записи CNAME?

В 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

Я могу отфильтровать CNAME надежным grep, но похоже, что у dig должен быть какой-то способ дать «Только IP, мэм».

Что это значит?

dig - это инструмент для устранения неполадок, поэтому он отправляет DNS-запросы и получает ответы DNS, и, как сказал Андреас, ответом являются записи 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

getent

В зависимости от вашей системы Unix, getent может быть использован. Однако обратите внимание, что это может или не может выполнять DNS-запрос, потому что вы настраиваете в /etc/nsswitch.conf источник данных для каждой службы и для hosts это, вероятно, будет смесь обоих files (что почтенный /etc/hosts) и DNS.

$ 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

Или используйте любую конечную точку DOH (DNS over HTTPS) (или аналогичную) с любым 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 есть собственное приложение-преобразователь:

$ 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 записи для любых случаев использования, которые в этом нуждаются)

И CNAME, и соответствующий A (или любой другой тип, который вы просили) принадлежат разделу ответов. Таким образом, нет опции dig (по крайней мере, в dig в RHEL7), которая могла бы отфильтровать ответ CNAME.

Я думаю тебе придется положиться на dig +short [...] | grep -v '\.$' чтобы удалить ответы CNAME.