Как я могу получить CNAME хоста, для которого не удается разрешить DNS (NXDOMAIN) в Go? - PullRequest
3 голосов
/ 02 июля 2019

Я ищу способ (в Go) получить CNAME (если есть) данного хоста, независимо от того, происходит ли разрешение DNS этого хоста или нет .

Разрешение DNS хоста может дать сбой и привести к NXDOMAIN, но у рассматриваемого хоста все еще может быть запись CNAME. На момент написания этого вопроса tst1crmapps.starbucks.com является примером такого хоста:

$ dig tst1crmapps.starbucks.com | grep -E 'NXDOMAIN|CNAME'
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 50444
tst1crmapps.starbucks.com. 86400 IN CNAME   bigip-tst1crmapps-starbucks.oracle.com.

(работает на macOS)

Функция net.LookupCNAME, кажется, мне подходит, но он не может вернуть CNAME, если разрешение DNS-узла не удается. Запуск

package main

import (
    "log"
    "net"
)

func main() {
    cname, err := net.LookupCNAME("tst1crmapps.starbucks.com")
    if err != nil {
        log.Fatal(err)
    }
    log.Println(cname)
}

выходы

yyyy/MM/dd hh:mm:ss lookup tst1crmapps.starbucks.com: no such host

Я неправильно понимаю net.LookupCNAME? Или я использую не ту функцию?

1 Ответ

6 голосов
/ 02 июля 2019

Функция LookupCNAME Go пытается следовать цепочке CNAME до самого конца. Это означает, что он считает DNS-имя без записей CNAME и A ошибкой:

Каноническое имя - это окончательное имя после нуля или более записей CNAME. LookupCNAME не возвращает ошибку, если хост не содержит DNS-записи «CNAME», если хост разрешает адресные записи.

Go не предоставляет низкоуровневый DNS API в стандартной библиотеке. Де-факто стандартным пакетом для этого является github.com / miekg / dns (обработка ошибок и проверка типов исключены для краткости):

package main

import (
    "fmt"

    "github.com/miekg/dns"
)

func main() {
    config, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
    c := new(dns.Client)
    m := new(dns.Msg)

    // Note the trailing dot. miekg/dns is very low-level and expects canonical names.
    m.SetQuestion("tst1crmapps.starbucks.com.", dns.TypeCNAME)
    m.RecursionDesired = true
    r, _, _ := c.Exchange(m, config.Servers[0]+":"+config.Port)

    fmt.Println(r.Answer[0].(*dns.CNAME).Target) // bigip-tst1crmapps-starbucks.oracle.com.
}

...