DNS网络协议初探

简介: DNS网络协议初探

DNS协议初探




DNS 使用TCP还是UDP协议?

DNS 迭代查询 和 递归查询 是什么?

如何构建DNS报文?



1. 什么是DNS


DNS: (Domain Name System) 域名系统, 用户在使用常用网络软件,例如: 浏览器,邮件 等,但是这些服务需要指定服务器的ip地址和端口号,这个难以记忆,大家更喜欢易读、有一定含义的名字,DNS就能满足这个要求,实现将域名映射为IP地址,这个就称为域名解析。目前互联网 DNS为分布式数据库, 域名服务器分布在世界各地,每个服务器也只存储了部分域名信息。


1.1 域名层次化


域名结构由标号序列组成,标点符号用点隔开, 例如: juejin.cn.  www.jd.com. 可总结为: ....三级域名.二级域名.顶级域名.根域名(可省略)



截止目前为止,全球上共有13个根服务器 ,从 a - m



# yum -y install bind-utils
# dig | grep root | awk '{print $NF}' | sort
a.root-servers.net.
b.root-servers.net.
c.root-servers.net.
d.root-servers.net.
e.root-servers.net.
f.root-servers.net.
g.root-servers.net.
h.root-servers.net.
i.root-servers.net.
j.root-servers.net.
k.root-servers.net.
l.root-servers.net.
m.root-servers.net.
# 



顶级域名分类:


  • 国家顶级域名nTLD
  • cn: 表示中国
  • us: 表示美国
  • jp: 表示日本
  • ...
  • 通用顶级域名gTLD
  • com: 表示工商企业
  • net: 表示网络提供商
  • gov: 政府专用
  • ...
  • 基础结构域名
  • arpa




1.2 域名服务器分类


域名服务器以区为单位,可以分为: 1. 根域名服务器 2. 顶级域名服务器 3. 权威域名服务器 4. 中间域名服务器


根域名服务器

全球共有13个根域名服务器,可通过 dig 获取。


顶级域名服务器

TLD服务器,负责管理该顶级域名下的二级域名。


权威域名服务器

负载一个区的域名服务器,保存该区的域名 和 IP地址映射关系。


中间服务器

不属于如上三种服务器,就是中间域名服务器。



1.3 通过实例来判断服务器分类


本次查询,DNS服务器信息如下


  • 本地域名服务器: 61.139.2.69
  • 根域名服务器: a.root-servers.net (198.41.0.4#53)
  • 顶级域名服务器: g.dns.cn (66.198.183.65#53)
  • 权威域名服务器: vip4.alidns.com (47.113.183.36#53)



利用dig追踪日志如下

dig +trace 可以追踪请求


# dig +trace juejin.cn. @61.139.2.69 
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.7 <<>> +trace juejin.cn. @61.139.2.69
;; global options: +cmd
.                       28351   IN      NS      a.root-servers.net.
.                       28351   IN      NS      b.root-servers.net.
.                       28351   IN      NS      c.root-servers.net.
.                       28351   IN      NS      d.root-servers.net.
.                       28351   IN      NS      e.root-servers.net.
.                       28351   IN      NS      f.root-servers.net.
.                       28351   IN      NS      g.root-servers.net.
.                       28351   IN      NS      h.root-servers.net.
.                       28351   IN      NS      i.root-servers.net.
.                       28351   IN      NS      j.root-servers.net.
.                       28351   IN      NS      k.root-servers.net.
.                       28351   IN      NS      l.root-servers.net.
.                       28351   IN      NS      m.root-servers.net.
;; Received 228 bytes from 61.139.2.69#53(61.139.2.69) in 3 ms
cn.                     172800  IN      NS      c.dns.cn.
cn.                     172800  IN      NS      g.dns.cn.
cn.                     172800  IN      NS      b.dns.cn.
cn.                     172800  IN      NS      ns.cernet.net.
cn.                     172800  IN      NS      e.dns.cn.
cn.                     172800  IN      NS      f.dns.cn.
cn.                     172800  IN      NS      a.dns.cn.
cn.                     172800  IN      NS      d.dns.cn.
cn.                     86400   IN      DS      57724 8 2 5D0423633EB24A499BE78AA22D1C0C9BA36218FF49FD95A4CDF1A4AD 97C67044
cn.                     86400   IN      RRSIG   DS 8 1 86400 20211211170000 20211128160000 14748 . gM8pprqRpkmDpcu6kNU5kffmW1jo9dmT/CjK7g9dUH4F2purVO1Txiyr RszAgzMWe7HmxeLLEN1s0p2vxbQvQ0uQZn7DMA5eJWbNf/rINyT6vmMK BndvUuTJ74wnEkiXY8Cviim597TEFWl5w7Z9Bn0FwM2nzt5OHBDben24 Fca3vbIXK3Q2n1cDbpO01We/VbiUrgcxlNAxm68wC8gWwLypFNFDXw5V tHVwwX4NsKG1si6n5lyuKramPj+GM9YV/htDNSZKzjEyHTrp/lfwQoxX Eju+cOhmFvnnSFRLS+9EyVmil+i822M2QyVbLhmwjkW8pdER+RxXd+pv vrm6gA==
;; Received 700 bytes from 198.41.0.4#53(a.root-servers.net) in 223 ms
juejin.cn.              86400   IN      NS      vip3.alidns.com.
juejin.cn.              86400   IN      NS      vip4.alidns.com.
3QDAQA092EE5BELP64A74EBNB8J53D7E.cn. 21600 IN NSEC3 1 1 10 AEF123AB 3QM14FQ32F1CJFTP8D3J5BCTNP5BIELO NS SOA RRSIG DNSKEY NSEC3PARAM
3QDAQA092EE5BELP64A74EBNB8J53D7E.cn. 21600 IN RRSIG NSEC3 8 2 21600 20211225190654 20211125181736 38388 cn. B735xzQYqVTspNxPes9yYW+EnnN1GuaKhRhI4UuowLiDdRqwrk1I/+3F aqzWerS2SUO+nhzcSzl+NeiIwBBuOjyh/NgF15e1WBHvc8PR2cG3HXSo rD3usJlX1rlaOZH6EP5k/VkMSktveAeJo3foOF104UXuljG0yRQqp+4v sh0=
DEFPMSCATA3DEUN2HJMIGDHN15FBH1AM.cn. 21600 IN NSEC3 1 1 10 AEF123AB DGCV05BN5EJCBB4F86S87BCR5CJOA3IC NS DS RRSIG
DEFPMSCATA3DEUN2HJMIGDHN15FBH1AM.cn. 21600 IN RRSIG NSEC3 8 2 21600 20211225184833 20211125181738 38388 cn. ghEDLlzom97T/4SL7znLbN5PKD0qyInh6VgcDw6dZPmoDy7eDd0Gk1Vw VoSSnn7dBp7AK8zEkAygKg28QiNFgPlWDlUtM37R3H3OGqfnJRiJ7R85 n/HSMchAunBtMgkSrtmXUVryzUm5inyi/FxH2iVc4fgGQZlLNmZr5BG+ lqQ=
;; Received 577 bytes from 66.198.183.65#53(g.dns.cn) in 274 ms
juejin.cn.              600     IN      CNAME   juejin.cn.w.cdngslb.com.
;; Received 75 bytes from 47.113.183.36#53(vip4.alidns.com) in 46 ms
# 


解析请求图大致如下

image.png




1.4 DNS递归解析和迭代解析


递归查询: 在进行查询时,若没有被查询的域名信息,则进行代理查询,直至查询到IP地址/或者是查询失败 , 然后返回给本地域名服务器。


迭代查询: 不会进行代理查询请求,而是将结果或者是下一跳域名服务器返回给本地域名服务器。

图示

迭代查询


image.png


递归查询

image.png




2. DNS报文解析


参考 rfc1035 datatracker.ietf.org/doc/html/rf…

请求报文

image.png



响应报文


image.png



2.1 DNS 整个报文格式

+---------------------+
    |        Header       |
    +---------------------+
    |       Question      | the question for the name server
    +---------------------+
    |        Answer       | RRs answering the question
    +---------------------+
    |      Authority      | RRs pointing toward an authority
    +---------------------+
    |      Additional     | RRs holding additional information
    +---------------------+



2.2 Head: 请求头

1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      ID                       |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    QDCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ANCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    NSCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ARCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+



ID: 16bit 查询/响应编号

作为 查询 和 应答标识ID


QR: 1bit 报文类型

0: 查询

1: 响应


Opcode:  4bit 查询的类型

0: 标准查询

1: 反查询

2: 服务器状态请求

3-15: 暂时闲置


AA: 1bit 权威应答

1: 是

0: 否


TC: 1bit 超出最大允许的长度(UDP包为512字节)

UDP 包为 512 字节,若返回报文超过512个字节,则需要将状态标志位 TC 置为1 然后将报文返回给客户端,客户端收到后会再次使用 TCP 进行查询请求

1: 超出最大长度,截断

0: 正常


RD: 1bit  期望递归查询

1: 需要递归查询

0:  不需要递归查询


RA: 1bit  可用递归 , 用于响应报文中

1: 支持递归

0: 不支持递归


Z: 3bit

保留


RCODE: 4bit 响应代码

0: 没有错误

1: 格式错误

2: 服务器故障

3: 名称错误

4: 不支持请求类型的查询

5: 服务器拒绝查询

6-15: 备用


2.3 Question 查询请求

                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                                               |
    /                     QNAME                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     QTYPE                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     QCLASS                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+


QNAME:  表示查询的域名

每个标签由一个8字节的长度 和 响应的字符组成

例如 juejin.com

在报文中QNAME应该展示为

6 j u e j in 3 c o m 0

image.png


QTYPE:  16bit 请求的类型

1: A

2: NS

3: MD

4: MF

5: CNAME

6: SOA

7: MB

8: MG

9: MR

10: NULL

11: WKS

12: PTR

13: HINFO

14: MINFO

15: MX

16: TXT


QCLASS: 16bit 请求的方式

1:  一般网络请求

2: CSNET

3: CHAOS

4: Hesiod


2.4 Answer 响应报文

                                    1  1  1  1  1  1
      0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                                               |
    /                                               /
    /                      NAME                     /
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TYPE                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                     CLASS                     |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      TTL                      |
    |                                               |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                   RDLENGTH                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
    /                     RDATA                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+


**NAEM: 16bit **

资源记录域名 , 采用 2个byte 来表示 , CO 为固定标记位,代表后面的值为偏移量

+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    | 1  1|                OFFSET                   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+


TYPE 16bit

RDATA资源类型


CLASS: 16bit

请求类型


TTL: 32bit

缓存时间,为0则不能缓存


RDLENGTH: 16bit

RDATA字节数


RDATA: RDLENGTH byte

资源记录值



3. DNS golang 代码案例


3.1 获取请求报文

获取/生成A记录报文Demo 代码放在了 gitee 上 gitee.com/pdudo/Sampl…

代码


package main
import (
  "fmt"
  "gitee.com/pdudo/SampleDNSTool"
  "log"
  "net"
)
func main() {
  var dnsInfo SampleDNSTool.DNSInfo
  udpconn ,err := net.ListenUDP("udp",&net.UDPAddr{
    IP: net.IPv4(0,0,0,0),
    Port: 53,
  })
  if err != nil {
    log.Fatal("listen udp error" , err)
  }
  for {
    buf := make([]byte,1024)
    n , err := udpconn.Read(buf[:])
    if err != nil {
      log.Println("udpconn error " , err)
    }
    dnsInfo.GetHeader(buf[:n])
    dnsInfo.GetQuestion(buf[:n])
    fmt.Println("DNS 查询ID: " ,dnsInfo.Header.ID ,
      "HeaderStatus:" , dnsInfo.Header.HeaderStatus ,
      "QCount:" , dnsInfo.Header.QCOUNT,
      "Qname:" , dnsInfo.QueryInfo.QNAMEString ,
      "QTYPE:",dnsInfo.QueryInfo.QTYPE ,
      "QCLASS:",dnsInfo.QueryInfo.QCLASS)
  }
}


启动服务器 并且 使用nslookup模拟请求

# go build
# ./testDNSQuery


客户端

# nslookup juejin.com 127.0.0.1
;; connection timed out; no servers could be reached
#


程序输出

# ./testDNSQuery
DNS 查询ID:  27284 HeaderStatus: {0 0 0 0 1 0 0 0} QCount: 1 Qname: juejin.com QTYPE: 1 QCLASS: 1
DNS 查询ID:  27284 HeaderStatus: {0 0 0 0 1 0 0 0} QCount: 1 Qname: juejin.com QTYPE: 1 QCLASS: 1
DNS 查询ID:  27284 HeaderStatus: {0 0 0 0 1 0 0 0} QCount: 1 Qname: juejin.com QTYPE: 1 QCLASS: 1


生成响应报文


修改代码

package main
import (
    "fmt"
    "gitee.com/pdudo/SampleDNSTool"
    "log"
    "net"
)
func main() {
    var dnsInfo SampleDNSTool.DNSInfo
    udpconn ,err := net.ListenUDP("udp",&net.UDPAddr{
        IP: net.IPv4(0,0,0,0),
        Port: 53,
    })
    if err != nil {
        log.Fatal("listen udp error" , err)
    }
    for {
        buf := make([]byte,1024)
        n , fromudpaddr , err := udpconn.ReadFromUDP(buf[:])
        if err != nil {
            log.Println("udpconn error " , err)
        }
        dnsInfo.GetHeader(buf[:n])
        dnsInfo.GetQuestion(buf[:n])
        fmt.Println("DNS收到请求 , 查询ID: " ,dnsInfo.Header.ID ,
            "HeaderStatus:" , dnsInfo.Header.HeaderStatus ,
            "QCount:" , dnsInfo.Header.QCOUNT,
            "Qname:" , dnsInfo.QueryInfo.QNAMEString ,
            "QTYPE:",dnsInfo.QueryInfo.QTYPE ,
            "QCLASS:",dnsInfo.QueryInfo.QCLASS)
        // 构建回复报文
        if (1 == dnsInfo.QueryInfo.QTYPE) {
            ip := make([]byte,4)
            ip[0] = 192
            ip[1] = 168
            ip[2] = 111
            ip[3] = 129
            res :=  dnsInfo.GenerateAnswers(buf[:n],ip,0,1)
            //udpconn.Write(res)
            udpconn.WriteToUDP(res,fromudpaddr)
        }
    }
}


利用nslookup查看效果

# nslookup juejin.com 127.0.0.1
Server:         127.0.0.1
Address:        127.0.0.1#53
Non-authoritative answer:
Name:   juejin.com
Address: 192.168.111.129
;; connection timed out; no servers could be reached

目录
打赏
0
0
0
0
60
分享
相关文章
Infoblox DDI (NIOS) 9.0 - DNS、DHCP 和 IPAM (DDI) 核心网络服务管理
Infoblox DDI (NIOS) 9.0 - DNS、DHCP 和 IPAM (DDI) 核心网络服务管理
101 4
【Android】网络技术知识总结之WebView,HttpURLConnection,OKHttp,XML的pull解析方式
本文总结了Android中几种常用的网络技术,包括WebView、HttpURLConnection、OKHttp和XML的Pull解析方式。每种技术都有其独特的特点和适用场景。理解并熟练运用这些技术,可以帮助开发者构建高效、可靠的网络应用程序。通过示例代码和详细解释,本文为开发者提供了实用的参考和指导。
140 15
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
阿里云CDN:全球加速网络的实践创新与价值解析
在数字化浪潮下,用户体验成为企业竞争力的核心。阿里云CDN凭借技术创新与全球化布局,提供高效稳定的加速解决方案。其三层优化体系(智能调度、缓存策略、安全防护)确保低延迟和高命中率,覆盖2800+全球节点,支持电商、教育、游戏等行业,帮助企业节省带宽成本,提升加载速度和安全性。未来,阿里云CDN将继续引领内容分发的行业标准。
342 7
深入解析图神经网络注意力机制:数学原理与可视化实现
本文深入解析了图神经网络(GNNs)中自注意力机制的内部运作原理,通过可视化和数学推导揭示其工作机制。文章采用“位置-转移图”概念框架,并使用NumPy实现代码示例,逐步拆解自注意力层的计算过程。文中详细展示了从节点特征矩阵、邻接矩阵到生成注意力权重的具体步骤,并通过四个类(GAL1至GAL4)模拟了整个计算流程。最终,结合实际PyTorch Geometric库中的代码,对比分析了核心逻辑,为理解GNN自注意力机制提供了清晰的学习路径。
420 7
深入解析图神经网络注意力机制:数学原理与可视化实现
阿里云网络安全体系解析:如何构建数字时代的"安全盾牌"
在数字经济时代,阿里云作为亚太地区最大的云服务提供商,构建了行业领先的网络安全体系。本文解析其网络安全架构的三大核心维度:基础架构安全、核心技术防护和安全管理体系。通过技术创新与体系化防御,阿里云为企业数字化转型提供坚实的安全屏障,确保数据安全与业务连续性。案例显示,某金融客户借助阿里云成功拦截3200万次攻击,降低运维成本40%,响应时间缩短至8分钟。未来,阿里云将继续推进自适应安全架构,助力企业提升核心竞争力。
深入解析:Linux网络配置工具ifconfig与ip命令的全面对比
虽然 `ifconfig`作为一个经典的网络配置工具,简单易用,但其功能已经不能满足现代网络配置的需求。相比之下,`ip`命令不仅功能全面,而且提供了一致且简洁的语法,适用于各种网络配置场景。因此,在实际使用中,推荐逐步过渡到 `ip`命令,以更好地适应现代网络管理需求。
247 11
深入解析PDCERF:网络安全应急响应的六阶段方法
PDCERF是网络安全应急响应的六阶段方法,涵盖准备、检测、抑制、根除、恢复和跟进。本文详细解析各阶段目标与操作步骤,并附图例,助读者理解与应用,提升组织应对安全事件的能力。
959 89
一次读懂网络分层:应用层到物理层全解析
网络模型分为五层结构,从应用层到物理层逐层解析。应用层提供HTTP、SMTP、DNS等常见协议;传输层通过TCP和UDP确保数据可靠或高效传输;网络层利用IP和路由器实现跨网数据包路由;数据链路层通过MAC地址管理局域网设备;物理层负责比特流的物理传输。各层协同工作,使网络通信得以实现。
TCP报文格式全解析:网络小白变高手的必读指南
本文深入解析TCP报文格式,涵盖源端口、目的端口、序号、确认序号、首部长度、标志字段、窗口大小、检验和、紧急指针及选项字段。每个字段的作用和意义详尽说明,帮助理解TCP协议如何确保可靠的数据传输,是互联网通信的基石。通过学习这些内容,读者可以更好地掌握TCP的工作原理及其在网络中的应用。

相关产品

  • 云解析DNS
  • 推荐镜像

    更多
  • DNS
  • AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等

    登录插画

    登录以查看您的控制台资源

    管理云资源
    状态一览
    快捷访问