我正在寻找一种方式(在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
吗?还是我使用了错误的功能?
答案 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.
}