图片来历:unsplash.com/photos/Q1p7…

作者:念山

布景

随着技能的开展,网络环境也变得越来越复杂,而关于一个以网络数据传输供给服务的 App 来讲,在复杂多变的网络环境下安全安稳有用的供给好服务显得尤为重要。而为了供给安全安稳有用的 HTTP 网络服务,咱们从网络恳求的初始阶段 DNS 解析上确保 DNS 安全性的技能:去分析下苹果2022年 WWDC 讲到的 DNSSEC 技能和咱们云音乐现行的 HTTPDNS 并做下对比。

什么是 DNS

域名体系(Domain Name System,DNS) 则是将域名解析 IP 地址的一项互联网根底服务,供给该服务的服务器称为 域名服务器(Domain Name Server)。

域名(Domain Name,Domain) 是一个在互联网上标识主机或主机组的称号,相当于 IP 地址的别号,相关于晦涩难记的 IP 地址,域名更显得易于回忆。

域名体系是怎么作业的呢

互联网上的域名体系是一个分布式的体系,结构上是一个四层的树状层次结构:

网络安全 DNSSEC & HTTPDNS

  • 本地域名服务器(Local Name Server,local DNS):假如经过 DHCP 装备,local DNS 由互联网服务供给商(ISP,如联通、电信)供给

  • 根域名服务器(Root Name Server):当 local DNS 查询不到解析成果时,第一步会向它进行查询,并获取尖端域名服务器的IP地址。全球一共有 13 个根域名服务器(除了它们的镜像),它们并不直接用于域名解析,仅用于指出可查询的尖端域名服务器。

  • 尖端域名服务器(Top-level Name Server):担任办理在该尖端域名服务器下注册的二级域名,例如**.com 尖端域名服务器**,而 baidu.com 威望服务器是注册在 .com 的威望域名服务器

  • 威望域名服务器(Authoritative Name Server):在特定区域内具有唯一性,担任保护该区域内的域名与 IP 地址的映射联系。在 DNS 应答报文中,标志位 AA 标识本次 DNS 记载是否来自威望域名服务器,不然或许来自缓存

模仿流程

那以咱们主站域名 interface.music.163.com 为例,来看一下 DNS 的进程:

网络安全 DNSSEC & HTTPDNS

  • 0、首先检查 DNS 缓存,假如缓存老化或未命中,客户端需求向 local DNS 发送查询恳求报文

  • 1、客户端向 local DNS 发送查询报文 query interface.music.163.com,local DNS 首先检查本身缓存,假如存在记载则直接回来成果,查询结束;假如缓存老化或未命中,则:

  • 2、local DNS 向根域名服务器发送查询报文 query interface.music.163.com,回来 .com 尖端域名服务器的地址(假如查无记载)

  • 3、local DNS 向 .com 尖端域名服务器发送查询报文 query interface.music.163.com,回来interface.music.163.com地点的威望域名服务器的地址(假如查无记载)

  • 4、local DNS 向 interface.music.163.com 威望域名服务器发送查询报文 query interface.music.163.com,得到 ip 地址,存入本身缓存并回来给客户端

DNS 特色

DNS 从 1983 年规划推出到现在已经在全球运作 40 年了,设备支撑高,可是因为最初规划的时分没有考虑安全相关的问题,报文无鉴权和加密相关的信息,带来了不安稳的因素。

优势

  • 体系支撑
  • 速度快

下风

  • 中间人进犯
    • DNS 诈骗
    • DNS 绑架
  • 结构复杂,中间变数多

针对 DNS 不安全的状况,业界也在经过 DNSSEC、HTTPDNS 等技能计划弥补往来不断确保安全提高服务可用。

什么是 DNSSEC

DNSSEC 能够说是在原有 DNS 根底之上做的扩展。 网域称号体系安全性扩大 (DNSSEC) 可为网域称号的 DNS (网域称号体系) 加上电子签名,藉此判断来历网路称号的真实性。此功能能够保护网路运用者不受编造 DNS 资料的要挟,让运用者要求正确网址时不会获得其他有意误导或歹意制造的网址。

DNSSEC 作业的流程

DNSSEC 经过树立信任链来验证记载

网络安全 DNSSEC & HTTPDNS

举个例子:设备想要解析 www.example.org 并启用 DNSSEC 验证,进程如下:

  • 发送问询 IP 地址、签名和密钥的查询,经过呼应能够树立从 IP 地址到密钥 1 的信任联系

  • 客户端向父区域 org 发送查询,问询可用于验证密钥 1 的记载,树立从密钥 1 到密钥 2 的信任联系

  • 设备递归地重复这个进程,直到它抵达根域

DNSSEC 特色

经过流程总结下来

优势

  • 供给校验确保安全
下风
  • 需求路由器支撑,路由器有必要支撑处理大于正常大小的 DNS 包
    • 正常的 DNS 包大小为 512 字节, DNSSEC 则大于 512 字节,国内较多路由器会丢弃超过 512 字节的 DNS 包
  • 域名注册服务商装备大部分是付费的
  • 云商支撑弱
    • 较多云商不支撑 DNSSEC 解析
    • 支撑 DNSSEC 解析的根本还收费
  • 需求威望服务器支撑
  • 体系兼容差
    • iOS16+ 支撑
    • macOS Ventura 以上才支撑

是否要挑选 DNSSEC?

DNSSEC 计划关于咱们 App 来讲不可控因素太多,且可扩展性较弱所以咱们挑选了一套相同安全,且更为可控的计划– HTTPDNS。

HTTPDNS

相较于 DN S和 DNSSEC,关于客户端来讲有一种可控性更强和更安全的计划:HTTPDNS,而 HTTPDNS 也是咱们云音乐现在正在运行的计划。

什么是 HTTPDNS

DNSOverHTTP,经过 HTTP 报文恳求往来不断拉取 DNS 的成果,客户端拿到成果后拿 IP 替换恳求的 host 并设置 SNI 往来不断进行IP直连的恳求,到达操控恳求目的 IP 挑选的成果,到达同等 DNS 的功能。

HTTPDNS 流程

  • 客户端恳求自己 HTTPDNS 服务器拿到 IP
  • 发恳求替换 host 为对应的 IP
  • 设置 SNI 来添加原始 host 信息

HTTPDNS 特色

优势

  • 可定制化强 : 服务走自己服务器
  • 安全 : 走 https 恳求

下风

  • 相较于 LocalDNS 时间损耗长:因为选用 HTTP 报文往来不断传输 domain 与 IP 的映射表
  • 需求自己处理替换域名的操作。
  • 具有必定的安全危险:iPhone 需求调用私有 API 去设置 SNI

安全危险

一个比较大的危险点是在运用私有 API 往来不断设置 SNI。

在依据现在网络根本运用 NSURLSession 的大布景下,在运用 HTTPDNS 技能的状况下有个重要的一个进程是经过私有 API 来设置 SNI 信息经过 HTTPS 的握手校验。可是私有 API 有随时被封禁的危险,如若被封禁则运用私有 API 来做 SNI 设置的HTTPS恳求都不可用。

怎么来躲避运用私有 API 这个安全危险呢?

核心问题

NSURLSession 无法操控 Socket 衔接,所以只能替换 host 的方法往来不断处理,假如经过操控 Socket 衔接池,就能躲避掉 SNI 的问题

新的网络库

咱们挑选一套新的网络库 Cronet 既能操控 Socket 衔接池,又能带来网络性能相关的提高及网络高级特性的支撑。

IP 跑马

HTTPDNS 拿到的是一个 IP 数组,实际发恳求的时分只需求一个 IP,那到底运用哪个 IP 来进行建连恳求呢?那就需求经过必定的计分标准来给 IP 打分,经过 IP 跑马来拿到最佳 IP。

计分规则

单次恳求的评分

单次恳求评分依照正确恳求和过错恳求两种不同的计分方法来进行处理。

过错评分

把网络过错细分为5个等级,不同等级扣分分值不一样

typedef NS_ENUM(NSInteger, NENetErrorLevel)
{
    NENetErrorLevelNone, // 无过错,不扣分
    NENetErrorLevelDefault, // 默认,扣1分
    NENetErrorLevelisCancel, //撤销不算过错,不扣分
    NENetErrorLevelNormal,  // 普通等级 扣10分
    NENetErrorLevelSerious, // 严峻  扣20分
};
// 把对应的NSURLSession的网络报错对应到过错等级进行评分
- (NENetErrorLevel)errorLevelForError:(NSError *)error
{
    NENetErrorLevel errorLevel =NENetErrorLevelNone;
    BOOL isCancel = NO;
    BOOL isChainError = NO;
    BOOL isTimeout = NO;
    NSError *urlError = error;
    NSInteger errorCode = urlError.code;
    if ([urlError.domain isEqualToString:NSURLErrorDomain] ||
        [urlError.domain isEqualToString:@"AFNetworkingErrorDomain"])
    {
        if (errorCode == NSURLErrorCannotConnectToHost)
        {
            isChainError = YES;
        }
        isTimeout = errorCode == NSURLErrorTimedOut;
        isCancel = errorCode == NSURLErrorCancelled;
    }
    else if ([urlError.domain isEqualToString:NSPOSIXErrorDomain])
    {
        if (errorCode == 54 || //ECONNRESET
            errorCode == 57 || //ENOTCONN
            errorCode == 60 || //ETIMEDOUT
            errorCode == 61 ||
            errorCode == 65
            )   //ECONNREFUSED
        {
            isChainError = YES;
        }
    }
    if (isCancel) {
        errorLevel = NENetErrorLevelisCancel;
    } else if (isChainError) {
        errorLevel = NENetErrorLevelSerious;
    } else if (isTimeout) {
        errorLevel = NENetErrorLevelNormal;
    } else if (error) {
        errorLevel = NENetErrorLevelDefault;
    }
    return errorLevel;
}
正确的评分

正确的评分选用恳求速度往来不断考量分值,挑选基准线速度和时间,在基准线上线浮动进行算分。

耗时<=2.5s 才会去依照基准线进行计算分 耗时>4.5s 开端扣分

// 计算公式
- (double)calcllateSuccessMarkWithDataLength:(NSUInteger)dataLength cost:(NSTimeInterval)cost
{
    if (cost == 0) {
        return 0;
    }
    double mark;
    long delta = 0;
    if (cost <= CALL_TIME_GOOD_BENCH_MARK) { //假如<= 2.25s, 才有积分机会
        delta = CALL_TIME_GOOD_BENCH_MARK - cost;
    } else if (cost > CALL_TIME_BAD_BENCH_MARK) { //假如 > 4.5s, 则开端扣分
        delta = CALL_TIME_BAD_BENCH_MARK - cost;
    }
    // 超时不必定是IP有问题
    //经过耗时维度计算出的mark 最低-5分
    mark = MAX(delta,-5);
    if (dataLength > 0 && mark > 0) {
        double speed = dataLength / (cost + 0.0f);
        if (speed < CALL_SPEED_GOOD_BENCH_MARK) { //利用speed, 将恳求体小的恳求分数降低
            mark = speed / CALL_SPEED_GOOD_BENCH_MARK * mark;
        }
    }
    return mark;
}
IP 总分

IP 总分有两次战略:累计计分、瞬时计分

累计计分

当前网络环境下(WiFi/蜂窝)的所有恳求的分值的加和。

瞬时计分

当前网络环境下(WiFi/蜂窝)的当前恳求的分值就是IP的最终得分。

挑选IP

恳求宣布的时分依据拿到的 IP 组依照 IP 的跑分拿最高分作为当成恳求的 IP。

全体流程图

网络安全 DNSSEC & HTTPDNS

4. 小结与展望

网络安全不容小觑,各大厂商都在极力去经过技能手段往来不断保护网络安全,来给用户供给一个安全可靠的网络环境。咱们也希望苹果在后续能够在DNS相关方面供给更开放可由开发人员往来不断实现战略的 API,在确保网络安全根底上又能让开发人员能有必定的灵活性。针对文中 Cronet 的运用因为还在灰度推动中,等推全后也将梳理篇 Cronet 接入带来的利好及坑点来和咱们交流。

参考资料

[1] WWDC – 10079

[2] DNSSEC 协议

[3] DNS绑架

[4] DNS诈骗

[5] Enable encrypted DNS

[6] Cronet 网络恳求流程

本文发布自网易云音乐技能团队,文章未经授权制止任何方式的转载。咱们终年招收各类技能岗位,假如你预备换作业,又恰好喜欢云音乐,那就参加咱们 grp.music-fe(at)corp.netease.com !