DNS 揭秘:破解网络魔法的挑战与对策

491 阅读7分钟

穿越网络的魔法:DNS揭秘

在我们平凡日常生活的背后,存在着一个非凡的网络世界,这是互联网的奇妙之地,让我们能够轻松地连接全球的信息和知识。在这其中,DNS(Domain Name System,域名系统)就扮演着连接现实与虚拟的关键桥梁,就像是网络世界的交通指挥官,引导着我们从一个地方到另一个地方。

DNS的魔法之源:地点变换的艺术

要想理解DNS,首先得知道,互联网的一个基本单位叫做“IP地址”——没错,就是那些看起来复杂、由几个数字组成的地址,像是192.168.1.1这样的。然而,让我们用人类的语言(网址)来和电脑的语言(IP)交流,就出现了DNS这个翻译官。

作用: 当你输入网址,比如www.google.com,DNS会将这个网址翻译成电脑可以理解的IP地址(比如216.58.222.147),这样你的设备就知道了去哪找你需要的信息。

魔法之旅:DNS的工作流程

  1. 欢迎来到起始点:当你在浏览器输入一个网址,就如同你吹响了召唤魔法的号角,你的设备会通过一个称为“DNS请求”的指令,询问“这个网址对应的IP地址是什么?”。
  2. 传送到DNS缓存:设备会先查看自己或者ISP(互联网服务提供商)的DNS缓存,看看是否已经有个答案。如果找到了,立刻起程前往目的地。如果没有,魔法继续。
  3. 寻找域名服务器:若缓存里没有答案,请求将被发送到本地的DNS服务器。这些服务器是网络世界里的智慧之书,存储着大量已翻译好的网络地址。
  4. 根域名服务器的指示:如果本地服务器也没找到答案,它会联络根域名服务器——这些是最高级别的服务器,它们指引着通往所有域名的路线图。基于你请求的顶级域名(.com,.org,.net等),根服务器会指引请求到下一个节点:域名服务器。
  5. 权威解决方案:域名服务器是特定域名的专家,它们能给出最终的答案。找到答案后,这一信息不仅会返回给你的设备,同时也会在本地服务器进行缓存,方便未来的请求直接找到答案,无需踏上全程的旅途。

魔法的挑战与实干家

然而,就像所有的魔法一样,DNS也不是完全没有挑战,

  • 延迟:过多的请求或不稳定的网络可能造成响应时间的延迟,影响你享受网络世界的流畅体验。
  • 安全性:网络世界的黑暗力量(黑客、恶意软件)有时会试图误导DNS请求,引导你前往错误的地方,这称为“DNS劫持”或“DNS欺骗”。

如何应对 DNS 劫持的挑战

在网络安全的领域中,DNS 劫持(DNS Hijacking)被视为一个棘手的难题,它通过篡改 DNS 查询结果,将用户引导至恶意网站,从而对网络安全构成威胁。在 iOS 平台上,工程师们采用 HttpDNS 技术来抵御 DNS 劫持的威胁,以提供更安全、更快速的网络体验。然而,这一方法在实施过程中引发了新的技术挑战,特别是针对证书验证和 SNI(Server Name Indication)的问题。

解决证书验证难题

当客户端使用 HttpDNS 解析域名时,请求 URL 中的 Host 字段被替换成由 HttpDNS 解析出的 IP 地址,这导致了证书验证过程中的域名不匹配问题,进而影响 SSL/TLS 握手的完成。为解决这一挑战,通常的做法是在请求头中补充 Host 字段,以确保证书验证过程中域名与证书中预期域名的一致性,确保网络通信的安全性与合规性。

SNI 问题的解决策略

SNI(Server Name Indication)是为了解决一个服务器使用多个域名和证书的 SSL/TLS 扩展,它允许客户端在建立 SSL 连接前发送目标域名,从而服务器可以返回正确的证书。然而,在 HttpDNS 场景下,请求 URL 中的域名被替换为 HttpDNS 解析出的 IP 地址,导致服务器端无法正确识别域名,进而无法返回正确的证书,或返回默认证书,导致 SSL/TLS 握手失败。

为解决 SNI 的问题,有以下两种主流方案:

  1. 自定义 NSURLProtocol 实现:此方法涉及重写请求流程,确保 SNI 信息的正确传递至服务器。虽然这种方法能有效解决 SNI 问题,但它无法解决 WKWebView 的 SNI 问题,因为 WKWebView 在独立进程中处理请求,这使得自定义 NSURLProtocol 在此场景下失效。
  2. 使用原生支持设置 SNI 字段的更底层的库:选择这一方案意味着使用支持自定义 SNI 字段的底层网络库,如 OpenSSL 或者更现代的网络库。这种方法能够更为直接地处理 SNI 信息,确保服务器能正确匹配并提供相应的证书,避免因域名与证书不匹配导致的 SSL/TLS 握手失败。

然而,对于 WKWebView 的 SNI 问题,目前参考阿里巴巴、腾讯等公司的解决方案是使用私有 API。使用私有 API 虽能解决 SNI 问题,但存在潜在的兼容性和安全风险,因为私有 API 的使用可能会在未来的系统更新中导致应用的不兼容问题。

其他问题与解决方案

除了证书验证和 SNI 问题外,诸如 AVPlayer 等其他组件也可能遇到相似的问题,需要专门设计解决方案,以确保网络通信的安全性与稳定性。

简单的加密 DNS 方案:利用 iOS 14 之后的 DOH 支持

自 iOS 14 起,苹果原生支持 DNS over HTTPS(DOH),这是一种能加密 DNS 查询的现代技术,显著增强了 DNS 查询的安全性和隐私性。通过使用 Swift 中的 Network 框架,你可以轻松实现 DNS 加密,确保网络通信的隐私安全。

实现加密 DNS 的 Swift 代码示例

下面的代码示例展示了如何使用 Network 框架对连接进行 DNS 加密:

import Network

let privacyContext = NWParameters.PrivacyContext(description"EncryptedDNS")
if let url = URL(string"https://dnsserver.example.net/dns-query") {
   let address = NWEndpoint.hostPort(host"2001:db8::2"port443)
   privacyContext.requireEncryptedNameResolution(true,
      fallbackResolver: .https(url, serverAddresses: [ address ]))
}

let tlsParameters = NWParameters.tls
tlsParameters.setPrivacyContext(privacyContext)

let connection = NWConnection(host"www.example.com"port443using: tlsParameters)
connection.start(queue: .main)

验证 DOH 使用情况

为了确保 DNS 查询采用了加密方式,你可以使用以下代码片段进行检测:

import Network

connection.requestEstablishmentReport(queue: .main) { report in
  guard let report = report else { return }
  for resolution in report.resolutions {
    switch resolution.dnsProtocol {
    case .https, .tls:
      print("加密的 DNS 正在使用中!")
    case .udp, .tcp:
      print("DNS 通信未加密。")
    default:
        // 忽略或处理未知协议
        print("未知的 DNS 协议。")
     }
  }
}

通过以上详尽的介绍与实践指南,不仅对 DNS 劫持的挑战有了更深入的了解,还掌握了在 iOS 平台下应对这些挑战的具体方法,包括如何利用最新技术如 DOH 保护你的网络通信,确保网络数据的隐私与安全,从而在网络的海洋中航行得更加安全、自由。

在面对 DNS 劫持的挑战时,工程师们必须采取综合的策略,包括但不限于 HttpDNS 的使用,以及对证书验证、SNI 问题的深入理解与恰当处理。同时,紧跟技术前沿,采用如 DNS over HTTPS 这样的现代技术,可以显著提升网络通信的安全性,保护用户隐私,确保网络服务的可靠与安全。