如何在Go中获取DNS解析失败的主机的CNAME(NXDOMAIN)?

时间:2019-07-02 15:48:48

标签: go dns cname

我正在寻找一种方式(在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似乎正好在我的小巷,但是如果主机的DNS解析失败,它将无法返回CNAME。正在运行

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 个答案:

答案 0 :(得分:6)

Go的LookupCNAME函数尝试一直遵循CNAME链直至结束。这意味着它认为没有CNAME和A的DNS名称都记录错误:

  

规范名称是在零个或多个CNAME记录之后的最终名称。只要主机不解析地址记录,只要主机不包含DNS“ CNAME”记录,LookupCNAME就不会返回错误。

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.
}