查询过程
- 查看本机是否有解析结果
- 是否有解析缓存
- 是否有对应域名的映射
- linux保存在
/etc/hosts
文件中 - 需要做一些域名测试,但dns服务器上配置还没生效时,可以把本地这个文件加上映射来测试
- 获取local DNS服务器地址并查询
- 一般通过DHCP协议,在主机接入网络的时候分配
- linux写在
/etc/resolv.conf
文件的nameserver
记录中
- local DNS服务器发起迭代查询并返回结果
- localDNS对于端来说,是递归查询。端并不需要知道localDNS期间做了哪些操作,只需要知道最终能拿到的结果
- localDNS是获取域名最终解析的过程就是迭代查询。他不断通过NS记录询问各个DNS服务器,最终找到可以给出具体解析记录的服务器,并获取结果
- 参考:https://zhuanlan.zhihu.com/p/61383735
- 递归查询和迭代查询
- 递归查询
- 在该模式下DNS 服务器接收到客户机请求,必须直接使用一个准确的查询结果回复客户机
- 如果DNS 服务器本地没有存储查询DNS 信息,那么该服务器本身会询问其他服务器
- 迭代查询
- DNS 服务器并不直接回复查询结果,而是告诉客户机另一台DNS 服务器地址,客户机再向这台DNS 服务器提交请求,依次循环直到返回查询的结果为止
- 即返回
NS
类型记录
- DNS查询默认使用UDP协议
- 如果很短时间内没有响应返回,就再次发送记录
- 每次查询报文都包含一个标识符,并复制到响应中,以防止混淆查询结果
- DNS在使用UDP解析传输的时候,大小应该限制在512字节以内
- 主要考虑是这个大小不会因为路径中某个MTU太小而导致IP分片
- 如果数据包大小超过512字节,则设置"TC"位(截断),以通知客户端消息长度已超过最大允许大小
- 在这种情况下,客户端必须通过TCP协议重新传输请求
Q&A
- 为什么有时权威DNS server返回的IP不是该区域的最佳IP?
- 权威DNS Server响应查询结果不是看最终端请求者的ip来判断地区的,是根据当前向他做查询的机器的ip来判断的
- 客户端本地配置的localDNS可能不是本地区的
- localDNS出口IP配错了,可能不是本地区的
- 如果localDNS和权威DNS都支持edns,那么权威DNS可以直接拿到客户端的出口ip或者是指定的ip
- DNS如何实现负载均衡?
- 权威DNS调整返回的记录及其顺序
- localDNS轮询权威DNS返回的IP列表
- 权威DNS只返回一个A记录,通过权重来控制四个A记录出现的概率
DNS架构
- DNS服务端一般使用53端口
- 采用分布式,层次性数据库
- 负责管理下级域的DNS服务器需要把自己的IP地址注册到上级DNS服务器中
- 每一层的DNS只会管理其子域的解析工作
- 例如查询www.baidu.com,
.
域的DNS,只会告诉你去.com
域的DNS查询,不会直接给你结果
根DNS
- 最顶层的根DNS
.
的IP被预先存在LDNS(local DNS)中 - 根DNS只有13个IP,但是实际上包括根镜像有数千个服务器,他们共享这13个IP
- 分别是
[a-m].root-servers.net
- 这利用了任播技术
- 谷歌的
8.8.8.8
DNS服务器也利用了这一技术 - 任播技术的使用主要目的倒不是为了负载,是为了将DDOS的流量限制在当地
- 只有13个主要是为了限制DNS报文的大小
本地(local)DNS服务器
- 当用户主机发送DNS请求时,该请求被发往本地DNS服务器,该服务器代替用户向上述分层DNS数据库迭代请求
- 向本地DNS服务器发送消息时,我们当然也需要知道DNS服务器IP地址,不过这个地址是事先设置好的,无须查询
- 默认由DHCP自动分配
- 如果电脑直连运营商网络,那么DNS会被分配为运营商服务地址
- 如果通过路由器上网,由于路由器本身内置DNS转发,那么分配给电脑的DNS服务地址会是路由器本身
- 此时DNS地址为内网地址,例如
192.168.1.1
- Linux系统里的本地DNS服务器地址配置在
/etc/resolv.conf
的namesever
记录中
- 如果地址是
127.0.0.53
,则当前本机的DNS Server是systemd-resolve,并且是一个DNS stub
- 真正的local DNS server可以通过以下命令查询:
systemd-resolve --status | grep "DNS Servers"
权威DNS服务器
- 权威DNS负责对请求作出权威的回答
- 权威能直接回答的,就回A记录
- 需要其他权威DNS回答的,就回NS记录,然后LDNS再去找其他权威DNS问
- 例如LDNS向根DNS请求
www.baidu.com
的IP时,根DNS会以NS记录返回com
域DNS的名字和IP
- 如果该记录是别名类型的,就回CNAME,LDNS就会再去解析别名
- 权威DNS中的DNS资源记录不会自动过期
- localDNS这种非权威DNS的资源记录会有TTL,超过这个时间后,DNS服务器会将记录对应的缓存删除,下次再重新获取最新的数据
- 每个组织(域名)必须提供可访问的权威DNS服务器来记录组织下面的服务器地址
- 当然也可以付费把记录储存在服务提供商提供的权威DNS服务器中
- 注册域名时,需要提供权威权威DNS服务器地址,此时注册登录机构将下面记录插入DNS系统中
(example.com, dns.example.com, NS)
(dns.example.com, 212.212.212.1, A)
DNS记录
- 域名不区分大小写
- 格式:
(Name, Value, Type, TTL)
- `Type`**分类:**
- `Type=A` : 表示域名到**IPv4地址**的映射
- `(www.example.com, 145.37.92.1, A)`
- `Type=AAAA`:表示域名到**IPv6地址**的映射
- `(www.google.com, 2404:6800:4003:c04, AAAA)`
- `Type=NS` : 表示该域或组织的权威DNS(name server)的域名
- `(foo.com, dns.foo.com, NS)`
- NS记录**优先于A记录**
- `Type=CNAME` : 别名到到规范域名的映射
- `(foo.com, relay1.bar.foo.com, CNAME)`
- `Type=SOA`:
别名(CNAME)
- CNAM表示一个域名的另一个名称, 前者继承后者的A记录解析结果
- 例如
www.qq.com. 276 IN CNAME ins-r23tsuuf.ias.tencent-cloud.net.
, 表示解析www.qq.com
的A记录等同于解析ins-r23tsuuf.ias.tencent-cloud.net
的A记录
- CNAME的好处
- 方便管理A记录
- 如果域名A 和 域名B 都指向 同一组IP,如果都各自绑定A记录,后期维护就比较麻烦了
- 一种解决就是新增一个域名C,由域名C直接和 IP组绑定;域名A/B只需增加一个CNAME指过去域名C即可
- 用于CDN加速
- 当使用CDN服务的时候,服务商提供的就是一个CNAME地址(加速域名)
- CDN服务商可以方便地更换提供的域名的A记录,而不用变更所有使用者域名的A记录
DNS劫持
- 路由器的 DNS 设置被非法侵入篡改
- DNS 设置为恶意的 DNS 地址,这些有问题的 DNS 服务器会在你访问某些网站时返回仿冒内容,或者植入弹窗广告等
- 运营商 LocalDNS 可能会导致接入域名的解析被劫持
- 部分运营商为了降低跨网流量,缓存部分域名的指向内容,把域名强行指向自己的内容缓存服务器的 IP 地址
- 不向权威DNS发起递归,导致服务端的全局流量调度失效
- 有些运营商从权威DNS拿到多个IP后,为了减少流量跨省结算的成本 ,会进行跨省拦截,只会向用户返回于本省的IP
- 会导致服务端使用外省节点替换本省节点来分摊流量失败,反而增加了剩余本省节点的流量
- 运营商可能会修改 DNS 的 TTL(Time-To-Live,DNS 缓存时间)
- 一些小运营商为了减轻自身的资源压力,把 DNS 请求转发给其他运营商去解析
- 分配的 IP 地址可能存在跨运营商访问的问题,导致请求变慢甚至不可用
HTTPDNS
- 用户的请求不再通过运营商来查询域名的解析,而是通过 HTTPS 来进行查询,这个 HTTP 接口后端再去向权威 DNS 请求
- 目前很多大厂也基本都支持 HttpDNS 为主,运营商 LocalDNS 为辅(fallback)的模式了
- 本质是采用自建DNS服务器的方式,其实也可以不采用HTTP协议请求
- 通过HTTP DNS解析域名的请求是直接通过预先写在SDK中的IP列表请求解析服务器的
- 需要保证这些IP的高可用,可以采用任播(BGP Anycast)技术
- 好处
- 调度更精准
- 由于 HttpDNS 服务器能获取到真实的用户出口 IP, 而非 Local DNS 的 IP,所以能选择离用户更近的节点进行接入
- 前提是 HttpDNS 服务自身需要有比较全的 IP 库来支持
- 每个LocalDNS覆盖多少用户是不清楚的,且某些省份,单个LocalDNS IP可以覆盖95%以上的用户
- 或者一次返回多个接入 IP,让客户端通过测速等方式选择速度更快的接入 IP,因此整体上接入调度也更精准
- 降低用户连接失败率
- 防止DNS劫持
- TTL时效性增强
- 避免了local DNS TTL缓存造成的调度生效慢和流量切不干净的问题
- 缺点
- HttpDns虽然可以解决劫持等问题,但其对比传统DNS技术,在性能上会有一定的损耗
- 这是因为传统DNS是基于UDP的协议,而HttpDNS一般是基于Https进行发送的,Https在握手、服务端处理等一系列环节上开销要大于UDP
- 但如果没有缓存的话,传统DNS需要多个UDP查询,而HTTP DNS只需要一个HTTP请求,反而快
- 这可以采取DNS与HttpDns竞速的方式解决
- 即同时发送DNS和HttpDns,哪个先回来就先使用哪个
- 但当HttpDns的数据返回后,后续请求全都是用HttpDns的解析结果
- 也可以采用预解析、批量查询等策略
- 参考: