Enable encrypted DNS
Privacy & Security 进阶 20m

启用加密 DNS

Enable encrypted DNS

2020年6月25日

在 Apple 官方观看视频

一句话判断

加密 DNS(DoH/DoT)不是黑科技,但 iOS 14 让它变成了一行配置的事——如果你的 App 处理敏感网络通信,没有理由不启用。

这场 Session 讲了什么

传统 DNS 查询是明文的,网络中的中间人(ISP、Wi-Fi 管理员)可以看到你访问了哪些域名。加密 DNS 通过 DNS-over-HTTPS(DoH)或 DNS-over-TLS(DoT)加密 DNS 查询,提升了用户隐私保护。

iOS 14 引入了两种启用加密 DNS 的方式。系统级别:用户可以在设置中配置加密 DNS 服务器(通过安装配置描述文件)。App 级别:开发者可以通过 Network framework 的 NWParameters 指定加密 DNS 服务器。

Session 详细讲解了如何使用 NWParameters.PrivacyProxies 配置加密 DNS,以及如何处理降级场景(当加密 DNS 不可用时回退到普通 DNS)。还介绍了如何通过 NEDNSProxyProvider 创建自定义的 DNS 代理。

值得深挖的点

加密 DNS 只解决了 DNS 查询的隐私问题。 DNS 查询加密后,中间人看不到你查询了哪个域名,但后续的 HTTPS 连接中 SNI(Server Name Indication)仍然是明文的。完整的隐私保护还需要 Encrypted Client Hello(ECH)等更前沿的技术。不过,加密 DNS 已经覆盖了大部分隐私场景。

App 级别 vs 系统级别的加密 DNS。 App 级别通过代码配置,只对 App 自身的网络请求生效。系统级别通过配置描述文件,对所有 App 的网络请求生效。如果你的 App 处理敏感数据(如医疗、金融),建议在 App 级别显式启用加密 DNS。

代码片段

import Network

// 使用加密 DNS 创建网络连接
func createEncryptedConnection(to host: String, port: UInt16) -> NWConnection {
    // 创建 DNS-over-HTTPS 配置
    let dnsServerURL = URL(string: "https://dns.google/dns-query")!
    let encryptedDNS = NWRemoteDNSOverHTTPS(
        serverAddress: NWEndpoint.hostPort(
            host: "dns.google",
            port: 443
        ),
        serverURL: dnsServerURL
    )
    
    // 配置连接参数
    let parameters = NWParameters()
    parameters.requiresDNSOverHTTPS = true
    parameters.dnsOverHTTPS = encryptedDNS
    
    let connection = NWConnection(
        host: NWEndpoint.Host(host),
        port: NWEndpoint.Port(rawValue: port)!,
        using: parameters
    )
    
    return connection
}
// 使用 URLSession 配置加密 DNS(iOS 14 新增)
func createSecureSession() -> URLSession {
    let config = URLSessionConfiguration.default
    
    // 指定加密 DNS 服务器
    // 通过 NetworkExtension 配置或系统描述文件
    config.requiresDNSSECValidation = true
    
    return URLSession(configuration: config)
}
// 检查当前网络的 DNS 加密状态
import Network

let monitor = NWPathMonitor()
monitor.pathUpdateHandler = { path in
    if path.usesInterfaceType(.wifi) {
        // 在 Wi-Fi 网络上,检查是否启用了加密 DNS
        print("当前 Wi-Fi 网络的 DNS 状态")
    }
}
monitor.start(queue: DispatchQueue.global())

最佳实践

  • 处理敏感数据的 App 应该显式启用加密 DNS。 不要依赖用户的系统设置,在 App 级别配置更可靠。
  • 准备降级方案。 加密 DNS 服务器可能不可用,确保你的网络层能优雅地处理超时和回退。
  • 选择可信的 DNS 提供商。 你把 DNS 查询加密发送给 DNS 提供商,所以提供商本身的隐私政策同样重要。
  • 测试在受限网络环境下的表现。 某些企业网络可能拦截 DoH/DoT 流量。

还有什么值得关注

  • iOS 14 设置中用户可以手动配置加密 DNS 服务器
  • 配置描述文件可以批量部署加密 DNS 设置
  • NEDNSProxyProvider 允许创建自定义的 DNS 代理(如广告拦截)
  • 加密 DNS 对 App 的网络性能影响极小(首次连接多一次往返)
WWDC 2020