盒子
盒子
文章目录
  1. 前言
  2. DNS 相关介绍
    1. DNS 基本概念
  3. 域名解析全过程
  4. dig 命令
  5. 参考文献

DNS基础

前言

Cracking the code interview 中有一道题:当你在浏览器中输入一个URL,并按下 Enter后都发生了什么?,在 Github 上有一个仓库:what-happens-when-zh_CN 也介绍了在浏览器中输入URL后发生的事情,其中都只是简单地介绍了 DNS 域名解析的过程,但其实域名解析远比这个复杂,因此本文将介绍关于 DNS 的基础知识。

本文演讲PPT请参见:xiazdong.github.io/slides/dns

DNS 相关介绍

DNS 基本概念

DNS(Domain Name System, 域名系统) 是互联网的基础设施,主要负责域名解析,即负责将域名转换成 IP 地址。1983 年由 Paul Mockapetris 设计出来。

域名是一个树状结构构成的,如下图,每个域名对应一个或多个 DNS 服务器,域名解析请求也是从上到下一步一步进行下发的。



下面介绍两个基本概念:

  • Zone: 以上图来说,就是一棵子树。比如”.com”的 Zone 就是以 “.com” 为根的子树。因此 “www.taobao.com” 是在 “.com” 的 Zone 里的。
  • Domain: 树中的一条路径。比如 “taobao.com.” 是 Domain,”www.taobao.com.” 也是 Domain。

从上图可知,域名(Domain)分成很多类:

  • 根域名(Root Domain): 是树状结构的根,在 URL 中对应的是:”.”。全世界一共有13个根域名服务器(每个服务器都是一个集群,通过 Anycast 技术共用一个 IP),这13个根域名服务器的名字分别是 [A-M].root-servers.net,根域名服务器的分布图如下:


  • 顶级域名(Top Level Domain, TLD): 根域名的下一层,URL 中对应例如:”.com”,”.cn”,”.net”。TLD 分成两类:
    • gTLD(generic TLD, 国际顶级域名): 比如 .com, .net
    • ccTLD(Country Code TLD, 国家和地区顶级域名): 比如 .cn, .jp
  • 二级域名(Second Level Domain):这层就是一般我们用钱去 Godaddy 买的域名,比如”taobao.com”。
  • 三级、四级域名…

URL 就是一个由”.”分隔的字符串,总长度必须小于等于255字节,每个分隔的子串必须小于等于63字节。其实完整的每个URL都是以”.”结尾的,比如”www.taobao.com.”,只是现在大家默认都会省去这个点。

为了完成域名解析,不得不介绍一下 Local DNS。

  • 一般上网我们都是设置为 DHCP(Dynamic Host Configuration Protocol)的,Local DNS 是你连上网之后,由网络服务提供商(ISP, Internet Service Provider, 比如移动、连通、电信)自动就近分配(地理位置尽量近以加快域名解析的速度)给计算机的(一般会分配两个,一个主DNS,一个备用DNS),因此 Local DNS 是由 ISP 自己维护的, ISP 还会为计算机分配 IP。如果你想自己设置 DNS 也是可以的(可以是公共 DNS,比如 AliDNS 或 Google 的 8.8.8.8),这样计算机就不使用 Local DNS 了。
  • 因为 Root DNS 的13个 IP 都是公开的,因此一般 Local DNS 会以静态文件的形式内置这13个 Root DNS 的 IP。

Local DNS 是负责帮你完成域名解析的大功臣,你只需要把 DNS 域名解析的报文请求发送给 Local DNS,它会以递归的方式帮你完成一系列的请求解析(因为要不断请求不同层级的 DNS,先从根 DNS 开始,再到 TLD,…),并最终返回给你域名的 IP。 Local DNS 执行流程如下图:




> - 内网 IP: 这是局域网内部的IP地址,输入 ipconfig 看到的是内网IP,比如 “192.168.0.103”。
> - 公网 IP: 这是运营商分配的IP地址,这个地址并不是你电脑独占的,比如我在家里电脑和手机连的是同一个网,那么他们共享同一个公网 IP。在百度里输入 IP,就能看到自己的外网 IP。

查看公网 IP 和 Local DNS 的 IP 的简便方法是访问:阿里的昆仑镜或者腾讯的华佗

> 如果要自己搭一个 DNS 服务器,一般使用 BIND(Berkeley Internet Name Domain)。

### DNS 分类

- 递归 DNS:负责接收域名解析请求,并帮助用户一次又一次递归地请求不同的 DNS 服务器,最后得到 IP 并返回给用户。比如 Local DNS, 公共 DNS。
- 权威 DNS:保存某个域 DNS 解析的权威信息,怎么解析他说了算。 至于哪个 DNS 服务器是权威 DNS,则在上一级的 Zone File 中通过 NS 记录设置。比如为了让 DNSPod 的 “f1g1ns1.dnspod.net”和” f1g1ns2.dnspod.net” 作为 “xiazdong.me” 的权威 DNS,必须要到 Godaddy 中设置 Nameserver(即设置 NS 记录:xiazdong.me NS f1g1ns1.dnspod.net),表明现在 “xiazdong.me” 有两个权威 DNS 服务器。

> 一个 DNS 既可以作为递归 DNS,也可以同时作为权威 DNS,即当 DNS 请求该 DNS 负责的域名时,则进行解析;当 DNS 请求不是他负责的域名时,则作为递归 DNS 使用。

### DNS 攻击

- DNS 劫持(DNS Hijacking or DNS redirection):攻击的人会 劫持 DNS 服务器,并获得管理权限,从而修改映射关系。常见的 DNS 劫持是 DNS 广告劫持,现象是比如你访问”www.taobao.com”,会在页面上弹出一个不相关广告,这是运营商干的,Local DNS 是 ISP 管理的,当你发一个 DNS 域名请求到 Local DNS,他会将 DNS 响应报文中的 IP 改成自己搭的广告服务器的IP,他预先会写一个静态页面在广告服务器,其中 <iframe> 依旧请求原页面,但是区别是多加一些代码用来弹广告。这个解决方法就是投诉。
- DNS 污染(DNS cache poisoning):DNS 服务器的缓存映射被篡改。假设 Root DNS 被污染,那么如果用户请求 “www.taobao.com”,Root DNS 直接返回一个假 IP,让用户访问不了淘宝。如果 Root DNS 都被污染了,那就无解了。因此 DNS 劫持是对 DNS 服务器本身做修改,而 DNS 污染是对 DNS 服务器缓存做修改。
- DDOS(Distributed Deny Of Service, 分布式拒绝服务): 搞一堆肉机,制造大量 DNS 解析请求,大量提升 QPS,导致 DNS 服务器的带宽被塞满,无法为其他用户提供服务。一些常见的解决方法是:黑名单(不对黑名单中 IP 提供 DNS 解析请求服务)、白名单(只对白名单中的 IP 提供 DNS 解析请求服务)。

### DNS Zone File

DNS Zone File(DNS 区域文件)是每个 DNS 服务器都需要有的一个文本文件,用来进行域名解析。一般格式如下:

$ORIGIN example.com. ; designates the start of this zone file in the namespace
$TTL 1h ; default expiration time of all resource records without their own TTL value
example.com. IN SOA ns.example.com. username.example.com. ( 2007120710 1d 2h 4w 1h )
example.com. IN NS ns ; ns.example.com is a nameserver for example.com
example.com. IN NS ns.somewhere.example. ; ns.somewhere.example is a backup nameserver for example.com
example.com. IN MX 10 mail.example.com. ; mail.example.com is the mailserver for example.com
@ IN MX 20 mail2.example.com. ; equivalent to above line, "@" represents zone origin
@ IN MX 50 mail3 ; equivalent to above line, but using a relative host name
example.com. IN A 192.0.2.1 ; IPv4 address for example.com
IN AAAA 2001:db8:10::1 ; IPv6 address for example.com
ns IN A 192.0.2.2 ; IPv4 address for ns.example.com
IN AAAA 2001:db8:10::2 ; IPv6 address for ns.example.com
www IN CNAME example.com. ; www.example.com is an alias for example.com
wwwtest IN CNAME www ; wwwtest.example.com is another alias for www.example.com
mail IN A 192.0.2.3 ; IPv4 address for mail.example.com
mail2 IN A 192.0.2.4 ; IPv4 address for mail2.example.com
mail3 IN A 192.0.2.5 ; IPv4 address for mail3.example.com


解释如下:

- 文件中每行都是一个资源记录(Resource Record,RR),资源记录有很多类型,比如 SOA(Start Of Authority), A(Address), NS(Name Server), MX(Mail eXchange), CNAME(别名,一般出于调度考虑)。
- $ORIGIN example.com.: 这个 Zone File 的 DNS 的域是 “example.com.”
- $TTL 1h: 该文件的记录的最大存活时间是1小时。
- example.com. IN SOA ns.example.com. username.example.com.: “example.com.” 的首选 DNS 服务器是 “ns.example.com.”,管理员邮箱是”username@example.com.”。
- example.com. IN NS ns: “ns.example.com.” 是 “example.com” 的 Nameserver。
- example.com. IN NS ns.somewhere.example.: “ns.somewhere.example.” 是 “example.com” 的另一个 Nameserver。
- example.com. IN MX 10 mail.example.com.: “mail.example.com.” 是 “example.com.” 的邮件服务器,优先级是10(优先级数字越小,则优先级越高)。MX 表示 Mail eXchange。
- @ IN MX 20 mail2.example.com.: 也是设置邮件服务器,优先级是20。
- @ IN MX 50 mail3: “mail3.example.com.” 是 “example.com” 的邮件服务器,优先级是50。
- example.com. IN A 192.0.2.1: “example.com” 的 IPv4 地址是 “192.0.2.1”。
- IN AAAA 2001:db8:10::1: “example.com” 的IPv6 地址是 “2001:db8:10::1”。
- ns IN A 192.0.2.2: “ns.example.com.” 的 IPv4 地址是 “192.0.2.2”。
- www IN CNAME example.com.: “www.example.com.” 是 “example.com” 的别名。
- wwwtest IN CNAME www: “wwwtest.example.com.” 是 “www.example.com.” 的别名。
- mail IN A 192.0.2.3: “mail.example.com” 的 IPv4 地址是 “192.0.2.3”。
- mail2 IN A 192.0.2.4: “mail2.example.com” 的 IPv4 地址是 “192.0.2.4”。
- mail3 IN A 192.0.2.5: “mail3.example.com” 的 IPv4 地址是 “192.0.2.5”。

那么 CNAME 能不能被 A 替代呢?答案是不能,主要是看需求。因为:

- 定义不同: A 记录对应的是 IP,CNAME 对应的是 URL,他只是域名解析的中间结果,因此 CNAME 引入了中间态。
- 应用场景不同: 如果我想把某个域名指向 google.com,而 google.com 有很多 IP 地址,而且可能随时会更换,因此最好的方式是通过 CNAME 指向 google.com,而不是用 A 记录指向 google.com 对应的一个 IP 地址。

一般来说,一个域名的 DNS 服务器会有很多台,会以 Master-Slave 的形式部署,而每台 Master 或 Slave 都会有 Zone File,Slave 会通过 AXFR(全量传输), IXFR(增量传输) 或 Notify 的方式同步 Master 的 Zone File。如下图:



从上面这张图看出:Remote Admin 是 DNSPod 提供的操作界面,当你修改了记录后,他会同步到 Master 的 Zone File 中,并通知 Slave 更新。

DNSPod 的权威 DNS 是”f1g1ns1.dnspod.net”和” f1g1ns2.dnspod.net”,我的博客”xiazdong.me”的权威 DNS 设置成了这两个 URL,为了让这个权威 DNS 生效,我需要去申请域名的平台(Godaddy)将 DNS NameServer 设置为这两个 URL,这样才能够生效,一般来说 Master DNS 服务器和 Slave DNS 服务器都是权威 DNS。如果你在 DNSPod 平台上修改 A 记录,那么会把修改同步到 Master DNS 服务器,Slave 再通过某种方式同步 Master 的 Zone File。

域名解析全过程

比如你在 Chrome 中输入 “www.taobao.com”,并按下回车,域名解析会进行如下步骤:

  1. 查看浏览器 DNS 缓存。Chrome 可以通过 chrome://net-internals/#dns 查看浏览器的 DNS 缓存,一般这些缓存的 TTL(Time To Live) 是几分钟。
  2. 查看系统 DNS 缓存。 Windows 可以通过 ipconfig /displaydns 查看系统 DNS 缓存。这里面包含了 hosts 文件设置的映射,有时候修改了 hosts 文件后,为了让 hosts 文件生效,需要执行 ipconfig /flushdns
  3. 查看路由器 DNS 缓存。
  4. 查看 Local DNS 的 DNS 缓存。这部分缓存是由 ISP 自己实现,有些 ISP 为了减少域名解析次数,会将缓存的 TTL 特意变长一点,比如原来 TTL=10min,但是 ISP 自己实现的时候,设置缓存的时间是30min。这也会导致你更改了 DNS 服务器的 A 记录后不能马上生效的原因。
  5. 如果这些缓存都没有域名对应的IP,那么 Local DNS 会帮你递归地开始进行域名解析。
    • 因为在 Local DNS 中内置了 13个 Root DNS 的 IP,因此任意选择一个 Root DNS 的 IP 发起 DNS 解析请求报文,当 Root DNS 收到 Local DNS 的请求后,会发现这个 URL 的顶级域名是 “.com”,因此他会把 “.com” 的 DNS 服务器的 IP(通常会发13个 “.com” 的服务器的 IP)发送给 Local DNS 作为响应。
    • Local DNS 收到 Root DNS 的响应后,会继续把请求发送给 “.com” 的 DNS 服务器(它的 IP 从 Root DNS 的响应中获得),”.com” 的 DNS 服务器收到请求后,会发现这个 URL 的二级域名是 “taobao.com”,因此会把 “taobao.com” 的 DNS 服务器的 IP(通常也会有多个)发送给 Local DNS 作为响应。
    • Local DNS 收到 “.com” DNS 的响应后,会继续把请求发送给 “.taobao.com” 的 DNS 服务器(它的 IP 从 “.com” DNS 的响应中获得),”taobao.com” 的 DNS 服务器收到请求后,会发现这个 URL 的子域名是 “www.taobao.com”,那么会把 “www.taobao.com” 的 DNS 服务器的 IP 发送给 Local DNS 作为响应。当然这里可能会有一个问题,因为”www.taobao.com”会有多个IP对应,那么到底返回哪个IP呢?一般 DNS 会有调度原则,实现方法是:DNS 服务器会内置一个 IP 库,会根据请求源的 IP(Local DNS 的 IP) 确定他的国家、地区、运营商,因此会返回就近的 IP,这就实现了就近调度。一般 CDN(Content Delivery Network, 内容分发网络, 主要存储静态文件如 CSS, JS)的实现原理就是这样。
    • Local DNS 收到了 “www.taobao.com” 的 IP,也就完成了任务,他会把这个 IP 送回给计算机。
  • 域名请求和响应是以 UDP 协议发送的。
  • RTT(Round Trip Time): 一次请求+响应的时间。
  • TTL(Time To Live): 当 DNS 服务器返回 IP 时,会带有 TTL,表示这个映射你能缓存的时间,比如 TTL=10min,那么这个映射关系只能缓存10分钟,10分钟之后就过期了。但是 ISP 的 Local DNS 可能并不会那么听话,他可能会缓存半个小时。

在无线端的域名解析,需要提几点:

  • 在开发移动应用时,为了节省域名解析的时间,采用”IP直连“的方式,即在应用中内置可能会用到的域名的 IP(比如手机淘宝可能会访问的域名其实都是可预料的),这样就省去了域名解析的时间(一般解析时间在200ms-400ms)。
  • 由于 Local DNS 运维水平参差不齐,可能会出现 DNS 劫持、ISP 分配给用户的 Local DNS 不在一个地区,又因为一个应用可能会访问的域名是固定的,因此大公司都会自己实现一套异步的 DNS 解析,比如腾讯的 HttpDNS。

HttpDNS 的实现思路是:

  • 开辟一个线程,从应用启动后定期地发起 HttpDNS 的域名解析请求(同时可以请求解析多个域名)到 HttpDNS 服务器(定期发起请求是因为怕 IP 过期),该请求走 HTTP 协议,然后 HttpDNS 服务器把 HTTP 请求转换成 DNS 请求,并对后端的 DNS 服务器进行 DNS 域名解析请求,当解析完成后,会将请求域名的 IP 地址送回给客户端,并缓存起来。
  • 当应用发起网络请求,会首先看 HttpDNS 的缓存中是不是存在已经解析好的 IP 地址,如果有,则直接拿来用(这里可能会出现 IP 过期,也需要降级走 Local DNS);如果没有,则降级走 Local DNS。

dig 命令

上一节已经介绍了 DNS 域名解析的基本流程,本节我们通过 Linux 中的 dig(Domain Information Groper) 命令来验证这个解析流程。以 dig +trace www.taobao.com 为例。

输出如下:

; <<>> DiG 9.8.3-P1 <<>> +trace taobao.com
;; global options: +cmd
. 84725 IN NS l.root-servers.net.
. 84725 IN NS j.root-servers.net.
. 84725 IN NS c.root-servers.net.
. 84725 IN NS f.root-servers.net.
. 84725 IN NS i.root-servers.net.
. 84725 IN NS k.root-servers.net.
. 84725 IN NS h.root-servers.net.
. 84725 IN NS e.root-servers.net.
. 84725 IN NS m.root-servers.net.
. 84725 IN NS a.root-servers.net.
. 84725 IN NS g.root-servers.net.
. 84725 IN NS b.root-servers.net.
. 84725 IN NS d.root-servers.net.
;; Received 505 bytes from 10.65.0.1#53(10.65.0.1) in 159 ms
;上面这些数据是从 /etc/resolv.conf 中指定的 DNS 服务器获得的13个根域名服务器的 IP 地址和名称。
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
com. 172800 IN NS c.gtld-servers.net.
com. 172800 IN NS d.gtld-servers.net.
com. 172800 IN NS e.gtld-servers.net.
com. 172800 IN NS f.gtld-servers.net.
com. 172800 IN NS g.gtld-servers.net.
com. 172800 IN NS h.gtld-servers.net.
com. 172800 IN NS i.gtld-servers.net.
com. 172800 IN NS j.gtld-servers.net.
com. 172800 IN NS k.gtld-servers.net.
com. 172800 IN NS l.gtld-servers.net.
com. 172800 IN NS m.gtld-servers.net.
;; Received 488 bytes from 128.63.2.53#53(128.63.2.53) in 275 ms
;上面这些数据是从13个根域名服务器的其中一个(IP 地址 128.63.2.53)获得 ".com" 的 DNS 服务器的 IP 地址和名称。
taobao.com. 172800 IN NS ns4.taobao.com.
taobao.com. 172800 IN NS ns5.taobao.com.
taobao.com. 172800 IN NS ns6.taobao.com.
taobao.com. 172800 IN NS ns7.taobao.com.
;; Received 180 bytes from 192.26.92.30#53(192.26.92.30) in 279 ms
;上面这些数据是从13个".com" DNS 服务器的其中一个(IP 地址 192.26.92.30)获得 "taobao.com" 的 DNS 服务器的 IP 地址和名称。
taobao.com. 1800 IN A 110.75.115.70
taobao.com. 10800 IN NS ns7.taobao.com.
taobao.com. 10800 IN NS ns5.taobao.com.
taobao.com. 10800 IN NS ns4.taobao.com.
taobao.com. 10800 IN NS ns6.taobao.com.
;; Received 196 bytes from 110.75.38.29#53(110.75.38.29) in 3 ms
;上面这些数据是从4个"taobao.com"的 DNS 服务器的其中一个(IP 地址为 110.75.38.29)获得 "taobao.com" 的 IP 地址:110.75.115.70。

参考文献

支持一下
扫一扫,支持xiazdong