1. DNS概述
当你想在某个浏览器中打开Chrome、Firefox、Bing等搜索引擎时,脑海里第一时间是想到输入:www.google.com (域名),还是输入ip地址:172.217.11.68. 习惯性地,都是输入域名地址,因为字符更容易被记住。比如,不用刻意,我们都能够轻易地记住淘宝、天猫、京东、当当等字符串域名,但是它的实际服务器ip多少?我们从未去关心过。表象看起来,输入域名也能够起到网络连接通信效果,但实际上,这背后却有一个服务默默地位我们做了许多的操作,它就是DNS。(Hostname Lookup Tools 工具根据提供域名来寻址对应IP)。
DNS(Domain Name System, DNS)域名系统,它实现了将符号域名转换为对应IP地址的功能。若没有DNS,我们不得不去记住所有Internet目的地的IP地址,细思极恐,这将是多么艰难的一件事。此外,DNS域名系统还支持其他的服务,比如将电子邮件(xxx@qq.com、xxx@gmail.com、xxx@163.com等)根据其格式找到能够处理此流量格式的服务器ip。网络通信是根据ip地址来寻址的,DNS暗中执行了翻译过程。DNS促进了Internet的发展及交互便捷性。
DNS是应用层协议,位于TCP/IP的第五层。Internet中的网络设备具有把名称解析成IP地址能力,在把一个IP数据包发送到Internet目的地之前,必须进行从名称到ip地址的解析过程。名称是人们为了便于记忆而为设备命名的,在将名称解析为对应ip地址时候,一般有三种方法(备注:来自《TCP/IP协议原理与应用》的P324的8.1节.)
(1) 计算机求助于硬盘上的一个从名称到ip地址的文件或表。因为需要不断手动更新,所以只适用用小型网络中.
(2) 计算机发送广播请求,声明它要发送一个数据包给特定的计算机名,并请求该计算机的ip地址。目的主机接收到该请求,并将本机ip地址返给请求方。名称解析过程完成,接下来就可以开始数据包的发送。适合本地网络,远程网络或是同网络下的子网络不适用。
(3) 源计算机与一个服务器进行连续;该服务器中维护着一个大型且动态更新的具有从名字到地址项的数据库,它为源设备提供查询服务,发送正确地址映射,并允许发送计算机传输数据包。允许计算机为世界上任何相连的设备进行名称解析功能。
对于OSI七层模型,DNS位于第六层(layer 7,表示层).DNS是一个分层的客户机-服务器协议。每个域名(如neu.edu、microsoft.com等)由一个或多个DNS服务器提供服务,这意味着对子域的请求(例如,www.neu.edu) 和(research.microsoft.com)被发送到这些服务器。
图片来自 THE DNS PROTOCOL
2. DNS报文格式
对于DNS,其查询消息报文和响应消息报文在格式有些差异,因此将DNS的报文格式分为两小部分来进行说明讲解。不尽相同并不代表完全不同,DNS请求报文和响应报文整体结构报文格式如下:
从图中可以看到,DNS报文消息的头部字段(Header, 12字节)内部含义大量的重要信息,这些消息对于DNS的请求、响应成功与否扮演了不可忽视的角色。
ID(Transaction ID, 2字节) 事务ID,它由请求客户端设置并由服务端响应。客户端用这个事务ID来唯一识别、区分请求与响应是否为同一个事务。
接下来的2字节是标志位Flags(16位),覆盖的信息量很广,现将标志位Flags中的16位拆分开来,针对其中每一位进行说明,如下图:
Flags:
OR: 1位(bit)大小,标记该消息报文是查询还是请求. 0-表示查询, 1-表示响应;
Opcode: 操作码4位(bit), 通常为0-标准查询;1-反向查询;2-服务器状态请求.
AA: 1位(bit), 表示”授权回答”, 即该名字服务器(Name Server)是授权与该域的.
TC: 1位(bit), Truncated(可参考Wireshark数据分段展示栏界面), 可截断的, 表示当使用UDP传输协议时候,若报文大小超过512字节, 可对其进行截取仅返回报文前部分的512字节大小.
RD: 1位(bit), Recursion Desired, 表示该DNS请求规则是希望”期望递归”方式进行查询. 通常有两种查询方式: 递归查询和非递归查询(迭代查询). 0-迭代查询.
RA: 1位(bit), Recursion Available, 表示”可用递归查询”, 若DNS服务器支持递归查询方式, 则在响应(Transaction ID相同)报文中该字段置1.
Z: 3位(bit), Zeserved. 保留字段,以备将来使用, 必须将次字段置0.
RCODE: Resonse Code, 4位(bit), 设置为响应的一部分。这些值有以下解释:
- 0: 无错误条件.
- 1: 格式错误-名称服务器无法解释查询.
- 2: 服务器故障——由于存在问题,名称服务器无法处理此查询服务器的名称.
- 3: 名称错误-仅对来自权威名称服务器的响应有意义,此代码表示查询中引用的域名不存在.
- 4: 未实现-名称服务器不支持所请求的查询类型.
- 5: 拒绝-名称服务器由于策略原因拒绝执行指定的操作.
对于RCODE字段, www2.cs.duke.edu 提到:
You should set this field to 0, and should assert an error if you receive a response indicating an
error condition. You should treat 3 differently, as this represents the case where a requested name
doesn’t exist.
您应该将此字段设置为0,并且如果收到指示错误情况的响应,则应该声明错误。您应将3区别对待,因为这代表了所请求名称不存在的情况。
QDCOUNT: 一个无符号的16位整数,指定问题部分中的条目数。您应该将此字段设置为1,表示您有一个问题.
ANCOUNT: 一个无符号的16位整数,指定答案部分中的资源记录数。您应该将此字段设置为0,表示您未提供任何答案.
NSCOUNT: 一个无符号的16位整数,用于指定授权记录部分中的名称服务器资源记录的数量. 您应该将此字段设置为0,并且应忽略本节中的任何响应条目.
ARCOUNT: 一个无符号的16位整数,用于指定其他记录部分中的资源记录数. 您应该将此字段设置为0, 并且应忽略本节中的任何响应条目.
2.1 显示过滤器之DNS(域名系统)
使用Wireshark显示过滤器规则,在若干个Wireshark数据分组包筛选出DNS域名是www.taobao.com的数据包, 则使用: dns.qry.name eq www.taobao.com 即可.
2.2 DNS请求报文格式
在Chrome浏览器中输入www.tianmao.com 域名,并同时打开Wireshark网络分析工具开始抓包,使用2.1.1节中的DNS显示过滤器方式筛选出刚才输入的域名,得到结果如下:
第一个分组数据包是DNS请求报文,第二个分组数据包是DNS响应报文,现在对DNS请求报文格式进行拆分剖析.
DNS头部(Header)中各字段以及各字段的位含义(如字段Flags)如上节所述,现对DNS请求报文中的“查询请求”字段,包括其内部结构进行说。如下图绿色框中箭头所指示,该“名字服务器查询请求问题”字段的内部格式由三部分组成,分别是:QNAME、QTYPE和QCLASS。
和Wireshark中抓取到的DNS请求报文格式是一致的,如下图:
Queries:
NAME: 查询名,即本次DNS请求想要查找的域名,如本例中的www.tianmao.com。因此Wireshark中DNS的显示过滤器过滤域名的方式是: dns.qry(query缩写).name eq(contains模糊查找)www.tianmao.com。在该NAME字段下面还有两个字段的附加说明,即域名长度和域名标识符的个数。可以根据DNS的报文结构大致猜测其结构定义形式如下:
typedef struct dns{
char cTranscactionId[0]; //事务ID
char cFlags[16]; //标识码
......
union{
struct{
char queryName[0]; //查询域名
unsigned uqueryType; //查询类型
unsigned uqueryClass; //查询类型
struct{
unsigned uNameLength; //域名长度
unsigned uLabelCount; //域名标识符个数
}attribute;
#define name_length attribute.uNameLength;
#defien label_count attribtute.uLabelCount;
}query;
struct{
......
}answer;
}dns_query_or_answer;
}dns;
复制代码
Name Length: 域名长度.
Label Count: 标识符个数.
对于域名Name,(参考《TCP/IP详解卷一·协议》)它是由一个或多个标识符组成的序列且由字符’\0’作为域名字符串的结束标志,每个标识符的首字节是一个用来说明紧随其后的标识符name的长度值。如下:
用数值来替换域名中的”.”(点号), 然后得到其域名长度15和域名组成的标识符个数3.
TYPE: 每个DNS请求报文中的问题字段值中都有一个查询类型,而对应的(相同事务ID)的DNS想要也有一个响应类型。在DNS报文中,最常用到的type是 A,即表示表示本次DNS查询期望DNS域名服务器返回域名对应的主机IP地址。
CLASS: DNS数据库中的资源记录(与域名、地址记录相关的数据以及域名系统感兴趣的其他数据. 资源记录Resource Record, RR)共划分为四大类,其中Internet是多数用户最为感兴趣的(如下图Wireshark抓包所示);某些类如仅用于MIT;还有一些已经被遗弃不用了.(本段话引自《TCP/IP协议原理与应用》) .
2.3 DNS响应报文格式
这里以前面访问www.tianmao.com 域名得到的DNS域名服务器响应的报文格式为例结合说明。下图是Wireshark抓取到的DNS服务器响应的报文分组数据。
从上面可以看到DNS服务器响应的报文中,对于后面的Answer(回答字段)、Authority(授权字段)和Additional(附加信息)三个字段,均采用的是所谓的“资源记录(Resource Record,RR. 资源记录)”的相同格式。如下图中左下图所示(包含: NAME、TYPE、TYPE、TTL、RDLENGTH和RDATA共6个字段.), 它们一一对应DNS服务器中数据库下某张表的某条记录。
假如DNS服务器上的某种类型数据库下的某个数据库里有张表专门设计用来存储与RR(资源记录)有关的表,该数据表的大概形式(关系型数据库)如下图右小图所示。响应该DNS请求客户端的每一条DNS报文消息中的”Answer”字段里的值都和数据库表中的某条记录是相对应的。
**Name:**所查询的域名,其格式与查询请求中的的QNAME相同.
Type: 类型,此字段指定RDATA字段中数据的含义。必须确保能够请求端能够解析0x0001 (A record) ,或0x0005(CNAME),或0x0002 (name servers),或0x000f (mail servers)。它的值和前面查询请求中的查询类型值一样。
Class: 两个八位字节,用于指定RDATA字段中数据的类别。您应该期望该项目表示Internet地址为0x0001。
Tome to live: 可以缓存结果的秒数.
Data length: RDATA资源记录字段的长度。
Resource Data: 格式取决于类型字段:如果是0x0001的A Record类型,则这是IP地址(4个八位字节)。如果是0x0005的CNAMEs的类型,那么是别名的名称。如果是0x0002的名称服务器的类型,则这是服务器的名称。
如下图所示,对于Answer的第二个响应体,其type是4,表示查询IP地址,则对于IPV4,为4字节大小。而第一个响应体中,Type是CNAME,即“别名记录,用于建立别名”,则其Data Length为别名的长度34字节。
可在/proc 虚拟文件系统的/proc/net目录下,通过查看arp文件而得之当前系统上面的ARP地址缓存信息.(2020-05-14补充)
[root@host-10-254-XX-2 net]# cat arp
IP address HW type Flags HW address Mask Device
10.254.XXX.3 0x1 0x2 fa:16:XX:27:XX:58 * eth0
10.66.XXX.193 0x1 0x2 fa:XX:3e:66:XX:7f * eth1
10.66.XXX.131 0x1 0x2 04:XX:c4:5c:XX:72 * eth1
10.254.XXX.254 0x1 0x2 04:XX:c4:5c:XX:72 * eth0
10.254.XXX.5 0x1 0x2 fa:XX:3e:2e:XX:22 * eth0
10.66.XXX.195 0x1 0x2 fa:XX:3e:f9:XX:be * eth1
10.66.XXX.254 0x1 0x2 50:XX:00:f2:XX:fc * eth1
复制代码
3. DNS应用场景
对于DNS,它可用于一下几个场景:
- i. 将主机名转换为IP地址.
- ii. 将IP地址转换为主机名(这称为反向查询或指针查询).
- iii.在DNS服务器之间传输信息.
- vi. 查找其他名称元素,例如MX记录(邮件交换).
4. DNS实战分析
4.1 DNS数据库
通过实例分析,对DNS的理解会更加透彻。本次使用的是ClouDNS。ClouDNS是欧洲最大的全球托管DNS服务提供商,包括GeoDNS、Anycast DNS和DDoS保护的DNS。该公司实施领先的云服务架构,以实现最高DNS速度和DNS冗余。本次使用的它的最重要原因是因为其提供免(“太”)费(“穷”)的DNS托管。(声明:并非为公司打广告,仅用来学习供参考. 哦对了, 若顺带来了广告收益,请记得分一杯羹给我, hahahaha . . .)
怎么申请属于自己的域名,怎么申请DNS服务器,请求参考 挖站否 . 里面会有详细的文章说明,感兴趣的读者可以尝试。
4.1.1 如何配置名称服务器
Configuring DNS 详细说明了如何配置DNS服务器的过程,以及各名词的含义,都说明的非常清楚。
5. DNS问题排查和解决工具
推荐Linux平台上的排查DNS问题的工具,最常用到的有:dig、nslookup.
Dig (Domain Information Groper, 域信息搜索器),是一个强大的命令行工具,用于查询DNS名称服务器。具体使用方法,可参考 Dig Command in Linux .
nslookup(Name Server lookup, 名称服务器查找)是一种网络管理工具,用于查询域名系统(DNS)以获取域名或IP地址映射或任何其他特定的DNS记录。可参考 nslookup command .