2023-12-21更新:虽然8.8.8.8对MX、CAA以及其他类型等依然不支持ecs(符合RFC标准),但是在cname链中已经不会对A/AAAA等其他记录类型造成影响,看上去像是单独处理了,已经修复了该问题。
但是依然存在ecs失效的可能,比如8.8.8.8的递归到权威的请求偶发超时、请求权威跨国且请求了同权威IP被污染的域名等场景,依然可能造成递归判断权威的IP不支持ecs,导致后续一段时间内的ecs失效,暂无太好的办法。
2021-04-02 更新: Google 公共 DNS 已经对 HTTPS 和 SVCB 支持了 ECS,其他类型正在评估,测试正常。
2021-03-26 更新:标准化组织正在对该问题进行讨论,大体方案可能为:
- 如果递归 DNS 准备解析 HTTPS 记录指向的域名,并且在返回给客户端的应答附加段中添加 A/AAAA 记录,则递归在向权威请求HTTPS 记录时应携带 /0,表示递归支持 ECS,但对 HTTPS 记录类型禁用,此时权威在响应时不能在附加段中添加相关 A/AAAA 记录,以便递归 DNS 携带正常的 ECS 进行 A/AAAA 记录的请求。
- 如果递归 DNS 不准备执行上面的方案,则递归在向权威进行 HTTPS 类型的请求时应携带与请求 A/AAAA 类型相同的 ECS。
方案1实现较复杂,递归 DNS 需要对 HTTPS 记录类型进行单独处理,此处也要注意 HTTPS 记录类型也包括对应的 CNAME,但是可以减轻缓存压力;方案2简单粗暴,对应增加的就是递归 DNS 的缓存压力。
具体信息可以参考: https://issuetracker.google.com/issues/181593657 和 https://github.com/MikeBishop/dns-alt-svc/pull/308
我们一直的观点是在国内不要使用 Google 的公共 DNS(8.8.8.8),这里再从技术层面讨论下 IOS 14 更新后使用 8.8.8.8 进行 DNS 解析对 CDN 调度的影响。
结论
- 在国内任意地区都不应该系统上直接设置或转发到 8.8.8.8 进行 DNS 解析,这个结论依然有效。
- IOS 14 更新后会对域名自动发出 TYPE HTTPS (TYPE65) 类型的请求,这会导致 8.8.8.8 对于包含 CNAME 记录的解析结果 ECS 判断失效的情况极大增多,调度不准确的情况会远多于 IOS 14 更新之前,CDN 调度受影响比较严重。
- 仅限于当前时间(2021.03.04)有效,如果后续相关 DNS 请求行为有变化,则结论可能不再准确。
解析过程
公共 DNS 的解析准确度一般是通过在尽量多的地区和运营商部署递归节点,以及是通过 ECS (EDNS Client Subnet,常简称为 EDNS) 技术来提示解析准确度,最主要的使用场景就是 CDN 的调度,所以一旦 ECS 失效,对 CDN 调度的影响也是最大的。
虽然任何 DNS 都不能保证完全解析准确,但是此前 8.8.8.8 做的还是不错的,但是从 20 年 IOS 14 更新后,解析准确度每况愈下,尤其是对部分使用 CDN 进行调度的域名影响较大,经常发生国内解析到国外、不同地区使用多家 CDN 时解析结果不符合预期等问题,下面分析下 IOS 14 对该现象的具体影响过程。
假设在权威 DNS 上对typehttps.example.com
配置以下记录, 并且权威 DNS 对 ECS 的支持正确,8.8.8.8 的自动检测也可以正确检测到权威 DNS 是支持 ECS 的。
typehttps 默认 600 CNAME test1.example.com.
typehttps 境外 600 CNAME test2.example.com.
test1 默认 600 A 8.8.8.8
test2 默认 600 A 8.8.4.4
当我们从国内向 8.8.8.8 请求 typehttps.example.com
或携带国内IP(如 119.29.0.0/24
)的 ECS IP 时,正常过程是这样的,
dig @8.8.8.8 typehttps.example.com +subnet=119.29.0.0/24
正常的结果应该是类似这样的,因为权威 DNS 是根据 8.8.8.8 请求时携带的119.29.0.0/24
进行解析的,
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
; CLIENT-SUBNET: 119.29.0.0/24/24
;; QUESTION SECTION:
;typehttps.example.com. IN A
;; ANSWER SECTION:
typehttps.example.com. 550 IN CNAME test1.example.com.
test1.example.com 600 IN A 8.8.8.8
但是现在你有很大概率拿到会是以下的错误结果,
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
; CLIENT-SUBNET: 119.29.0.0/24/24
;; QUESTION SECTION:
;typehttps.example.com. IN A
;; ANSWER SECTION:
typehttps.example.com. 590 IN CNAME test2.example.com.
test1.example.com 600 IN A 8.8.4.4
解析到了境外的 CNAME 及其 IP,以前虽然也可能出现这种解析错误的情况,但是相对少很多,那是什么原因呢,此时如果我们指定请求 CNAME 类型再来看下有什么区别,
dig @8.8.8.8 typehttps.example.com +subnet=119.29.0.0/24 CNAME
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
; CLIENT-SUBNET: 119.29.0.0/24/0
;; QUESTION SECTION:
;typehttps.example.com. IN CNAME
;; ANSWER SECTION:
typehttps.example.com. 590 IN CNAME test2.example.com.
此时可以看到 ECS 段中的 scope 为 0,这就表示 8.8.8.8 的缓存中将境外线路的 CNAME 记录作为全局结果缓存了,那为什么会出现这种错误的解析和缓存结果呢?
通过抓包分析可以发现,8.8.8.8 对权威 DNS 发起的查询请求中,即使权威是支持 ECS 的,8.8.8.8 也并不会对所有类型的请求记录携带 ECS 段,大部分常见的请求类型,如 A 记录(IPv4)、AAAA 记录(IPv6)、CNAME 记录等并不会出现问题,但是有部分请求类型则不会携带 ECS 进行请求,而这其中有部分类型可能会返回 CNAME 记录,比如 MX 、CAA 以及 HTTPS 类型,权威 DNS 就会按照 8.8.8.8 的递归 DNS 的 IP 所在地返回境外线路的 CNAME 记录,而后 8.8.8.8 就会按照全局 /0 的 scope 缓存该 CNAME。
所以这里就破案了,具体过程是如下两图所示,
- IOS14 升级后会支持 TYPE HTTPS 的记录类型,解析一个域名时应同时请求 A/AAAA/HTTPS 记录类型。
- 则 A 和 AAAA 记录可以正常获得境内的 CNAME 和 IP 并正常按照
119.29.0.0/24
的 IP 段缓存,但该缓存仅对该 IP 段有效. - HTTPS 类型的返回的错误 CNAME 结果就会因为上述原因作为全局 /0 的缓存。
- 后续所有非
119.29.0.0/24
网段 请求都会命中全局缓存的错误 CNAME 记录,然后再对 CNAME 记录进行正常的递归查询,客户端最后拿到的就是错误的境外结果。 - 虽然 MX 、CAA、HTTPS 类型都会造成此问题,但是在实际的网络环境中,普通域名的 MX 和 CAA 记录类型都是很少被请求到的,所以 8.8.8.8 虽然一直存在类似的问题,但是并不严重。直到 IOS14 更新后, HTTPS 记录类型默认被请求,该问题就变得比较严重了。
影响范围
对不同地区设置了不同 CNAME 记录的域名会有较大影响,一般常见于 CDN,所以对 CDN 影响比较大,具体分析话大概是这样的,
- 如果境内和境外使用了不同的 CNAME 记录,如国内使用国内的 CDN,国外使用国外的 CDN,则国内使用 8.8.8.8 会大概率解析到国外线路的 CNAME,很可能解析到国外节点影响访问体验。
- 如果未设置其他国家、大洲、境外等线路,只是不同省份运营商使用不同的 CNAME 记录进行负载均衡,则国内使用 8.8.8.8 会大概率会解析到默认线路上,虽然会造成负载均衡效果不符合预期,但在客户端的访问体验上总体影响不大。
- 对境外用户影响有限,因为虽然也存在一样的 ECS 失效问题,但根据递归 DNS IP 获取到的 CNAME 结果范围不会差距很大。
规避方法
- 在国内避免使用 8.8.8.8,当然这里有部分运营商已经帮忙搞定这一步了,移动端则可以考虑使用 HTTPDNS 等技术手段规避。
- 如果条件允许,不同地区应使用相同的 CNAME,如果必须使用不同的CNAME,则需要关注默认和境外相关线路的容量等问题,如境外线路的 CDN 能提供境内 CDN 节点则可以很大的缓解该问题。
其他公共DNS
- OpenDNS 208.67.222.222 仅 CAA 记录可能存在此问题;腾讯云/DNSPod 119.29.29.29,各请求类型均不受影响;阿里云 223.5.5.5 不受影响。
- 1.1.1.1、9.9.9.9、180.76.76.76、114.114.114.114,默认未支持 ECS ,仅能通过后端递归节点的部署进行调度,不涉及该问题。