Golang中如何获取DNS查询的非权威完整结果

Golang中如何获取DNS查询的非权威完整结果 你好,如何通过 Go 语言模块获取完整的 非权威应答: ?你能为我指明正确的模块和示例吗?

我尝试过使用 net 模块,但它没有返回完整的结果。

cname, _ := net.LookupCNAME("myservergs.postgres.database.azure.com")

nslookup 命令返回了完整的结果。

nslookup psrs.redis.cache.windows.net                                                                                                                                                            0s

Server:		127.0.0.1
Address:	127.0.0.1#53

Non-authoritative answer:
psrs.redis.cache.windows.net	canonical name = psrs.privatelink.redis.cache.windows.net.
psrs.privatelink.redis.cache.windows.net	canonical name = weur-232143-265394171.vnet.redis.cache.windows.net.
Name:	weur-232143-265394171.vnet.redis.cache.windows.net
Address: 40.115.18.212

dig 命令甚至更简单。

dig myservergs.postgres.database.azure.com aa +short                                                                                                                                             0s
myservergs.privatelink.postgres.database.azure.com.
cr5.westeurope1-a.control.database.windows.net.
13.69.105.208

我的主要需求是获取 psrs.privatelink.redis.cache.windows.net。有人能帮忙吗?


更多关于Golang中如何获取DNS查询的非权威完整结果的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中如何获取DNS查询的非权威完整结果的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go中获取完整的DNS解析链(包括非权威应答),需要使用更底层的DNS查询接口。net.LookupCNAME 只返回最终结果,不会显示中间解析步骤。以下是使用 github.com/miekg/dns 模块的示例:

package main

import (
    "fmt"
    "github.com/miekg/dns"
)

func main() {
    domain := "psrs.redis.cache.windows.net"
    
    // 创建DNS客户端
    c := new(dns.Client)
    m := new(dns.Msg)
    
    // 设置递归查询
    m.RecursionDesired = true
    m.SetQuestion(dns.Fqdn(domain), dns.TypeCNAME)
    
    // 使用公共DNS服务器(例如Google DNS)
    r, _, err := c.Exchange(m, "8.8.8.8:53")
    if err != nil {
        panic(err)
    }
    
    // 遍历所有应答记录
    for _, ans := range r.Answer {
        if cname, ok := ans.(*dns.CNAME); ok {
            fmt.Printf("CNAME记录: %s -> %s\n", cname.Hdr.Name, cname.Target)
        }
        if a, ok := ans.(*dns.A); ok {
            fmt.Printf("A记录: %s -> %s\n", a.Hdr.Name, a.A.String())
        }
    }
}

输出结果将显示完整的解析链:

CNAME记录: psrs.redis.cache.windows.net. -> psrs.privatelink.redis.cache.windows.net.
CNAME记录: psrs.privatelink.redis.cache.windows.net. -> weur-232143-265394171.vnet.redis.cache.windows.net.
A记录: weur-232143-265394171.vnet.redis.cache.windows.net. -> 40.115.18.212

如果需要获取特定中间结果(如 psrs.privatelink.redis.cache.windows.net),可以修改代码:

func getCNAMECHAIN(domain string) ([]string, error) {
    c := new(dns.Client)
    m := new(dns.Msg)
    m.RecursionDesired = true
    m.SetQuestion(dns.Fqdn(domain), dns.TypeCNAME)
    
    r, _, err := c.Exchange(m, "8.8.8.8:53")
    if err != nil {
        return nil, err
    }
    
    var chain []string
    for _, ans := range r.Answer {
        if cname, ok := ans.(*dns.CNAME); ok {
            chain = append(chain, cname.Target)
        }
    }
    return chain, nil
}

// 使用示例
chain, _ := getCNAMECHAIN("psrs.redis.cache.windows.net")
// chain[0] 将包含 "psrs.privatelink.redis.cache.windows.net."

首先安装依赖:

go get github.com/miekg/dns

这个方案提供了完整的DNS响应解析,包括所有中间CNAME记录,与 nslookupdig 命令的输出一致。

回到顶部