DNS (Domain Name System), 也叫网域名称系统,是互联网的一项服务。它实质上是一个 域名 和 IP 相互映射的分布式数据库,有了它,我们就可以通过域名更方便的访问互联网。最初,由于 ip 长且难记,通过 ip 访问网站不方便。。所以后来通过发明了 DNS 服务器,这个时候我们访问网站输入网站域名,DNS 服务器就解析我们的域名为 ip。这样我们实际访问的就是对应的 ip 地址啦。
DNS 有以下特点:
- 分布式的
- 协议支持 TCP 和 UDP, 常用端口是 53
- 每一级域名的长度限制是 63
- 域名总长度限制是 253
那么,什么情况下使用 TCP,什么情况下使用 UDP 呢?
最早的时候,DNS 的 UDP 报文上限大小是 512 字节, 所以当某个 response 大小超过 512 (返回信息太多),DNS 服务就会使用 TCP 协议来传输。后来 DNS 协议扩展了自己的 UDP 协议,DNS client 发出查询请求时,可以指定自己能接收超过 512 字节的 UDP 包, 这种情况下,DNS 还是会使用 UDP 协议
域名与 ip 的对应关系,被称为记录(record),可分为各种类型
- A: Address,域名指向的 IP 地址,一个域名可以有多个 A 记录。
- NS:Name Server,保存下一级域名信息的服务器地址
- MX:Mail eXchange,接受电子邮件的服务器地址
- CNAME:Canonical Name,返回另一个域名,令当前查询域名挑去该域名,多个域名->服务器的映射。
- PTR: Pointer Record,只用于 ip 地址查询域名
DNS 由下面三个部分组成
- 名称解析器(resolver)
- 域名空间(domain name space)
- 名称服务器(name server)
假如你要访问 baidu.com,需要先通过 dns 系统查出他的 ip 地址如 220.181.57.216,才能访问。
dns 查询的过程
dns 通过域名查出 ip(我们以浏览器输入www.example.com为例):
- 检查浏览器缓存(缓存时间比较短,默认只有 1 分钟,且只能容纳 1000 条缓存)
1 | // 查看Chrome自身的缓存 |
- 检查操作系统 DNS 缓存
1 | # Windows - 查看DNS缓存条目 |
- 读取
hosts
文件 - 检查路由器缓存
- 如果前几步都没没找到,会向 ISP(网络服务提供商)的 LDNS 服务器查询
- 如果 LDNS 服务器没找到,会向跟域名服务器(Root Server)请求解析,分为以下几步:
- 跟服务器返回顶级域名(TLD)服务器如.com,.cn,.org 等的地址,全球只有 13 台,该例子中会返回.com 的地址
- 接着向 TLD 发送请求,然后会返回次级域名(SLD)服务器的地址,本例子会返回.example 的地址
- 接着向 SLD 域名服务器通过域名查询目标 IP,本例子会返回www.example.com的地址
- Local DNS Server 会缓存结果,并返回给用户,缓存在系统中。
DNS 安全问题
- DNS 反射/放大攻击
向大量开放 DNS 服务器发送大范围域名查询的 DNS 请求,并将该 DNS 请求的源 IP 地址伪造成想要攻击的目标 IP 地址。由于请求数据比相应数据小得多,攻击者可以利用该技术放大掌握的带宽资源和攻击流量。 - DDOS 攻击可能造成域名解析瘫痪
- DNS/域名劫持
在劫持的网络范围内拦截域名解析的请求,分析请求的域名,返回假的 IP 地址或者使请求失去响应。DNS 劫持通过篡改 DNS 服务器上的数据返回给用户一个错误的查询结果来实现的。 - DNS 污染
DNS 污染是一种让一般用户由于得到虚假目标主机 IP 而不能与其通信的方法,指的是用户访问一个地址,国内的服务器(非 DNS)监控到用户访问的已经被标记地址时,服务器伪装成 DNS 服务器向用户发回错误的地址的行为。
dns 污染与 dns 劫持的区别在于,dns 劫持修改了 dns 的解析结果,dns 污染是不经过 dns 服务器,返回错误信息 - DNS 信息黑客被修改
DNS 优化
可以看出,dns 解析是一个漫长的过程,如何优化这一过程呢?
- DNS Prefetching 用户在请求某个链接之前,浏览器先尝试解析该链接的域名再将其进行缓存。这样真正请求的时候就不需要进行 DNS 解析。可以
- 在服务器中响应设置
X-DNS-Prefetch-Control
的值为on
启动预解析 - HTML 中,
<meta http-equiv="x-dns-prefetch-control" content="on">
- 对特定域名预解析
<link rel=”dns-prefetch” href=”//fonts.googleapis.com”>
- 在服务器中响应设置
- 域名收敛
建议将静态资源只放在一个域名下面,可以有效减少 dns 的请求 - httpdns 基于 Http 协议向 HTTPDNS 服务器发送域名解析请求,替代了基于 DNS 协议向运营商 Local DNS 发起解析请求的传统方式,可以避免运营商的域名劫持和进行精准调度。这过程分为两步
- 客户端直接访问 HttpDNS 接口,获取业务在域名配置管理系统上配置的访问延迟最优的 IP。(基于容灾考虑,还是保留次选使用运营商 LocalDNS 解析域名的方式)
- 客户端向获取到的 IP 后就向直接往此 IP 发送业务协议请求。以 Http 请求为例,通过在 header 中指定 host 字段,向 HttpDNS 返回的 IP 发送标准的 Http 请求即可。
参考文章
「真 ® 全栈之路 - DNS 篇」故事从输入 URL 开始….:https://juejin.im/post/5ceebb7251882507266414b7#heading-10