浅尝DNS原理及其应用

一、DNS 是什么?

概念简介

网络上的所有主机,从只能手机到笔记本电脑个人PC到为大量零售网站提供内容服务的服务器,都是通过IP的形式定位找到彼此并互相通信。然而IP地址对于人类来说比较不易于记忆且复杂,所以当我们打开浏览器浏览网站时,我们不再需要通过这些冗长复杂的IP进行访问,而是通过像 example.com 这样的域名就可以连接到正确的主机位置。

使用DNS进行访问控制有以下好处:

  1. 可以对服务进行一定效果的负载均衡;
  2. 对请求进行分地区的容灾管理、访问控制等;
  3. 便于人们记忆。

当然,任何事物都会有他的两面性,DNS的主要问题可能有:

  1. 请求容易被运营商劫持,最终就会导致访问A网站时因为劫持的存在访问请求到了B;
  2. 因为local dns(下文会提及)的存在,会导致修改域名记录后修改记录无法及时生效,需要等待TTL过期后修改才能正确影响用户请求;

查询过程

DNS 递归查询过程

协议格式 DNS协议运行在UDP/TCP协议之上,使用端口号53。

一个Message的基本组成:

代码语言:javascript
复制
    +---------------------+
    |        Header       |
    +---------------------+
    |       Question      | the question for the name server
    +---------------------+
    |        Answer       | RRs answering the question
    +---------------------+
    |      Authority      | RRs pointing toward an authority
    +---------------------+
    |      Additional     | RRs holding additional information
    +---------------------+

(1)Header(头部)

代码语言:javascript
复制
                                    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,Request ID 与 Response ID 保持一致
  • QR(1bit):查询/响应的标志位,1为响应请求,0为查询请求
  • Opcode(4bit):定义查询或响应的类型(0为标准的,1为反向的,2为服务器状态请求,3-15保留值)
  • AA(1bit):授权回答的标志位。该位在响应报文中有效,1表示域名服务器是权限服务器
  • TC(1bit):截断标志位。1表示响应已超过512字节并已被截断
  • RD(1bit):被请求报文设置,该位为1表示客户端希望得到递归回答,应答时使用相同的值返回。
  • RA(1bit):支持递归, 这个比特位在应答中设置或取消,用来代表服务器是否支持递归查询。
  • Z(3bit):保留字段。
  • RCODE(4bit):返回码,表示响应的差错状态,通常为0和3,各取值含义如下: 0 无差错 1 报文格式差错(Format error)服务器不能理解的请求报文 2 服务器失败(Server failure)因为服务器的原因导致没办法处理的请求 3 名字错误(Name error) 只有对授权域名解析服务器有意义,指出解析的域名不存在 4 没有实现(Not Implemented)域名服务器不支持的查询类型 5 拒绝(Refused)服务器由于设置的策略据局给出应答 6 - 15 保留值
  • QDCOUNT(16bit):问题数,无符号16位整数表示报文请求段中的问题记录数。
  • ANCOUNT(16bit):应答数,无符号16位整数表示报文回答段中的回答记录数。
  • NSCOUNT(16bit): 授权资源记录数,无符号16位整数表示报文授权段中的授权记录数。
  • ARCOUNT(16bit):附加资源记录数,无符号16位整数表示报文附加段中的附加记录数。

(2)Question(查询问题区域)

代码语言:javascript
复制
                                    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:查询名,查询长度不定,域名的每一“小段”通过整型进行截断并记录段长。如www.baidu.com,格式如下:

6

w

w

w

5

b

a

i

d

u

3

c

o

m

0

  • QTYPE(16bit):查询类型。一般为A,支持的选项有:A (1)、CNAME (5)、PTR (12)、HINFO (13)、MX (15)、AXFR (252)、ANY (255)。
  • QCLASS(16bit):表示查询的协议类,IN (1) 指互联网地址。

(3)Answer(回答区域)

代码语言:javascript
复制
                                    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                     /
    /                                               /
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
  • NAME:域名,长度变长,格式与上述QNAME保持一致。
  • TYPE(16bit):RDATA记录类型,取值与查询问题区域QTYPE一致。
  • CLASS(16bit):表示查询的协议类,与查询问题区域QCLASS相同。
  • TTL(16bit):Time To Live,记录过期时间。DNS查询记录会被缓存TTL长度的时间。
  • RDLENGTH(16bit):RDATA字段的长度。
  • RDATA:资源记录值,长度为RDLENGTH。比如查询 baidu.com 的DNS记录,那么这里的取值可能会是 39.156.69.79。

(4)抓包

请求包

DNS 查询抓包(1)

结果回包

DNS 查询抓包(2)

二、DNS记录类型

资源记录是用于答复DNS客户端请求的DNS数据库记录,每一个DNS服务器包含了它所管理的DNS命名空间的所有资源记录。资源记录包含和特定主机有关的信息,如IP地址、提供服务的类型等等。常见的资源记录类型有:SOA(起始授权结构)、A(主机)、AAAA(IPV6主机)、NS(名称服务器)、CNAME(别名)和MX(邮件交换器)。

我们可以通过 dig 命令快速获取域名的解析情况。

A

  • A记录 又称IP指向,用户可以在此设置子域名并指向到自己的目标主机地址上,从而实现通过域名找到服务器。说明:指向的目标主机地址类型只能使用IP地址;
代码语言:javascript
复制

 $ dig 689259.p23.tc.cdntip.com

; <<>> DiG 9.9.4-RedHat-9.9.4-29.el7_2.2 <<>> 689259.p23.tc.cdntip.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63346
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;689259.p23.tc.cdntip.com. IN A # 要查询的记录类型

;; ANSWER SECTION:
689259.p23.tc.cdntip.com. 180 IN A 58.251.150.72 # 域名的A记录
689259.p23.tc.cdntip.com. 180 IN A 58.251.150.80 # 域名的A记录

;; Query time: 63 msec
;; SERVER: 10.112.65.55#53(10.112.65.55)
;; WHEN: Mon Jan 20 19:42:36 CST 2020
;; MSG SIZE rcvd: 85

AAAA

  • 类似A记录,不过AAAA是IPV6版本的。

CNAME

  • CNAME 通常称别名指向。您可以为一个主机设置别名。比如设置test.mydomain.com,用来指向一个主机www.rddns.com那么以后就可以用test.mydomain.com来代替访问www.rddns.com了。
代码语言:javascript
复制
$ dig jwlchina.cn CNAME

; <<>> DiG 9.9.4-RedHat-9.9.4-29.el7_2.2 <<>> jwlchina.cn CNAME
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41582
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;jwlchina.cn. IN CNAME # 要查询的记录类型

;; ANSWER SECTION:
jwlchina.cn. 555 IN CNAME jwlchina.cn.cdn.dnsv1.com. # 别名域名

;; Query time: 11 msec
;; SERVER: 10.112.65.55#53(10.112.65.55)
;; WHEN: Mon Jan 20 20:06:22 CST 2020
;; MSG SIZE rcvd: 79

MX

  • MX记录 邮件交换记录。用于将以该域名为结尾的电子邮件指向对应的邮件服务器以进行处理。如:用户所用的邮件是以域名mydomain.com为结尾的,则需要在管理界面中添加该域名的MX记录来处理所有以@mydomain.com结尾的邮件。
代码语言:javascript
复制
$ dig jwlchina.cn MX

; <<>> DiG 9.9.4-RedHat-9.9.4-29.el7_2.2 <<>> jwlchina.cn MX
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34364
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;jwlchina.cn. IN MX # 要查询的记录类型

;; ANSWER SECTION:
jwlchina.cn. 600 IN MX 7 mxdomain.qq.com. # 委托指向的DNS服务器

;; Query time: 88 msec
;; SERVER: 10.112.65.55#53(10.112.65.55)
;; WHEN: Mon Jan 20 20:05:52 CST 2020
;; MSG SIZE rcvd: 71

NS

  • NS记录 解析服务器记录。用来表明由哪台服务器对该域名进行解析。
代码语言:javascript
复制
$ dig jwlchina.cn NS

; <<>> DiG 9.9.4-RedHat-9.9.4-29.el7_2.2 <<>> jwlchina.cn NS
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53303
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;jwlchina.cn. IN NS # 要查询的记录类型

;; ANSWER SECTION:
jwlchina.cn. 86400 IN NS f1g1ns2.dnspod.net. # 域名解析服务器地址
jwlchina.cn. 86400 IN NS f1g1ns1.dnspod.net. # 域名解析服务器地址

;; Query time: 24 msec
;; SERVER: 10.112.65.55#53(10.112.65.55)
;; WHEN: Mon Jan 20 20:06:45 CST 2020
;; MSG SIZE rcvd: 94

SOA

  • SOA叫做起始授权机构记录,NS用于标识多台域名解析服务器,SOA记录用于在众多NS记录中那一台是主服务器。
  • SOA 记录表示此域名的权威解析服务器地址。 当要查询的域名在所有递归解析服务器中没要域名解析的缓存时,就会回源来请求此域名的SOA记录,也叫权威解析记录。

三、EDNS

(1)什么是EDNS?

EDNS就是在遵循已有的DNS消息格式的基础上增加一些字段,来支持更多的DNS请求业务。

需要注意的是,像DNS服务器这样一个大型且广泛应用的系统软件,新增加扩展协议的时候一定要考虑到向后兼容性(backward compatibility),即你增加了你这个特性的消息传输给未支持该特性的服务器时,后者依然能正确处理。

(2)为什么要有EDNS?

RFC2671中指出EDNS被提出来的几个理由:

1)DNS协议头部的第二个16字节中都已经被用的差不多了,需要添加新的返回类型(RCODE)和标记(FLAGS)来支持其他需求;

2)只为标示domain类型的标签分配了两位,现在已经用掉了两位(00标示字符串类型,11表示压缩类型),后面如果有更多的标签类型则无法支持;

3)当初DNS协议中设计的用UDP包传输时包大小限制为512字节,现在很多主机已经具备重组大数据包的能力,所以要有一种机制来允许DNS请求方通知DNS服务器让其返回大包;

以后我们会看到,DNSSEC机制和edns-client-subnet机制等都需要有EDNS的支持。

(3)EDNS的内容是什么?

怎样在DNS消息协议的基础上再增加一些字段呢?为了保持向后兼容性,更改已有的DNS协议格式是不可能的,所以只能在DNS协议的数据部分中做文章。

所以,EDNS中引入了一种新的伪资源记录OPT(Resource Record),之所以叫做伪资源记录是因为它不包含任何DNS数据,OPT RR不能被cache、不能被转发、不能被存储在zone文件中。OPT被放在DNS通信双方(requestor和responsor)DNS消息的Additional data区域中。

(4)OPT伪资源记录中的内容有哪些呢?

OPT pseudo-RR中的内容包含固定部分和可变部分。它的结构如下:

代码语言:javascript
复制
       +------------+--------------+------------------------------+
| Field Name | Field Type | Description |
+------------+--------------+------------------------------+
| NAME | domain name | MUST be 0 (root domain) |
| TYPE | u_int16_t | OPT (41) |
| CLASS | u_int16_t | requestor's UDP payload size |
| TTL | u_int32_t | extended RCODE and flags |
| RDLEN | u_int16_t | length of all RDATA |
| RDATA | octet stream | {attribute,value} pairs |
+------------+--------------+------------------------------+

                           OPT RR Format</code></pre></div></div><figure class=""><div class="rno-markdown-img-url" style="text-align:center"><div class="rno-markdown-img-url-inner" style="width:100%"><div style="width:100%"><img src="https://cdn.static.attains.cn/app/developer-bbs/upload/1723212281678568615.png" /></div></div></div></figure><p>需要注意的是,每个DNS 消息中只能有一个OPT伪资源记录,当有多中EDNS扩展协议时,各个{attribute, value}对一个紧接一个存储在RDATA中。具体可以看下面这个例子:</p><p>对 jwlchina.cn 这个域名进行dig域名,并且访问的客户端IP为2.2.2.2(client subnet),则客户端会发送以下请求包。执行的命令如下:</p><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>javascript</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-javascript"><code class="language-javascript" style="margin-left:0">$ dig jwlchina.cn @119.29.29.29 +client=67.220.91.30

; <<>> DiG 9.9.3 <<>> jwlchina.cn @119.29.29.29 +client=67.220.91.30
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24076
;; flags: qr rd ra; QUERY: 1, ANSWER: 7, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; CLIENT-SUBNET: 67.220.91.30/32/24
;; QUESTION SECTION:
;jwlchina.cn. IN A

;; ANSWER SECTION:
jwlchina.cn. 600 IN CNAME jwlchina.cn.cdn.dnsv1.com.
jwlchina.cn.cdn.dnsv1.com. 600 IN CNAME 689259.p23.tc.cdntip.com.
689259.p23.tc.cdntip.com. 180 IN A 220.194.87.190
689259.p23.tc.cdntip.com. 180 IN A 58.251.150.72
689259.p23.tc.cdntip.com. 180 IN A 14.204.144.140
689259.p23.tc.cdntip.com. 180 IN A 42.56.79.189
689259.p23.tc.cdntip.com. 180 IN A 113.59.43.98

;; Query time: 13 msec
;; SERVER: 119.29.29.29#53(119.29.29.29)
;; WHEN: Tue Feb 04 21:05:53 CST 2020
;; MSG SIZE rcvd: 206

client subnet 查询是一个非常有用的edns功能,可以查询任意IP子网段对应的DNS记录结果。

edns 查询抓包

四、DNS ANYCAST

(1)anycast 是什么?

anycast是多个主机使用相同ip地址的一种技术,当报文发给该地址时,根据路由协议,选择最近(跳数最少)的主机服务。

因此,当某台主机服务量大,或者被攻击,到该主机的距离变长,使得报文被发送给另外的主机。

所以,在服务器数量足够多的前提下,anycast天然支持负载均衡和抵抗ddos攻击。

简而言之,anycast就是不同服务器用了相同的ip地址,达到就近访问的效果。

(2)技术原理

  1. Multicast(多播):它是指网络中一个节点发出的信息被多个节点收到。实际上,在数据链路层和网络层都有Multicast,通常所说的Multicast大多是针对IP的。这种技术用于多媒体应用、多用户交互(如聊天室)、软件分发等,相比与传统的Unicast可以大大提高效率。在子网内实现 Multicast 较为简单,跨越子网时需要路由器、网关等设备的支持。
  2. Unicast(单播):在客户端与媒体服务器之间需要建立一个单独的数据通道,从一台服务器送出的每个数据包只能传送给一个客户机,这种传送方式称为单播。指网络中从源向目的地转发单播流量的过程。单播流量地址唯一。每个用户必须分别对媒体服务器发送单独的查询,而媒体服务器必须向每个用户发送所申请的数据包拷贝。这种巨大冗余首先造成服务器沉重的负担,响应需要很长时间,甚至停止播放;管理人员也被迫购买硬件和带宽来保证一定的服务质量。文字单播方式下,只有一个发送方和一个接收方。与之比较,组播是指单个发送方对应一组选定接收方。
  3. Anycast中文称为任意播。集Multicast和Unicast的特性于一身
  • 从宏观上来说,Anycast类似于Multicast,同一种类型的数据流同时存在多个接收者。
  • 从微观上来说,Anycast又有着Unicast的唯一性。每一个单独的IP会话都能够找到唯一的源主机和目标主机。

AnyCast 不同源节点的路由选择

(3)实际应用

DNSPOD Public Dns 地址 119.28.28.28 使用的就是 anycast 技术。

该地址同时支持 edns-client-subnet 技术,精准调度,多地集群容灾,面向所有互联网用户免费使用。

介绍详情:https://www.dnspod.cn/Products/Public.DNS

五、HTTPDNS

移动解析(HTTPDNS)基于Http协议向DNS服务器发送域名解析请求,替代了基于DNS协议向运营商Local DNS发起解析请求的传统方式,可以避免Local DNS造成的域名劫持和跨网访问问题,解决移动互联网服务中域名解析异常带来的困扰。

使用 HTTPDNS 有以下优点:

  1. 当HTTPDNS解析节点覆盖足够多足够广泛的前提下,可以更快速更高效地进行解析访问,避开了 Local Dns 跨网访问、解析异常等问题;
  2. 使用HTTPDNS可以由客户端自身去控制DNS解析的行为,在故障时可以有效地快速切换解析,避免等待漫长的TTL 缓存时间;
  3. 可以有效地防止运营商 Local Dns 劫持;
  4. 可以更精准地识别访问来源运营商,提供更加精准的访问调度策略,进行提升 网站/应用 的访问响应速度。

当然,HTTPDNS 本身并不是万能的,他也会潜在一些缺点:

  1. 在网络环境较好的情况下,HTTPDNS 基于TCP协议,相较于传统的 DNS 解析使用的 UDP 协议,HTTPDNS 解析时延可能会更高;
  2. HTTPDNS 需要针对客户端逻辑进行改造,在开发上可能没有原生 DNS 解析来的方便快速。

参考