DNS
DNS,Domain Name System,域名系统
Last updated
DNS,Domain Name System,域名系统
Last updated
有专门的域名注册商,国内的可以在工信部的网站上查到,终极的域名注册商是 ICANN。
最右边的是顶级域名,然后是二级域名、三级域名,以此类推。最左边的是主机名,通常用来表明主机的用途(但也不绝对),比如 www
表示提供万维网服务、mail
表示提供邮件服务。
以 developer.mozilla.org
为例,org
是顶级域名,mozilla
是二级域名,developer
是主机名。
说明:
域名的总长度需在 253 个字符以内,每级域名的长度需在 63 个字符以内
域名是大小写无关的,通常都用小写
过长或层次过多的域名会导致难以记忆,所以大多是二级或三级,四级以上很少见
代替 IP 地址。IP 地址是对物理网卡的 MAC 地址(16 进制数)做的一层抽象,这样一来,只要每个小网络在 IP 地址这个概念上达成一致,那么不管它在 MAC 层有多大的差异都可以接入 TCP/IP 协议栈,最终汇合进整个互联网。然而随着接入互联网的计算机越来越多,IP 地址的缺点也暴露出来了——不好记忆和输入。于是就在 IP 地址之上再来一次抽象,即把 IP 地址转换成更有意义更好记的名字,这就是 DNS 域名系统。
在 web 服务器里(Apache, Nginx),域名可以用来标识虚拟主机,从而决定由哪台虚拟主机来对外提供服务。
域名本质上还是名字空间系统,作为一种身份标识,它被扩展到了其它应用领域。比如 Java 的包机制,只是它使用了反序(如 org.mozilla.developer
),比如 XML 使用 URI 作为名字空间,也是间接地使用了域名。
作为互联网的基础设施,域名解析必须稳定可靠、快速高效。
DNS 的核心系统是一个三层的树状分布式服务,基本对应域名的结构。
Root DNS Server 根域名服务器
管理顶级域名服务器
返回 com
, net
, cn
, gov
等顶级域名服务器的 IP 地址
Top-level DNS Server 顶级域名服务器
管理各自域名下的权威域名服务器
比如顶级域名服务器 com
可以返回权威域名服务器 apple.com
的 IP 地址
Authoritative DNS Server 权威域名服务器
管理自己域名下主机的 IP 地址
比如权威域名服务器 apple.com
可以返回 www.apple.com
的 IP 地址
目前全世界共有 13 组根域名服务器,又有数百台镜像,保证一定能被访问到。之所以是 13 组,是因为 DNS 协议和 UDP 协议里包大小的限制,只有 512 字节,再除以 DNS 记录的长度,最多 15 组,再去掉 buffer。
任何一个域名都可以在这个树形结构中自顶向下地进行查询,即把域名按照从右到左的顺序走了一遍,最终就能获得该域名对应的 IP 地址。比如,要访问 www.apple.com
,就要进行三次查询:
访问根域名服务器,它会告诉我们顶级域名服务器 com
的 IP 地址
访问顶级域名服务器 com
,它会告诉我们权威域名服务器 apple.com
的 IP 地址
最后访问权威域名服务器 apple.com
,就能得到 www.apple.com
的 IP 地址
在核心 DNS 系统之外,还有两种手段可以用来减轻域名解析的压力,并且能够更快地获取结果,其基本思路就是缓存。
许多大公司和网络运行商都会建立自己的 DNS 服务器,作为用户 DNS 查询的代理,代替用户访问核心 DNS 系统。这些野生 DNS 服务器,也称非权威域名服务器,它们可以缓存之前的查询结果。如果已经有记录了,就不用再查询根服务器了,可以直接返回对应的 IP 地址。这类 DNS 服务器的数量要比核心系统的服务器多很多,而且大多都部署在离用户很近的地方。比较知名的非权威域名服务器有 Google 的 8.8.8.8,Microsoft 的 4.2.2.1,以及 CloudFlare 的 1.1.1.1 等。
操作系统也会缓存 DNS 的解析结果,而且它还有一个特殊的主机映射文件 hosts。有了这些缓存策略,很多域名解析的工作就能直接在本地或本机解决了,不仅方便了用户,还减轻了各级 DNS 服务器的压力,大大提升了查询效率。
下图比较完整地表示了现在的 DNS 架构:
首先,会在本地域名服务器中递归查询,查询的顺序依次是:
浏览器缓存。在 chrome 中可以通过 URI chrome://net-internals/#dns 来查询和清除浏览器缓存
操作系统缓存。比如 dnscache client 进程,可以用命令 ipconfig /displaydns
显示已有缓存,用命令 ipconfig /flushdns
强制更新缓存
hosts 文件。本机 DNS 解析,固定的默认位置
因为是递归查询,所以查询顺序≠生效顺序
如果在本地域名服务器中没有查询到给定域名的 IP,则会启动远程查询。远程查询是基于 UDP 协议的,通常使用 53 号端口。通常我们电脑中的网卡会被分配一个 DNS server IP(即非权威 DNS 服务器的 IP),比如企业内网 DNS 服务器、局域网 DNS 服务器、三大运营商的 DNS 服务器、谷歌公开的 DNS 服务器、微软公开的 DNS 服务器等。如果非权威 DNS server 还是没有查询到给定域名的 IP,那么它会继续访问核心 DNS 系统,即依次请求:根域名 server -> 顶级域名 server -> 权威域名 server。
比如在 nginx 中,
resolver
指令就用来配置 DNS server IP。如果没有它,那么 nginx 就没法查询域名对应的 IP 了,也就没法反向代理到外部网站了,比如resolver 8.8.8.8 valid=30s;
小结:本地域名 server -> 非权威 DNS server -> DNS 核心系统,展开之后就是(浏览器 cache -> OS cache -> hosts file)-> 非权威 DNS server ->(根域名 server -> 顶级域名 server -> 权威域名 server)。
如果查询到了给定域名的对应 IP,通常各个环节都会对域名解析的结果进行缓存(是缓存就有缓存有效期)。如果域名不存在或域名解析失败,会显示如下类似信息:
在域名解析基础上的延展:
重定向。域名不变,而主机的 IP 地址可以任意变动。当有主机需要下线或迁移时,可以更改 DNS 记录,让域名指向其它的机器
可以使用 bind9 等开源软件搭建一个在内部使用的 DNS,作为名字服务器。可以用域名来标记各种内部开发的服务。
实现基于域名的负载均衡
第一种:域名解析可以返回多个 IP 地址,当客户端收到多个 IP 地址后,可以自己使用轮询算法依次向服务器发起请求,实现负载均衡
第二种:配置域名解析的内部策略,返回离客户端最近的主机,或是返回当前服务质量最好的主机,这样就能在 DNS 端把请求分发到不同的服务器,实现负载均衡
恶意 DNS:域名屏蔽、域名劫持