指定用于在 Go 中查找的 DNS 服务器

Fra*_*844 13 dns go

有没有办法指定用于名称查找的 DNS 服务器?

查看https://golang.org/pkg/net/#LookupHost似乎它只会使用本地解析器

LookupHost looks up the given host using the local resolver. It returns a slice 
of that host's addresses.
Run Code Online (Sandbox Code Playgroud)

也早在那个链接上

 It can use a pure Go resolver that sends DNS requests directly to 
 the servers listed in /etc/resolv.conf,
Run Code Online (Sandbox Code Playgroud)

如何像使用 dig 那样对任意服务器进行查找?

dig @8.8.8.8 google.com
Run Code Online (Sandbox Code Playgroud)

Fra*_*844 17

来自reddit上的/u/gac 的回答

如果我正确地阅读了该文档(也许不是)...

使用您要使用的 DNS 地址 ( https://golang.org/pkg/net/#Resolver ) 使用自定义拨号程序创建自己的本地解析器,然后使用该解析器的 LookupAddr 函数?

编辑:

package main

import (
    "context"
    "net"
    "time"
)

func main() {
    r := &net.Resolver{
        PreferGo: true,
        Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
            d := net.Dialer{
                Timeout: time.Millisecond * time.Duration(10000),
            }
            return d.DialContext(ctx, network, "8.8.8.8:53")
        },
    }
    ip, _ := r.LookupHost(context.Background(), "www.google.com")

    print(ip[0])
}
Run Code Online (Sandbox Code Playgroud)

这似乎有效 - 在我的防火墙上,这表明我的机器正在打开与 Google 的连接,而不是本地域控制器

  • 需要注意的是,DNS 使用 UDP **和** TCP。对于那些答案不适合 UDP 数据包的查询,上述内容可能无法为您提供答案。 (5认同)
  • @nc。答案在我发表评论后进行了编辑。它最初有 `return d.DialContext(ctx, "udp", "8.8.8.8:53")`,它有我的评论中描述的问题。完成的编辑表明,即使使用“网络”也可能存在问题(无法回退到 TCP)。因此,在所有情况下,无论您做什么,作为 DNS 客户端,您都需要尝试 UDP 和 TCP,并对此保持聪明。UDP 回复可能不会出现,或者 DNS 数据包回复中带有截断标志,在这种情况下,您需要使用 TCP 重试。您还可以使用 UDP 的“bufsize”EDNS0 选项,该选项可能有帮助,也可能没有帮助。 (2认同)