DNS & CND

DNS

介绍

DNSDomain Name System,域名系统),DNS 服务用于在网络请求时,将域名转为 IP 地址。能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的 IP 数串。

image-20231207162328822

传统的基于 UDP 协议的公共 DNS 服务极易发生 DNS 劫持,从而造成安全问题。

image-20231207162403478

  • 递归查询

    如果主机所查询的本地域名服务器不知道被查询域名的 IP 地址,那么本地域名服务器就以 DNS 客户端的身份,向其他根域名服务器继续发出查询请求报文,而不是让该主机自己进行下一步的查询。

  • 迭代查询

    当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所查询的 IP 地址,要么告诉本地域名服务器:你下一步应当向哪一个域名服务器进行查询。然后让本地域名服务器进行后续的查询,而不是替本地域名服务器进行后续的查询。

由此可见,客户端到 Local DNS 服务器,Local DNS 与上级 DNS 服务器之间属于递归查询;DNS 服务器与根 DNS 服务器之间属于迭代查询。

问题

Local DNS 劫持

image-20231207162926645

Local DNS 把域名劫持到其他域名,实现其不可告人的目的。

域名缓存

域名缓存就是 LocalDNS 缓存了业务的域名的解析结果,不向权威 DNS 发起递归。

image-20231207163024532

  • 保证用户访问流量在本地内网消化:国内的各互联网接入运营商的带宽资源、网间结算费用、IDC机房分布、网内ICP资源分布等存在较大差异。为了保证网内用户的访问质量,同时减少跨网结算,运营商在网内搭建了内容缓存服务器,通过把域名强行指向内容缓存服务器的IP地址,就实现了把本地本网流量完全留在了本地的目的。(从而实现本网流量消化,不用跨网,也就可以省钱,或者增加一些广告。)
  • 推送广告:有部分 LocalDNS 会把部分域名解析结果所指向的内容缓存,并替换成第三方广告联盟的广告。

解析转发

image-20231207163311185

除了域名缓存以外,运营商的LocalDNS 还存在解析转发的现象。

解析转发是指运营商自身不进行域名递归解析,而是把域名解析请求转发到其他运营商的递归DNS上的行为。

而部分小运营商为了节省资源,就直接将解析请求转发到了其他运营的递归 LocalDNS 上去了。

image-20231207163449253

这样的直接后果就是权威 DNS 收到的域名解析请求的来源IP就成了其他运营商的IP,最终导致用户流量被导向了错误的IDC,用户访问变慢。

递归出口 NAT

LocalDNS 递归出口 NAT 指的是运营商的 LocalDNS 按照标准的 DNS 协议进行配置,但是因为在网络上存在多出口且配置了目标路由 NAT,结果导致LocalDNS 最终进行递归解析的时候的出口 IP 就有概率不为本网的 IP 地址。

image-20231207164837139

这样的直接后果就是 DNS 收到的域名解析请求的来源IP还是成了其他运营商的IP,最终导致用户流量被导向了错误的 IDC,用户访问变慢。

高可用 DNS 设计

实时监控 + 商务推动:

这种方案周期比较长,毕竟通过行政手段来推动运营商来解决这个问题是比较耗时的。

另外我们通过大数据分析,得出的结论是 Top3 的问题用户均为移动互联网用户。对于这部分用户,我们有什么技术手段可以解决以上的问题呢?

绕过自动分配 DNS,使用 114DNSGoogle public DNS

  • 如何在用户侧构造域名请求:对于 PC 端的客户端来说,构造一个标准的 DNS 请求包并不算什么难事。但在移动端要向一个指定的 LocalDNS 上发送标准的 DNS 请求包,而且要兼容各种 iOSAndroid 的版本的话,技术上是可行的,只是兼容的成本会很高。
  • 推动用户修改配置极高:如果要推动用户手动修改 PCDNS配置的话,在 PC端和手机客户端的 Wi-Fi 下面还算勉强可行。但是要用户修改在移动互联网环境下的 DNS 配置,其难度不言而喻。

完全抛弃域名,自建 HTTPDNS 进行流量调度:

  • 如果要采用这种方案的话,首先就得要拿到一份准确的IP地址库来判断用户的归属(根据HTTPHeader获取里面放的源IP),然后再指定个协议,搭建服务器来做调度,然后再对接入层做调度改造。
  • 这种方案和上面两种方案一样,可以做,但是成本会很高,尤其对于大体量业务规模如此庞大的公司而言。

当前主流的解决方案:HTTPDNS。使用 HTTP 请求,代替使用 UDP 请求 DNS

最佳实践

HTTPDNS 利用 HTTP 协议与 DNS 服务器交互,代替了传统的基于 UDP 协议的 DNS 交互,绕开了运营商的 LocalDNS,有效防止了域名劫持,提高域名解析效率。

image-20231207170221398

另外,由于 HTTPDNS 服务器端获取的是真实用户端 IP 而非 LocalDNSIP,能够精确定位客户端地理位置、运营商信息,从而有效改进调度精确性。

HTTPDNS基本原理

由于 HTTPDNS 是通过 ip 直接请求 HTTP获取服务器A记录地址,不存在向本地运营商询问 domain 解析过程,所以从根本避免了劫持问题。

image-20231207170425290

平均访问延迟下降:

  • 由于是ip直接访问省掉了一次 domain 解析过程

用户连接失败率下降:

  • 通过算法降低以往失败率过高的服务器排序
  • 通过时间近期访问过的数据提高服务器排序
  • 通过历史访问成功记录提高服务器排序

根治域名解析异常

image-20231207170639723

由于绕过了运营商的 LocalDNS,用户解析域名的请求通过HTTP协议直接透传到了 HTTPDNS 服务器IP 上,用户在客户端的域名解析请求将不会遭受到域名解析异常的困扰。

  • 调度精准:HTTPDNS 能直接获取到用户IP,通过结合 IP地址库以及测速系统,可以保证将用户引导到访问最快的 IDC节点上;
  • 实现成本低廉:
    • 接入 HTTPDNS的业务仅需要对客户端接入层做少量改造,无需用户手机进行 root 或越狱;
    • 而且由于少量HTTP协议请求构造非常简单,兼容各版本的移动操作系统更不成问题;
    • 另外 HTTPDNS的后端配置完全复用现有权威 DNS 配置,管理成本也非常低;

优势

如果只有一个 VIP,即可以增加 DNS记录的TTL,减少解析的延迟。

image-20231207171225596

Anycast 可以使用一个IP,将数据路由到最近的一组服务器,通过BGP宣告这个IP,但是这存在两个问题:

  • 如果某个节点承载过多的用户会过载
  • BGP 路由计算可能会导致连接重置

因此需要一个稳定Anycast技术来实现。例如谷歌使用的 8.8.8.8How Anycast makes DNS resolve faster

CDN

使用 HTTPDNS + CDN缓存静态图片等资源,让终端访问更快。

系统架构

架构图

image-20231207171254922

  1. 用户流量发起 DNS 请求到 Loacl DNS,查询IP,返回最佳接入IP(由权威的DNS返回距离最近的IP)
  2. 往最佳 IP 发起请求,也就是一级 CDN,一级 CDN 可能会将流量转发到二级 CDN
  3. 二级CDN访问源站节点,将资源返回,并且缓存到本地

拓扑图

image-20231207171315027

  • 缓存代理

    通过智能DNS的筛选,用户的请求被透明地指向离他最近的省内骨干节点,最大限度的缩短用户信息的传输距离。

  • 路由加速

    利用接入节点和中继节点或者多线节点互联互通

  • 安全保护

    无论面对是渗透还是 DDoS 攻击,攻击的目标大都会被指向到了 CDN,进而保护了用户源站

  • 节省成本

    CDN 节点机房只需要在当地运营商的单线机房,或者带宽相对便宜的城市,采购成本低。

image-20231207171548263

  • 内容路由

    DNS系统、应用层重定向,传输层重定向

  • 内容分发

    • PUSH:主动分发,内容管理系统发起,将内容从源分发到 CDNCache 节点。使用边缘节点存储热点数据,降低内部网络流量和延迟。
    • PULL:被动分发技术,用户请求驱动,用户请求内容中 miss,从源中或者其他 CDN 节点中实时获取内容(还可以使用归并回源,收敛请求)
  • 内存存储

    随机读、顺序写、小文件的分布式存储

  • 内容管理

    提高内容服务的效率,提高 CDN 的缓存利用率

数据一致性

  • PUSH

    不存在数据一致性问题(特别是前端jscss 文件名保持一致,导致新版本跟老版本不一致的问题,推荐在 jscss里面的references里面携带 md5信息,例如 a.{md5}.js

  • PULL

    缓存更新不及时,数据一致性问题,可设置缓存的失效时间,可以达到最终一致性。如果用户对一致性要求比较高也可以使用 ?version=xxx 的技术,也可以每次上传图片返回的 url 是不同的方式来代替版本号。

CDN 存储的资源复本指定过期时间,因而缓存图像文件可在一个小时,一个月有效的。任何资源缓存在 CDN上,是潜在历史版本,因为在源数据与副本之间总是有一个更新与传输的延迟。

image-20231207172258043

  • Expires

    即在 HTTP 头中指明具体失效的时间(HTTP/1.0

  • Cache Control

    max-ageHTTP 头中按秒指定失效的时间,优先级高于 Expires(HTTP/1.1)

  • Last-Modified / If-Modified-Since

    文件最后一次修改的时间(精度是秒,HTTP/1.0),需要 Cache-Control 过期

  • Etag

    当前资源在服务器的唯一标识(生成规则由服务器决定),优先级高于 Last-Modified

静/动态 CDN 加速

静态 CDN 加速

image-20231207172704086

地理位置分散的用户最小化接收静态内容所需的跳数,直接从附近边缘的缓存中获取内容。结果是显著降低了延迟和数据包丢失,加快了页面加载速度,并大大降低了原始基础架构的负载。

  • 静态域名非主域名(例如api域名和主域名做区分,避免同源策略携带cookie
  • 静态多域名和收敛(PC上多域名可以提高并发,移动端减少域名降低域名请求次数)
  • 静态资源版本化管理(增量发布,避免缓存带来的影响)

动态 CDN 加速

也就是动态数据加速,数据发生变化的时候,通过CDN回源到核心机房,实现加速。

image-20231207172843553

  • TCP优化

    设计算法来处理网络拥堵和包丢失,加快这些情况下的数据从 CDN 的恢复以及一些常见的 TCP 瓶颈

  • Route optimization

    就是优化从源到用户端的请求的线路,以及可靠性,就是不断的测量计算得到更快更可靠的路线。

  • Connection management

    就是边缘和源之间,包括 CDN 之前的线路,采用长连接,而不是每一个请求一个连接(避免源站链接数过多)

  • On-the-fly compression

    就是数据在刚刚离开源的时候就进行压缩,可以缩短在整个网络之中的流通时间。

  • SSL offload

    加速或者说减少一些安全检测,减少原服务器执行这种计算密集型的压力。(在边缘节点分摊)