对于 DNS 协议,你可能想知道以下几个问题:
DNS 是啥
DNS 服务器有哪些
DNS 查询方式有哪些
DNS 缓存如何提升性能
DNS 协议格式长啥样
DNS 有哪些安全问题
DNS 的应用场景有哪些
DNS 的工具有哪些
DNS 协议简单说就是为了 将用户可读的域名转换为 IP 地址 。域名就是 IP 地址的代号,为什么互联网会有域名这一说法,主要是为了方便记忆,也为了掩盖对象本身的真实信息,使信息对用户透明,比如在周星驰的电影《唐伯虎点秋香》中,9527 就是唐伯虎的的代号。
为了根据域名得到 IP 地址,需要建立一个域名和 IP 地址之间的映射关系,简单点就是用一个文件来完成,这种叫 静态映射 ,复杂点就是用专门的服务器来完成,这种叫 动态映射 ,提供动态映射服务的服务器就叫 DNS 服务器 。
windows 用户比较熟悉的静态映射方法就是通过 hosts 文件,位置在 C:\Windows\System32\drivers\etc\hosts,只要在 hosts 文件中写上你想访问的域名和地址,系统内置的 DNS 解析器会优先解析,不会访问 DNS 服务器。Linux 下是 /etc/hosts。
由于存在单点故障,DNS 服务器不可能设计成集中式的,由于需要解析的域名信息众多且复杂,DNS 服务器必须足够多,为了方便管理,DNS 服务器最后呈现的是 具有层次结构的大型分布式集群系统 。如下图所示:
总体形成一个分级的树状体系,每个节点为一个 DNS 服务器,每个节点都有自己的 IP 地址。每一层的角色不一样,从上到下分别表示:
根域名服务器(Root Domain):用 · (句点)表示,根域名服务器全球的数量是固定的,为 13 个(当然这里的“个”是“组”的意思),至于为什么是 13 个?见文末的解释。
顶级域名服务器(Top-Level Domain, TLD):指代某个国家/地区或组织使用的类型名称,如 com、cn、edu 等。
次级域名服务器(Second-Level Domain, SLD):个人或组织在 Internet 上注册的名称,如 qq.com、gitHub.com 等
三次域名服务器或权威域名服务器(如果有):这层严格来说是次级域名的子域,是二层域名派生的域名,通俗说就是网站名,如 cs.berkeley.edu
主机名(如果有):主机名称标签,通常在 DNS 域名最左侧,标识网络上的特定计算机,如 www.berkeley.edu
附:13 个根服务器的配置文件:https://www.internic.net/domain/named.root
DNS 服务器有一个区域的概念。由于 DNS 服务器要为全球的用户提供查询和数据库的服务,对计算、存储、网络带宽都要求很高,所以就必须组织成域名服务器集群,使它们协同工作,共同提供域名解析服务。每个集群就负责管理相应的域名名字空间,也就是说每个集群负责不同的 DNS 区域(DNS Zone) 。比如每个根域名服务器节点指向的下一级就是它管理的 DNS 区域,同样再往下,cn 顶级域名服务器节点下面就管理中国区的 DNS 区域。
通过这种区域管理的方法,就很容易进行 DNS 查询。每一级的 DNS 区域域名服务器会保存下一级的 DNS 区域域名服务器的信息,如果从根域名服务器出发,一级级的往下查找,就可以得到目标域名对应的 IP 信息。
可能你会有问题,怎么找到根域名服务器呢?
上面已经提到过,全球的根域名服务器总的只有 13个,这 13 个的信息都是公开的,也就是说每一个用户的出口 DNS 服务器上都有这些根域名服务器的已知信息。有了这些信息,查找就不是问题了。
除了以上所列的 DNS 服务器,严格来说还有三种 DNS 服务器角色不容忽视。一种是本地 DNS 服务器,一种是 ISP DNS 服务器,还有一种是公共 DNS 服务器。
一个大概的图示如下所示:
本地 DNS 服务器 ,特指内网的 DNS 服务器,提供内网主机之间的域名查询服务,一般作为缓存/转发之用,当在该服务器上找不到相应域名时,它会将请求转发到上级 DNS 服务器作进一步查询。它会依赖于两个文件,以 Linux 为例,就是 /etc/hosts
和 /etc/resolv.conf
,前者记录了内网主机 hostname 和 IP 之间的映射关系,后者记录了外网的 DNS 服务器地址。
当本地 DNS 服务器在 /etc/hosts
和自身的缓存中都找不到相应的域名时,就会从 /etc/resolv.conf
中记录的地址进行进一步查询。
这个角色也可以用软件的形式来实现,我们常见的 Linux操作系统中内置的 DNS 域名解析模块(DNS Resolver)或者类似 Dnsmasq 这种软件都可以完成。
ISP DNS 服务器 ,如果你的电脑是连接到运营商(ISP)的网络,那么外网 DNS 服务器就是指代的 ISP DNS 服务器。ISP DNS 服务器相比本地 DNS 服务器,多了递归和迭代向各分级 DNS 服务器查询的功能。
公共 DNS 服务器 ,如果不想通过 ISP 的 DNS 服务器查询,也可以向公共的 DNS 服务器去查询。现在很多公共的 DNS 服务器,相信大家应该很熟悉了,随便列几个:
# Google 提供公共 DNS:
8.8.8.8 # 主
8.8.8.4 # 备
# 国内三大运营商提供的公共 DNS:
114.114.114.114
114.114.115.115
# 阿里提供的
223.5.5.5
223.6.6.6
# 百度提供的:
180.76.76.76
当然,在实际中,我们也经常看到,这三种服务器角色都可以看做是一个整体,没有那么严格地区分。
下面我们就来具体看看具体的查询过程是什么样的。
DNS 查询有两种方法,一种是 递归查询 ,一种是 迭代查询 。
递归查询就是一层接一层地去查询,直到查询到最终的结果之后才返回。如下图所示:
迭代查询就是每一层查询完之后都会返回,返回的结果是下一层 DNS 服务器的地址,根据返回的结果,接着去查询下一层,直到查询到最终的结果为止,如下图所示:
实际中,根域名服务器和其他的 TLD 服务器,它们不执行递归查询,因为这些服务器是相当宝贵的资源,需要为全球的用户提供 DNS 解析服务,执行 DNS 递归查询会导致全球互联网性能不佳。
所以,通常这两种查询方式是一起用的,本地 DNS 服务器和 ISP DNS 服务器可以执行递归查询,而其他层级 DNS 服务器执行迭代查询,对照上面的图:
我们总结整个查询过程如下:
本地终端发出域名解析请求,到本地 DNS 服务器(如果是 web 请求,会先查看浏览器缓存)
本地 DNS 服务器首先查看自身缓存,如果不存在则向 ISP DNS 服务器发出查询请求
ISP DNS 服务器同样先查看缓存,不存在再向众所周知的全球 13 台根服务器发出请求
根 DNS 服务器收到请求后会判断该域名(比如.com)由谁授权管理,返回管理这个域名的顶级 DNS 服务器的 IP,给到 ISP DNS 服务器
ISP DNS 服务器根据返回的 IP 继续请求顶级 DNS 服务器
该顶级 DNS 服务器收到请求后,如果自己无法解析,也会判断对应域名(比如qq.com)由下一级的哪个 DNS 服务器授权管理,并将该次级 DNS 服务器的 IP 发给 ISP DNS 服务器。
ISP DNS 服务器继续根据返回的 IP 请求次级 DNS 服务器
次级 DNS 服务器如果解析出对应的域名(比如 www.qq.com),就将该域名对应的 IP 返回给 ISP DNS 服务器,如果没有,就继续重复上述动作。
ISP DNS 服务器缓存一份域名与 IP 的映射关系,并将结果返回给本地 DNS 服务器
本地 DNS 服务器同样会缓存一份,然后将结果给到请求的终端,完成本次查询。
我们都知道大名鼎鼎的 80/20 原则,用在网站访问上就是 80% 的时间我们都在看那些 20% 的网站 。
所以,如果把常用的信息缓存起来,那么后面的请求将会大大缩短访问时间。对于 DNS 请求来说,如果中间的 DNS 服务器都设有缓存,缓存那些经常会用到的域名信息,那将大大提高 DNS 的解析效率。
在 DNS 查询解析的过程会用到的 DNS 缓存有:
浏览器缓存:当用户通过浏览器访问某域名时,浏览器首先会在自己的缓存中查找是否有该域名对应的IP地址
系统缓存:一般 DNS Resolver 模块通常设有 DNS cache,hosts 文件也可以看做是缓存
本地 DNS 缓存(如果有):这里特指硬件服务器,和系统缓存对应
路由器缓存:一般现在的出口路由器也会设有 DNS 缓存,当以上都查询不到,会在路由器缓存中查询
ISP DNS 缓存:ISP 网络提供的 DNS 服务器缓存。
根域名/顶级域名/次级域名等缓存
当完成一次完整的查询之后,中间的 DNS 服务器缓存会将返回的结果一次存放入自己的缓存中,以备下次使用。
DNS 缓存当然能够加快 DNS 查询的效率,但有时也会影响网络问题排查。这个时候需要将 DNS 缓存清除,清除的方法如下:
对于 Windows 系统,在命令行输入 ipconfig /flushdns
即可
对于 Linux 系统,看有没有使用 dnsmasq
之类的缓存服务器,如果使用的话,只需重启缓存服务即可,如重启 dnsmasq
服务:sudo systemctl restart dnsmasq.service
,如果没有使用,则根据各大 Linux 发行版各自的缓存服务来清除,比如 ubuntu 系统,默认使用 systemd
解析的服务来缓存 DNS 条目,可以通过 sudo systemd-resolve --flush-caches
来清除缓存
对于 Web 浏览器的 DNS 缓存,可以在地址栏输入 chrome://net-internals/#dnsChrome
,然后再点击 "clear host cache",也可以通过 Ctrl+Shift+Del
打开清除浏览器数据窗口进行清除
DNS 是用户层协议,传输层主要使用 UDP 协议,只有大包才可能使用 TCP 协议,具体原因请看这篇文章:为什么 DNS 使用 UDP 协议
首先看看 DNS 使用 UDP 协议整个报文的格式如下:
DNS 报文由 12 字节固定长度的首部和 4 个长度可变的字段组成。使用 UDP 时,整个 DNS 报文长度限定为 512 字节,如果使用 TCP 或者扩展域,DNS 消息体的长度可以进行扩展,并在传输时借助 TCP 来分段。
关于 DNS 报文每一个字段的释义,可以参考《TCP/IP 详解 · 卷一》。
DNS 安全问题,总的可以总结出以下几个:
域名抢注:有些黄牛会批量抢注大量域名,然后转身高价卖给那些对域名感兴趣的人,谋取暴力
DNS Cache 污染:中间 DNS 服务器将上级服务器返回结果进行修改,给客户端一个改变了(污染)的信息
DNS 劫持:和 DNS Cache 污染比较像,不过这种可以被外部第三者劫持进行恶意修改
DNS 欺骗:用一个假的 DNS 应答来欺骗用户计算机,让其相信这个假的地址,并且忽略真正的 DNS 应答
DNS 放大攻击:这是一种 DDoS 攻击, 利用 DNS 回复包比请求包大的特点,放大流量,伪造请求包的源 IP 地址为受害者 IP,将应答包的流量引入受害的服务器
系统上运行的 DNS 服务存在漏洞,导致被黑客获取权限,从而篡改 DNS 信息
DNS 设置不当,导致泄漏一些敏感信息。提供给黑客进一步攻击提供有力信息
下面着重说下 DNS 劫持和 DNS 欺骗。
有些流氓的域名服务器故意更改一些域名的解析结果,将用户引向一个错误的目标地址。这就叫作 DNS 劫持,主要用来阻止用户访问某些特定的网站,或者是将用户引导到广告页面。如下图所示:
针对 DNS 劫持,我们可以简单地更换域名服务器,比较靠谱的一个是Google 提供的 8.8.8.8。下面用 8.8.8.8 来解析一下 www.google.com 就能看到正确的地址了。
$ nslookup www.google.com 8.8.8.8
Server:8.8.8.8
Address:8.8.8.8#53
Non-authoritative answer:
Name:www.google.com
Address: 216.58.221.68
DNS 欺骗简单来说就是用一个假的 DNS 应答来欺骗用户计算机,让其相信这个假的地址,并且抛弃真正的 DNS 应答。在一台主机发出 DNS 请求后,它就开始等待应答,如果此时有一个看起来正确(拥有和DNS请求一样的序列号)的应答包,它就会信以为真,并且丢弃稍晚一点到达的应答。
利用 DNS 服务器实现访问的负载均衡,这是一种较早的负载均衡技术。
具体做法就是在 DNS 服务器中,配置多个 A 记录,这些 A 记录对应的服务器构成集群,然后就可以利用 DNS 轮询解析出不同的 IP 地址,以此实现最简单的轮询式负载均衡。比如 dig baidu.com
,我们可以看到 baidu.com
对应多个 A 记录:
通常的做法是将 DNS 服务器作为第一级的负载均衡设备,A 记录对应内部负载均衡器或服务器的 IP 地址,通过请求 DNS 服务器,将流量引导内部的负载均衡器或服务器上,作进一步处理。
但这种方案缺点也很明显,就是 DNS 有缓存,如果后端的某个机器出故障,域名解析还是返回那个机器的 IP,那所有的访问都会出问题,所以现在的 LB 都不采用这种 DNS 解析这种做法了。
DNS 服务器作为 CDN 专用访问服务器,也是作为第一级负载均衡器来使用。CDN 专用 DNS 服务器会缓存 CDN 的全局负载均衡设备的 IP 地址,而 CDN 全局负载均衡设备知晓全局范围内的所有 CDN 缓存服务器的地址,从而实现就近访问。如下图所示:
具体步骤:
①、当用户点击APP上的内容,APP会根据URL地址去本地DNS(域名解析系统)寻求IP地址解析。
②、本地DNS系统会将域名的解析权交给CDN专用DNS服务器。
③、CDN专用DNS服务器,将CDN的全局负载均衡设备IP地址返回用户。
④、用户向CDN的负载均衡设备发起内容URL访问请求。
⑤、CDN负载均衡设备根据用户IP地址,以及用户请求的内容URL,选择一台用户所属区域的缓存服务器。
⑥、负载均衡设备告诉用户这台缓存服务器的IP地址,让用户向所选择的缓存服务器发起请求。
⑦、用户向缓存服务器发起请求,缓存服务器响应用户请求,将用户所需内容传送到用户终端。
⑧、如果这台缓存服务器上并没有用户想要的内容,那么这台缓存服务器就要网站的源服务器请求内容。
⑨、源服务器返回内容给缓存服务器,缓存服务器发给用户,并根据用户自定义的缓存策略,判断要不要把内容缓存到缓存服务器上。
DNS 能够将一个服务的名字转换为 IP 这种特性,天然就适合作为一种服务发现手段。在目前的集群场景中,很多项目都会使用 DNS 来为集群提供服务发现的功能,比如 Kubernetes 集群中,就常使用 KubeDNS 和 CoreDNS 这两个 DNS 项目来解决服务发现的问题。
从 Kubernetes v1.12 开始,CoreDNS 便取代了 Kube-DNS,成为 Kubernetes 推荐的服务发现项目,CoreDNS 是 Golang 编写的一个插件式 DNS 服务器,关于 CoreDNS 的介绍后面会开一篇文章来单独介绍。
更多信息可以看:https://coredns.io/manual/toc/
常用的 DNS 调试工具:
host
nslookup
dig
这三个命令都属于 bind-utils
包,CentOS 系用户可以使用 yum install bind-utils
安装。
dig(Domain Information Groper,域名信息搜索),是一款 Unix/BSD 系统自带的 DNS 诊断工具。
使用 dig 查询从根域名到指定域名中间可能经过的所有域名服务器,使用 +trace 选项。
dig selfboot.cn +trace @8.8.8.8
; <<>> DiG 9.8.3-P1 <<>> selfboot.cn +trace @8.8.8.8
;; global options: +cmd
. 474418 IN NS j.root-servers.net.
. 474418 IN NS g.root-servers.net.
......
. 474418 IN NS l.root-servers.net.
. 474418 IN NS m.root-servers.net.
;; Received 496 bytes from 8.8.8.8#53(8.8.8.8) in 12 ms
cn. 172800 IN NS a.dns.cn.
......
cn. 172800 IN NS e.dns.cn.
cn. 172800 IN NS ns.cernet.net.
;; Received 292 bytes from 2001:500:1::803f:235#53(2001:500:1::803f:235) in 382 ms
selfboot.cn. 86400 IN NS f1g1ns2.dnspod.net.
selfboot.cn. 86400 IN NS f1g1ns1.dnspod.net.
;; Received 83 bytes from 203.119.25.1#53(203.119.25.1) in 816 ms
selfboot.cn. 14400 IN A 192.30.252.153
selfboot.cn. 14400 IN A 192.30.252.154
selfboot.cn. 600 IN NS f1g1ns1.dnspod.net.
selfboot.cn. 600 IN NS f1g1ns2.dnspod.net.
;; Received 125 bytes from 115.236.137.40#53(115.236.137.40) in 31 ms
nslookup 也是一款 DNS 诊断工具,几乎所有平台带这款工具,使用非常方便。
nslookup 的优势在可以交互式地查询域名记录,比如:
# nslookup
> github.com
Server:114.114.114.114
Address:114.114.114.114#53
Non-authoritative answer:
Name:github.com
Address: 13.229.188.59
>
host 可以看做是 dig 的简化版,主要将域名解析成 IP 地址或将 IP 地址解析成域名。
1、 将域名解析为 IP 地址:
# host baidu.com
baidu.com has address 39.156.69.79
baidu.com has address 220.181.38.148
baidu.com mail is handled by 20 jpmx.baidu.com.
baidu.com mail is handled by 10 mx.maillb.baidu.com.
baidu.com mail is handled by 20 mx50.baidu.com.
baidu.com mail is handled by 20 mx1.baidu.com.
baidu.com mail is handled by 15 mx.n.shifen.com.
可以看到除了返回 IP 地址,还返回域名相关的各种记录。
2、将 IP 地址解析为域名
DNS 逆向查询,等同于 dig -x
。
# host 13.229.188.59
59.188.229.13.in-addr.arpa domain name pointer ec2-13-229-188-59.ap-southeast-1.compute.amazonaws.com.
查询域名的注册情况。
# whois coolshell.cn
Domain Name: coolshell.cn
ROID: 20090825s10001s91994755-cn
Domain Status: ok
Registrant ID: hc401628324-cn
Registrant: 陈皓
Registrant Contact Email: [email protected]
Sponsoring Registrar: 阿里云计算有限公司(万网)
Name Server: f1g1ns1.dnspod.net
Name Server: f1g1ns2.dnspod.net
Registration Time: 2009-08-25 00:40:26
Expiration Time: 2023-08-25 00:40:26
DNSSEC: unsigned
附:
主要是基于当时的网络环境,从 UDP 分片上考虑,保证报文能畅通无阻。
绝大多数的网络接口类型支持IP报文≤576 字节无需分片自由通行,考虑到以上诸因素,IETF决定将DNS报文体限制在512字节。每一个根域名服务器占用32字节,其中包括根域名的名称、IP地址、TTL(Time To Live)等参数。
13根域名服务器一共占用416字节,剩余的96字节用于包装DNS报文头以及其它协议参数。所以从空间上来说,没有多余的空间容纳第14个根域名服务器的32字节。
容易被大众误解的是,这13个根域名服务器并不等于13台物理服务器,而是代表着13个全球IP地址,由13个机构来管理,对应有不同的名字,分别为“A” 到 “M”,其中美国最大电信运营商Verizon管理两个根域名全球IP地址。
截至到(2019.09)为止,全球一共有 1011台服务器实例(Instances),遍布 5大洲 4大洋。
参考:
https://mp.weixin.qq.com/s/n4q0f__t3FbsFMDs0M-gTwhttps://www.zhihu.com/question/22587247/answer/66417484https://mp.weixin.qq.com/s/LfprledUQWxLaOWyH8mOeQ https://blog.csdn.net/tianxuhong/article/details/74922454 https://selfboot.cn/2015/11/05/dns_theory/
后台回复“加群”,带你进入高手如云交流群
推荐阅读:
一张图带你循序渐进掌握性能优化问题
三张图彻底搞懂iptables和netfilter
救命,Linux正在吃掉我的内存!
别再说你不懂Linux内存管理了
强烈安利的几款画图工具
LVS 实战抓包分析
故障排查:K8s中Pod无法正常解析域名
详解Linux中3个文件查找相关命令
网络排错大讲解~
如何诊断 Linux 服务器的性能?
用了HTTPS就安全了吗?
HTTP/3 原理实战
Linux 下10个帮助你调试的命令
OVS 和 OVS-DPDK 对比
微软出品的最新K8S学习指南3.0下载
了解HTTPS工作原理,看这一篇就够了
▼
喜欢,就给我一个“在看”
10T 技术资源大放送!包括但不限于:云计算、虚拟化、微服务、大数据、网络、Linux、Docker、Kubernetes、Python、Go、C/C++、Shell、PPT 等。在公众号内回复「1024」,即可免费获取!!