DNS

  • DNS,域名系统,是一种用于 TCP/IP 应用程序的分布式数据库,提供了主机名字和 IP 地址之间的转换以及其他一些信息.

DNS基础

  • DNS 域名空间具有层次结构,如下图:

DNS_第1张图片

  • 每一个节点都具有2种属性:

    • 标识:至多63个字符,不区分大小写.不同节点的标识可以相同.

    • 域名:即从该节点到树根的标识串连起来,中间使用一个点“.”分隔这些标识.不同节点的域名必须不同.

  • 区域: DNS层次组织中一个子树就是一个区域,区域又可以分为多个子区域.

  • 区域的授权结构: 一个区域的授权结构负责将该区域内所有主机的记录存放在名字服务器中,并提供给互联网上其他主机进行查询.

    • 当一个组织加入 Internet,并获得DNS域名空间的授权,则它们也获得了对应IP地址的in-addr.arpa域名空间的授权,这意味着当该组织新增一个主机时,需要将该主机的域名,IP地址以及其他类型的资源存放在名字服务器中,并且为域名 'IP地址(反过来).in-addr.arpa'添加一个指针类型的资源(即指针记录).这样因特网上其他主机就可以根据域名来获取主机的IP地址以及其他信息,或者根据主机的IP地址来获取主机的域名.如:

    • 一个网络号为140.252的组织加入Internet之后,将会获得noao.edu域的授权(假设该组织的域名为noao.edu),以及 252.140.in-addr.arpa域的授权,如新增主机140.252.13.33,域名为sun.noao.edu;则首先将(域名=sun.noao.edu,IP地址=140.252.13.33)存放在名字服务器中,然后将(域名=33.13.252.140.in-addr.arpa,PTR=sun.noao.edu)也存放在该主机中.这样其他主机就可以根据域名sun.noao.edu获取该主机的IP地址以及其他信息,以及根据140.252.13.33获取该主机的域名.

  • 完全合格的域名: 即以'.'结尾的域名,如 my.oschina.net.,否则认为该域名是不完全的.一般可以进行如下判断:

if 域名以'.'结尾 || 域名由2个或2个以上标识组成
    则认为该域名是完全的;
else
    该域名是不完全的;

从DNS中查询

DNS报文格式

DNS_第2张图片

  • 标识: 唯一地标识DNS查询报文.客户程序通过它来确定响应与查询是否匹配.

  • 标志: 又可细分为若干个子标志,如图:,

    • QR: 取值为0,表明该DNS是一个查询报文中.否则表明DNS是一个响应报文

    • opcode: 只在查询报文中有效,可取值: 0,标准查询(目前为止,见过的所有DNS报文都取该值);1,反向查询;2,服务器状态请求;

    • AA: 只在响应报文中有效,若置位则表明该名字服务器是待解析域名所处域的主域名服务器,其回答是可信的.否则表明回答来自名字服务器的高速缓存,可能不可信. 

    • TC: 若取值为1,表明该DNS查询/响应报文被截断了,即实际的报文长度>512字节,但限于UDP数据包的大小,只发送了512字节;此时应该使用TCP协议重新发送查询报文!
      如DNS客户端在发送一条DNS查询报文之后,在接受到的DNS响应报文中发送TC置位,则表明相应的实际字节数>=512,但由于UDP的限制,只发现了512个字节,此时客户端应该使用TCP重新发送请求,然后获取完整的DNS响应

    • RD: 只在查询报文中有效,期望递归,若取值为1,告诉名字服务器使用递归查询;若取值为0,告诉名字服务器使用迭代查询;

    • RA: 只在响应报文中有效,递归可用,若置位则表明名字服务器支持递归查询;否则表明名字服务器不支持递归查询.

    • zero: 表明未用位,必须为0.

    • rcode: 只在响应报文中有效,表明本次查询的返回值;0,没有出错;3,指定的域名不存在;...

  • 这4个字段: 说明最后4个变长字段中包含的条目数.

查询问题字段

  • 使用的格式如下:

DNS_第3张图片

  • 查询名: 就指定了待查询的域名,它是一个或多个标识的序列,每个标识以首字节的计数值来说明随后标识的字节长度,以最后字节为 0结束.如 my.oschina.net. 域名的存储为:

2 m y 7 o s c h i n a 3 n e t 0
  • 查询类型: 希望获取查询名相应类型的资源记录.如若查询类型为A,则表明希望获取查询名的IPV4地址.查询类型为AAAA,表明希望获取查询名的IPV6地址.

  • 查询类: TODO 这个不太懂,一般取值为1,表明是互联网数据... 

回答字段

  • 仅出现在响应报文中,用于回答在查询报文中出现的问题.使用的格式被称为资源记录(RR),如下:

DNS_第4张图片

  • 域名: 指定了该资源记录的域名!存储格式与在查询问题字段中的查询名一致.

    • 域名的压缩存储: 它的单计数字节中的最高两位将被设置为 11,这表示它是一个 16 bit指针而不再是 8 bit的计数字节,指针中的剩下14 bit说明在该 DNS 报文中标识符所在的位置(起始位置由标识字段的第一字节起算).如下为一次DNS响应报文的一部分:

0000   c7 62 81 80 00 01 00 03 00 05 00 00 03 77 77 77  
0010   05 62 61 69 64 75 03 63 6f 6d 00 00 01 00 01 c0  
0020   0c 00 05 00 01 00 00 03 11 00 0f 03 77 77 77 01  
0030   61 06 73 68 69 66 65 6e c0 16 c0 2b 00 01 00 01  
// c0 0c 引用偏移为12(0x0c),即 03 77 77 77 05 ... 03 63 6f 6d;
// c0 16 引用偏移为22(0x16),即'03 63 6f 6d 00',即'com.';
// c0 2b 引用偏移为0x2b,即'03 77 77 77 01...c0 16';即'www.a.shifen.com';

  • 类型: 用于指定资源数据的类型,如若类型为A,则表明资源数据为IPV4地址.若类型为AAAA,则表明资源数据为IPV6地址.

  • 类: TODO 这个不太懂,一般取值为1,表明是互联网数据... 

  • 生存时间: 指定了该资源记录在客户端的存活时间,单位为秒.

  • 资源数据长度: 指定了资源数据的字节长度;

  • 资源数据: 该域名的资源数据,可能是域名的IPV4地址,或者域名的指针,或者域名的规范名称,...

授权字段,附加信息字段

  • 该字段中使用的报文格式仍是资源记录(RR)格式.

  • 迭代查询: 当名字服务器的分布式数据库,以及其高速缓存中不存在指定的域名时,名字服务器会在发送的DNS响应报文的授权字段中指定一些可能可以解答该查询的其他名字服务器列表.并可能在附加信息字段中存放这些名字服务器的IP地址.[这是授权字段,附加信息字段的一种用处]

  • 递归查询: 当名字服务器的分布式数据库,以及其高速缓存中不存在指定的域名时,名字服务器会自动向那些可能可以解答该查询的名字服务器发送DNS查询报文,即一定会会把查询结果返回.

资源类型

  • 即上述的'查询类型','类型',一般具有值:

  • MX,邮件交换记录,格式:优先级(2 bytes);域名;邮件交换记录感觉像是别名之类的概念,如:

$ host -t mx 163.com # 请求域名 163.com 的邮件交换记录
163.com mail is handled by 10 163mx03.mxmail.netease.com. #优先级为 10.
163.com mail is handled by 50 163mx00.mxmail.netease.com. #优先级为 50.
163.com mail is handled by 10 163mx01.mxmail.netease.com.
163.com mail is handled by 10 163mx02.mxmail.netease.com.
即发往163.com的邮件实际上是发送到'163mx03.mxmail.netease.com.'等主机上的!
即163.com实际上是'163mx03.mxmail.netease.com.'这些主机的一个别名.
  • CNAME,规范名称,拥有规范名称的域名又被称为别名;如:

$ host -t cname my.oschina.net # 请求域名 my.oschina.net 的规范名称;
my.oschina.net is an alias for www.oschina.net. # 即规范名成为 www.oschina.net
  • NS,名字服务器,

$ dig my.oschina.net
oschina.net.  IN   NS	ns2.dnsv2.com.
oschina.net.  IN   NS	ns1.dnsv2.com.
# 指定了 oschina.net. 域有2个授权名字服务器,分别是 ns2.dnsv2.com.;ns1.dnsv2.com;

使用 tcp 协议的 DNS 报文格式

+-----------------------------+
| DNS消息长度 |     DNS Msg    |  
+-----------------------------+
  • DNS消息长度;2 bytes;指定了"DNS Msg"的字节长度,

  • DNS Msg,即 DNS 报文.

DNS查询,一般过程

  • 当一个名字服务器收到DNS查询后,此时一般处理过程为:

if 名字服务器是根名字服务器
    通过授权字段返回若干个可解析查询名的名字服务器;
    // 格式: 查询名所在的域;NS;1;存活时间;长度;名字服务器的域名
    通过附加字段附加上这些名字服务器的IP地址;
    // 格式: 名字服务器的域名;A;1;存活时间;长度;名字服务器的IP地址
else{ 
    if 查询名存在于数据库 
        发送一个回答;
    else if(查询名不存在于高速缓存中)
        if 使用迭代查询
            返回根名字服务器的域名以及IP地址;
            // 如上通过授权字段返回域名,通过附加字段返回IP地址;
            返回;
        else{
            向根名字服务器发送DNS查询;
            向DNS响应中的名字服务器发送DNS查询;
            ...
            if 成功获取结果
                将结果存放在高速缓存中;
            else 
                发送查询失败的DNS响应报文,如置rcode=3;
                返回;
        }
    // 此时结果一定处在高速缓存中了;
    将高速缓存中的结果通过DNS响应报文返回.   
}
  • 默认情况下,DNS查询报文首先发送往本地主机的53号端口;

DNS指针查询

  • 指针查询: 即给定一个 IP 地址,返回与该地址对应的域名.

  • 请求IP地址为'A.B.C.D'的域名,此时会发送DNS查询报文,其中问题部分格式如: 查询名=D.C.B.A.in-addr.arpa;查询类型=PTR;查询类=IN;此时收到的响应报文中资源记录如: 域名=D.C.B.A.in-addr.arpa;类型=PTR;类=IN;存活时间=xxxx;长度=xx;资源数据=主机A.B.C.D的域名;如:

$ host 8.8.8.8
8.8.8.8.in-addr.arpa domain name pointer google-public-dns-a.google.com.
$ host google-public-dns-a.google.com.
google-public-dns-a.google.com has address 8.8.8.8
google-public-dns-a.google.com has IPv6 address 2001:4860:4860::8888
# 可以抓包看一下

一些问题

是否在请求报文中包括多个问题

  • 首先,没有在 RFC 中找到相关规定(就查看了 RFC1034,RFC1035);然后测试后发现,当DNS报文中含有多个DNS问题时,无论是使用TCP,还是UDP协议,则服务端都返回 ret_code=1,Format Error,














































你可能感兴趣的:(DNS)