获取域名/IP/DNS信息 如此简单!

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
.cn 域名,1个 12个月
简介: 获取域名/IP/DNS信息 如此简单!

一、获取域名 IP 地址

要获取某个域名对应的 IP 地址,可以使用 net 包中的 LookupIP 函数:


func LookupIP(host string) ([]IP, error)

它接受一个域名参数,返回一个 IPAddr 切片和错误。IPAddr 结构体中包含了 IP 地址,可以处理 IPv4 和 IPv6 两种情况:


type IPAddr {    IP IP}
type IP []byte

使用示例:


package main
import (  "fmt"  "net")
func main() {  ips, err := net.LookupIP("www.baidu.com")  if err != nil {    fmt.Println(err)    return  }
  for _, ip := range ips {    fmt.Println(ip)  }}
输出:120.232.145.1852409:8c54:870:67:0:ff:b0c2:ad75

上例中打印出了 www.baidu.com 目前解析到的两个 IP 地址,一个 IPv4 地址,一个 IPv6 地址。


 

二、获取 IP 地址信息

对应地,若已经有一个 IP 地址,想要知道它的域名是什么,就可以使用反向查询函数 net.LookupAddr:


func LookupAddr(addr string) (names []string, err error)

它会将 IP 地址解析为一个或多个域名,返回字符串 slice。例如:


package main
import (  "fmt"  "net")
func main() {  names, _ := net.LookupAddr("8.8.8.8")  fmt.Println(names)}
输出:[dns.google.]


 

三、探测域名是否可用

要检查某个域名是否已经被注册,或者是否可供注册,可以使用 net.LookupNS 函数探测域名是否可用:


func LookupNS(host string) (names []*NS, err error)

它会查找指定主机/域名的名称服务器(Name Server),返回 NS 记录 slice。

如果域名没有被注册,它会返回错误。如果域名可以使用,它会返回域名正在使用的名称服务器记录。这可以用来判断域名是否可用:


package main
import (  "fmt"  "net")
func main() {  ns, err := net.LookupNS("example.com")  if err != nil {    fmt.Println("域名不可用")   } else {    fmt.Println("域名可用")    fmt.Println(ns)    }}
输出:域名不可用

上例中,example.com 是一个虚构的域名,结果显示此域名未被注册,不可用。


 

四、获取域名的 MX 记录

MX 记录指定了电子邮件服务器的信息。要获取一个域名的 MX 记录,可以使用 net.LookupMX 函数:


func LookupMX(name string) ([]*MX, error)

它返回一个 MX 记录的 slice,每个 MX 记录包含 mail exchange 域名与优先级:


type MX struct {    Host string    Pref uint16}

使用示例:


package main
import (    "fmt"    "net")
func main() {    mxs, err := net.LookupMX("baidu.com")    if err != nil {        fmt.Println(err)        return    }
    for _, mx := range mxs {        fmt.Printf("Host: %s, Pref: %d \n", mx.Host, mx.Pref)    }}
输出:Host: mx.maillb.baidu.com., Pref: 10Host: mx.n.shifen.com., Pref: 15  Host: usmx01.baidu.com., Pref: 20 Host: mx50.baidu.com., Pref: 20   Host: mx1.baidu.com., Pref: 20    Host: jpmx.baidu.com., Pref: 20

结果显示了 baidu.com 使用的 5 个邮件服务器域名及其优先级。


 

五、实现 DNS 查询

Go 标准库 net 包中提供了 LookupHost 函数可以通过域名查询 IP:


func LookupHost(hostname string) (addrs []string, err error)

它接受主机域名作为参数,返回其 IP 地址切片。


package main 
import (    "fmt"    "net")
func main() {    ips, err := net.LookupHost("www.example.com")    if err != nil {        fmt.Println(err)        return    }
    for _, ip := range ips {        fmt.Println(ip)     }}

如果想要自定义更灵活的 DNS 查询,可直接使用 UDP 套接字,按照 DNS 协议组织数据包,和 DNS 服务器进行通信。

下面是一个简单的 DNS 客户端查询 A 记录的实现:


package main
import (    "bytes"    "encoding/binary"    "fmt"    "net")
func main() {    // 连接DNS服务器      conn, err := net.Dial("udp", "8.8.8.8:53")    if err != nil {        fmt.Println(err)        return    }    defer conn.Close()
    // 构造DNS查询数据包    buf := new(bytes.Buffer)     // Transaction ID     var tranID uint16 = 0xABCD      binary.Write(buf, binary.BigEndian, tranID)
    flags := uint16(0x0100) // Standard query     binary.Write(buf, binary.BigEndian, flags) 
    var qds uint16 = 1 // Query Count    binary.Write(buf, binary.BigEndian, qds)
    // Only one question    var ans uint16 = 0     binary.Write(buf, binary.BigEndian, ans)    var auth uint16 = 0    binary.Write(buf, binary.BigEndian, auth)      var add uint16 = 0    binary.Write(buf, binary.BigEndian, add)
// 数据段开始// QNAMEbuf.WriteString("www.example.com") buf.WriteByte(0)
// QTYPE 和 QCLASSbinary.Write(buf, binary.BigEndian, uint16(1))binary.Write(buf, binary.BigEndian, uint16(1))
// 发送DNS查询请求conn.Write(buf.Bytes())
// 读取响应    reply := make([]byte, 512)_, err = conn.Read(reply)if err != nil {    fmt.Println("No reply")    return}
// 解析响应// 校验事务ID匹配tid := binary.BigEndian.Uint16(reply[0:2]) if tid != tranID {    fmt.Println("Wrong transaction ID")    return  }
// Response Coderescode := binary.BigEndian.Uint16(reply[3:5])if rescode != 0 {    fmt.Println("Server returned error")     return}
// 查询数应为1qdcount := binary.BigEndian.Uint16(reply[4:6])  if qdcount != 1 {    fmt.Println("Invalid query count")    return}
// 回答Resource记录数 >= 1ancount := binary.BigEndian.Uint16(reply[6:8])if ancount < 1 {     fmt.Println("No answer")    return}
// 跳过问题portionstart := 12  for {    if reply[start] == 0 {        break    }    start++}start += 5 
// 解析回答for i := 0; i < int(ancount); i++ {    // 跳过NAME    nameLen := int(reply[start])     start += 1 + nameLen  
    typ := binary.BigEndian.Uint16(reply[start : start+2])    start += 2    class := binary.BigEndian.Uint16(reply[start : start+2])     start += 2    ttl := binary.BigEndian.Uint32(reply[start : start+4])    start += 4
    rdlen := binary.BigEndian.Uint16(reply[start : start+2])    start += 2        // A记录为IP    if typ == 1 {         ip := net.IP(reply[start : start+rdlen]).String()          fmt.Println(ip)     }
    start += int(rdlen)}
}

上例实现了完整的 DNS 查询 client,自定义构造请求数据包,解析返回结果,打印查询 IP。使用 UDP socket 和 DNS 服务器通信。

这只是最基础的查询 A 记录的示例,可以扩展实现其他类型的 Resource Record 查询。


 

六、更多 DNS 记录查询

除了 A 记录(地址)查询,Go 标准库还提供了查询其他 DNS 记录的函数:

查询 TXT 记录


func LookupTXT(host string) ([]string, error)

查询 SRV 记录


func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error)

使用示例:


package main
import (  "fmt"  "net")
func main() {  texts, _ := net.LookupTXT("baidu.com")  for _, text := range texts {    fmt.Println(text)  }
  _, srvs, _ := net.LookupSRV("xmpp-server", "tcp", "baidu.com")  for _, srv := range srvs {    fmt.Println(srv.Target)  }}


 

七、域名/IP 相关实用包

除了标准库,Go 社区还提供了很多域名和 IP 地址操作相关的实用包,可以大大简化相关开发:

godns

godns 提供了便捷的域名查询和更新 API,支持不同类型的记录查询:


import "github.com/timshannon/godns"
A, _ := godns.Lookup("baidu.com", "A")MXs, _ := godns.Lookup("baidu.com", "MX"))

hosts

hosts 包实现了 hosts 文件(像 Linux 中的/etc/hosts)相关操作:


import "github.com/jaytaylor/go-hostsfile"
hosts, _ := hostsfile.NewHostsfile()ip := hosts.IP("localserver")hosts.Add("192.168.1.5", "test")

以上两个库可以大大简化域名/IP 相关操作。


 

八、模拟 NSLOOKUP

可编写一个类似 NSLOOKUP 命令行工具的程序,输入域名和 DNS 服务器地址,显示域名 lookup 的结果:


package main
import (    "flag"    "fmt"    "net"    "os")
func main() {    domain := flag.String("d", "baidu.com", "Domain to lookup")    server := flag.String("s", "8.8.8.8:53", "DNS server")    flag.Parse()        // UDP连接DNS服务器    conn, err := net.Dial("udp", *server)    if err != nil {        fmt.Println(err)        os.Exit(1)    }        // 模拟A记录查询    ips, err := lookupA(conn, *domain)    if err != nil {        fmt.Println(err)     } else {        fmt.Printf("Domain: %s\n", *domain)         fmt.Println(ips)    }          conn.Close()   }
// 模拟A记录查询func lookupA(conn net.Conn, domain string) ([]string, error) {        // 构造DNS查询请求数据包     buf := new(bytes.Buffer)
    // ..... 省略请求数据包组装过程            conn.Write(buf.Bytes())         // 解析返回数据包     reply := make([]byte, 512)        n, err := conn.Read(reply)         // ...... 省略解析过程获取IP        var ips []string     ips = append(ips, ip.String())     return ips, nil}

通过命令行参数指定域名和服务器地址模拟 NSLOOKUP 查询 IP 的功能。可以封装更多其他类型的查询。

目录
相关文章
|
7天前
|
域名解析 网络协议 安全
反向DNS解析是从IP地址到域名的映射,主要作用于验证和识别,提高通信来源的可信度和可追溯性
在网络世界中,反向DNS解析是从IP地址到域名的映射,主要作用于验证和识别,提高通信来源的可信度和可追溯性。它在邮件服务器验证、网络安全等领域至关重要,帮助识别恶意行为,增强网络安全性。尽管存在配置错误等挑战,但正确管理下,反向DNS解析能显著提升网络环境的安全性和可靠性。
29 3
|
2月前
|
自然语言处理 数据可视化 前端开发
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
合合信息的智能文档处理“百宝箱”涵盖文档解析、向量化模型、测评工具等,解决了复杂文档解析、大模型问答幻觉、文档解析效果评估、知识库搭建、多语言文档翻译等问题。通过可视化解析工具 TextIn ParseX、向量化模型 acge-embedding 和文档解析测评工具 markdown_tester,百宝箱提升了文档处理的效率和精确度,适用于多种文档格式和语言环境,助力企业实现高效的信息管理和业务支持。
4019 5
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
|
15天前
|
网络协议 网络安全 网络虚拟化
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算
本文介绍了十个重要的网络技术术语,包括IP地址、子网掩码、域名系统(DNS)、防火墙、虚拟专用网络(VPN)、路由器、交换机、超文本传输协议(HTTP)、传输控制协议/网际协议(TCP/IP)和云计算。通过这些术语的详细解释,帮助读者更好地理解和应用网络技术,应对数字化时代的挑战和机遇。
56 3
|
17天前
|
运维 监控 安全
在实际应用中,如何选择基于不同域名还是不同 IP 进行代理多服务的配置?
综上所述,在实际应用中选择基于不同域名还是不同 IP 进行代理多服务的配置,需要根据具体的业务需求、可扩展性、性能、安全性以及维护和管理成本等多方面因素进行综合考虑,权衡利弊,选择最适合自己系统架构和运营需求的配置方式。
|
18天前
|
域名解析 网络协议 测试技术
IP、掩码、网关、DNS1、DNS2到底是什么东西,ping telnet测试
理解IP地址、子网掩码、默认网关和DNS服务器的概念是有效管理和配置网络的基础。通过使用ping和telnet命令,可以测试网络连通性和服务状态,快速诊断和解决网络问题。这些工具和概念是网络管理员和IT专业人员日常工作中不可或缺的部分。希望本文提供的详细解释和示例能够帮助您更好地理解和应用这些网络配置和测试工具。
51 2
|
28天前
|
域名解析 缓存 网络协议
浏览器中输入URL返回页面过程(超级详细)、DNS域名解析服务,TCP三次握手、四次挥手
浏览器中输入URL返回页面过程(超级详细)、DNS域名解析服务,TCP三次握手、四次挥手
|
2月前
|
人工智能 前端开发 JavaScript
拿下奇怪的前端报错(一):报错信息是一个看不懂的数字数组Buffer(475) [Uint8Array],让AI大模型帮忙解析
本文介绍了前端开发中遇到的奇怪报错问题,特别是当错误信息不明确时的处理方法。作者分享了自己通过还原代码、试错等方式解决问题的经验,并以一个Vue3+TypeScript项目的构建失败为例,详细解析了如何从错误信息中定位问题,最终通过解读错误信息中的ASCII码找到了具体的错误文件。文章强调了基础知识的重要性,并鼓励读者遇到类似问题时不要慌张,耐心分析。
|
18天前
|
安全 数据建模 测试技术
只有ip没有域名怎么申请SSL
在没有域名只有IP地址的情况下,仍可申请SSL证书。需确保拥有固定公网IP地址和服务器管理权限,选择支持IP SSL证书的CA(如JoySSL),完成注册、购买、验证、安装和测试等步骤,实现HTTPS加密访问。注意证书有效期、兼容性和安全性。
|
15天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
45 2
|
2月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
70 0