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

相关文章
|
21天前
|
机器学习/深度学习 算法 PyTorch
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
RPN(Region Proposal Networks)候选区域网络算法解析(附PyTorch代码)
164 1
|
24天前
|
缓存 网络协议 Linux
【Shell 命令集合 网络通讯 】Linux 配置DNS dnsconf 命令 使用教程
【Shell 命令集合 网络通讯 】Linux 配置DNS dnsconf 命令 使用教程
38 0
|
3月前
|
网络协议 网络性能优化 网络架构
【计算机网络】网络层首部解析
【1月更文挑战第27天】【计算机网络】网络层首部解析
|
3月前
|
缓存 网络协议 安全
【网络工程师】<软考中级>解析协议ARP&路由协议RIP/OSPF/BGP
【1月更文挑战第27天】【网络工程师】<软考中级>解析协议ARP&路由协议RIP/OSPF/BGP
|
4天前
|
存储 安全 测试技术
网络奇谭:虚拟机中的共享、桥接与Host-Only模式解析
网络奇谭:虚拟机中的共享、桥接与Host-Only模式解析
14 0
|
22天前
|
SQL 安全 网络安全
构筑数字堡垒:网络安全漏洞解析与防御策略
在数字化时代,网络安全已成为维护信息完整性、保障用户隐私和确保商业连续性的关键。本文将深入探讨网络安全领域的核心议题—安全漏洞及其防御机制。通过分析常见网络攻击手段,如SQL注入、跨站脚本攻击(XSS)及拒绝服务(DoS)攻击,揭示其背后的原理与潜在危害。同时,文章将重点介绍加密技术的种类和应用场景,以及如何通过强化安全意识,构建多层次的防御体系来有效预防和应对网络安全威胁。本研究旨在为读者提供一份系统性的网络安全防护指南,帮助个人和组织在不断演变的威胁面前保持警惕,并采取适当的安全措施。
16 2
|
27天前
|
域名解析 缓存 网络协议
探索Qt 网络编程:网络地址与服务类全解析
探索Qt 网络编程:网络地址与服务类全解析
54 0
|
1月前
|
数据采集 前端开发 JavaScript
Java网络爬虫实践:解析微信公众号页面的技巧
Java网络爬虫实践:解析微信公众号页面的技巧
|
1月前
|
运维 监控 网络虚拟化
|
2月前
|
域名解析 缓存 网络协议

相关产品

  • 云解析DNS
  • 推荐镜像

    更多