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

简介: 获取域名/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 的功能。可以封装更多其他类型的查询。

目录
相关文章
|
6月前
|
域名解析 存储 网络协议
域名解析的终极指南:从基础到进阶,彻底搞懂 DNS 记录
域名解析是网站运行的基础,正确配置DNS记录至关重要。本文从基础到进阶全面解析DNS知识,涵盖A、AAAA、CNAME、MX、TXT、CAA等常见记录类型及其应用场景。通过学习,你将了解DNS的工作原理,掌握如何优化域名配置,确保网站与邮件服务高效运行。无论搭建个人博客还是企业官网,本文都能助你轻松搞定域名解析!
1183 0
|
4月前
|
网络协议 安全 区块链
DNS+:互联网的下一个十年,为什么域名系统正在重新定义数字生态? ——解读《“DNS+”发展白皮书(2023)》
DNS+标志着域名系统从基础寻址工具向融合技术、业态与治理的数字生态中枢转变。通过与IPv6、AI和区块链结合,DNS实现了智能调度、加密传输等新功能,支持工业互联网、Web3及万物互联场景。当前,中国IPv6用户达7.6亿,全球DNSSEC支持率三年增长80%,展现了其快速发展态势。然而,DNS+仍面临安全威胁、技术普惠瓶颈及生态协同挑战。未来,需推动零信任DNS模型、加强威胁情报共享,并加速标准制定,以筑牢数字时代网络根基,实现更安全、高效的数字生态建设。
308 3
|
7月前
|
域名解析 存储 缓存
深入学习 DNS 域名解析
在平时工作中相信大家都离不开 DNS 解析,因为 DNS 解析是互联网访问的第一步,无论是使用笔记本浏览器访问网络还是打开手机APP的时候,访问网络资源的第一步必然要经过DNS解析流程。
|
7月前
|
监控 负载均衡 安全
静态IP代理与动态IP代理:提升速度与保障隐私的技术解析
本文探讨了静态IP代理和动态IP代理的特性和应用场景。静态IP代理通过高质量服务提供商、网络设置优化、定期更换IP与负载均衡及性能监控提升网络访问速度;动态IP代理则通过隐藏真实IP、增强安全性、绕过封锁和提供独立IP保障用户隐私。结合实际案例与代码示例,展示了两者在不同场景下的优势,帮助用户根据需求选择合适的代理服务以实现高效、安全的网络访问。
217 1
|
7月前
|
安全 网络协议 网络安全
只有IP地址没有域名,如何实现HTTPS访问?
在仅有IP地址而无域名的情况下,实现HTTPS访问并非不可能。主要挑战包括证书颁发机构(CA)对IP地址的支持有限及浏览器兼容性问题。解决方案有:1) 搭建私有CA为内部IP地址颁发证书;2) 使用支持IP地址的公共CA服务。选择合适的方案需根据需求权衡。具体步骤包括选择证书类型、生成CSR文件、提交并完成验证、安装SSL证书和配置强制HTTPS访问。确保IP地址稳定,并定期维护安全性。 **申请优惠**:访问JoySSL官网并填写注册码“230907”可优惠申请IP地址证书。
978 5
|
7月前
|
机器学习/深度学习 人工智能 文字识别
从“泛读”到“精读”:合合信息文档解析如何让大模型更懂复杂文档?
随着deepseek等大模型逐渐步入视野,理论上文档解析工作应能大幅简化。 然而,实际情况却不尽如人意。当前的多模态大模型虽然具备强大的视觉与语言交互能力,但在解析非结构化文档时,仍面临复杂版式、多元素混排以及严密逻辑推理等挑战。
196 0
|
9月前
|
网络协议 Unix Linux
深入解析:Linux网络配置工具ifconfig与ip命令的全面对比
虽然 `ifconfig`作为一个经典的网络配置工具,简单易用,但其功能已经不能满足现代网络配置的需求。相比之下,`ip`命令不仅功能全面,而且提供了一致且简洁的语法,适用于各种网络配置场景。因此,在实际使用中,推荐逐步过渡到 `ip`命令,以更好地适应现代网络管理需求。
321 11
|
9月前
|
Serverless 对象存储 人工智能
智能文件解析:体验阿里云多模态信息提取解决方案
在当今数据驱动的时代,信息的获取和处理效率直接影响着企业决策的速度和质量。然而,面对日益多样化的文件格式(文本、图像、音频、视频),传统的处理方法显然已经无法满足需求。
325 4
智能文件解析:体验阿里云多模态信息提取解决方案
|
9月前
|
文字识别 开发者 数据处理
多模态数据信息提取解决方案评测报告!
阿里云推出的《多模态数据信息提取》解决方案,利用AI技术从文本、图像、音频和视频中提取关键信息,支持多种应用场景,大幅提升数据处理效率。评测涵盖部署体验、文档清晰度、模板简化、示例验证及需求适配性等方面。方案表现出色,部署简单直观,功能强大,适合多种业务场景。建议增加交互提示、多语言支持及优化OCR和音频转写功能...
295 3
多模态数据信息提取解决方案评测报告!
|
9月前
|
数据采集 XML API
深入解析BeautifulSoup:从sohu.com视频页面提取关键信息的实战技巧
深入解析BeautifulSoup:从sohu.com视频页面提取关键信息的实战技巧

热门文章

最新文章

推荐镜像

更多
  • DNS