大多数浏览器和
Developer App 均支持流媒体播放。
-
启用加密的DNS
当人们在你的 app 中访问网络时,他们的隐私至关重要。通过在我们的平台上利用加密的 DNS 来保护你的信息,以在你的 app 内提供私人的和安全的连接。了解如何使用系统 DNS 设置连接到加密服务器或使用标准网络 API 在 app 内启用加密 DNS。启用加密 DNS 是你的 app 可以帮助保护客户隐私并为他们提供更好和更安全的体验的另一种方法。
资源
相关视频
WWDC23
WWDC22
WWDC20
-
下载
(你好) (2020全球开发者大会) 大家好 欢迎来到全球开发者大会 (启用加密的DNS) 你好 我是汤米保利 加密的DNS是改善互联网隐私的关键技术 而且 Apple平台原生就支持此技术 是一项让开发者可以为用户 启用的一项底层技术
如果你提供公共DNS服务 你可以写一个app 或者配置简档 让人们使用你加密的DNS服务器
你还可以选择在自己的app中使用 加密的DNS 进行特定连接 在我们深入探讨如何在Apple平台上 使用加密的DNS之前 让我们谈谈什么是DNS 以及为什么这对隐私很重要 DNS的全称是域名系统 它以你在Safari浏览器中看到的 网页的名称命名 并将其转换成互联网上服务器的 实际IP地址
每次你上网时 你的设备都在使用DNS 当你的app访问网站时 系统会询问一个问题 提出一个将名字转换成 一组地址的DNS查询 (www.apple.com在哪里? www.apple.com 在…) 通常 问题发送到一个DNS服务器 且由本地网络配置 那和隐私有什么关系呢? 一个担忧是DNS的问题和答案 通常通过未加密的传输UDP发送 这意味着网络上的其它设备 不仅能看见你在查什么设备名字 它们甚至会干扰答案 另一个隐私问题是 你可能不信任本地网络上的 DNS解析程序 如果你加入了公共无线网络 他人可以跟踪你的互联网使用情况 或者对你封锁 那么加密的DNS如何改善这种情况呢?
简单说的话 加密的DNS 使用加密来保护你的DNS问题和答案 加密传输 而且如果你不信任你的的本地网络 它还可以将你的问题发送到 你信任的DNS服务器
从今年开始 Apple平台原生支持加密的DNS 有两个受支持的协议 TLS上的DNS 也叫DoT 和HTTPS上的DNS 也叫DoH 这两者都使用TLS加密DNS信息 DoH还使用了HTTP协议来提高性能
有两种方法可以启用加密的DNS 第一种方法是选择一台DNS服务器 作为系统上所有app的默认解析程序 如果你提供公共DNS服务器 你现在可以编写NetworkExtension app 用于配置系统使用你的服务器 公共DNS服务提供商 使用MDM的企业 或者 如果你使用移动设备管理 又称MDM 来配置设备的上的企业设置 你可以向下推送配置文件来 配置加密的DNS设置 用于你的网络 启用加密的DNS的第二种方法是 直接从app中选择 如果你想让你的app使用加密的DNS 即使系统的其他部分还没有使用 你可以选择一个特定的服务器 用于app的部分或全部连接 (注重隐私的app 选择特定的服务器) 让我们先看看系统范围的 DNS设置是如何工作的 系统DNS设置可以通过 NetworkExtension app进行配置 它使用NEDNSSettingsManager 或者包含DNSSettings有效负载的 MDM配置文件
这两种方法都允许你指定相同的内容
一种识别要使用的服务器的 DNS服务器配置 以及服务器支持的协议 使用网络扩展的服务器配置 还有一套网络规则 这允许你自定义何时应用你的DNS设置
让我们看看你如何使用NetworkExtension 指定服务器配置
使用共享的NEDNSSettingsManager对象 首先加载任何现存的配置
接下来 你可以为HTTPS上的DNS服务器 或通过TLS上的DNS服务器定义设置
在本示例中 我们使用DoH
你可以提供服务器的IP地址 它们是可选的 而服务器网址是必需的 你应该将此对象设置到 “dnsSettings”属性
然后 你调用saveToPreferences 将配置应用到系统 此时 你可以在设置app中 启动你的DNS服务器
接下来 让我们看一下配置的 网络规则部分 指定网络规则允许你确保你的 DNS设置与不同的网络兼容 DNS系统对于隐私来说非常重要 但是公共DNS服务器不能解析私人域名 如果它们只是本地网络已知的话 例如 只有企业无线网络上的 DNS服务器 才能解析员工访问的某些私有名称 兼容性的某些方面会自动为你处理 对于这些 你不需要指定网络规则 专属网络检测 如有人登录类似餐厅的公共网络时 自动被授予例外权限
同样地 如果启用了VPN VPN通道内的解析将使用 VPN的DNS设置 而不是系统范围的设置
但是 在企业无线网络上 处理私人姓名等情况 需要设置网络规则 你的网络规则可以定义 特定网络类型的行为 比如无线网或蜂窝网络 以及特定的无线网络SSID
在配对的网络上 你可以完全禁用你的DNS设置 或者仅授予特定私有域的例外权限 以下是如何在你的app中 设置一些网络规则的方法 你的app应该允许 用户配置这些类型的规则
要为工作网络创建例外规则 为具有特定SSID的无线网络定义规则 连接规则列表 定义一个域 在本示例中enterprise.example.net 不应该使用你的DNS设置
总的来说 这条规则规定 除了私有企业域之外 你的DNS设置应该用于工作无线网络
你还可以设置规则 使用断开规则在整个网络类别上 禁用你的DNS设置 在这里 我们禁用所有 蜂窝网络上的DNS设置
最后一条规则是你应该要设置 一个catchall 在本示例中 让我们确保默认情况下 你的DNS设置是打开的 这是通过连接规则实现的
你将网络规则存储为有序列表 然后可以保存配置
现在 我们准备好来看一个 DNS设置的app运行实例
下面是一个配置系统范围的 DNS设置的示例项目 在我们的app中 我们使用NEDNSSettingsManager
在此处 我们可以定义服务器配置
我们也可以根据用户偏好设定网络规则 这个特殊的应用程序支持同时在蜂窝网络 或无线网络上启用或禁用
在运行app之前 我们需要确保在XCode中启用了 DNS设置功能 要检查此项 转到你的项目设置
然后转到签名和功能
DNS设置功能是 NetworkExtension功能之一 因为我们正在配置一个 系统支持的协议 我们不需要实施扩展点 我们只需要构建一个app
让我们现在来看看这个app
当我们运行app时 配置已经安装好 但是还没有马上生效
我们可以启用或禁用无线网络 或蜂窝网络上的设置 然后在app设置中启用整个配置
我们转到设置、通用
看看VPN和网络 在这里 有一个DNS的部分 一旦安装了配置 你的app会在这里显示出来 如果你选择你的设置 它们将自动应用于整个系统 如果你回到你的app 现在可以看到配置处于活动状态
这就是你要做的一切 此时 你的DNS设置将应用于 系统上的所有app
请注意 根据策略某些网络可能会 使用加密的DNS服务器进行阻止 这些网络可能试图通过 查看DNS查询来过滤流量 如果发生这种情况 将会把此无线网络标记为隐私警告 app中的连接将会失效 而不会损害你的隐私 如果你不提供整个系统都可以使用的DNS 但是你仍然想在你的app中使用加密的DNS 你可以在整个app中启用加密的DNS 或者只为特定连接启用 无论你使用什么系统API 这种方法都有效 URLSession任务、网络框架连接 或者像getaddrinfo这样的POSIX API 让我们看一下网络框架 启用加密的DNS的方法 你可以使用PrivacyContext选项 你为共享DNS设置的每组连接 都创建一个PrivacyContext
当你需要加密时 你可以提供一个DNS服务器配置作为后备 这意味着任何系统范围的DNS 配置都将优先启用 但是在其它情况下你的app 后备配置将生效 在这里 我们使用DoH服务器的网址
当你为你的连接创建参数时 设置好你之前创建的PrivacyContext
然后 开始连接 它们将使用加密的DNS
你还可以检查在给定的连接上 是否使用了加密的DNS
一旦连接就绪 请求EstablishmentReport
此报告包含解决步骤列表 你可以检查哪个协议用于DNS HTTPS协议、TLS协议 UDP协议或TCP协议 请注意 来自缓存的答案 可能没有任何协议集 如果你想在你的app中使用加密的DNS 你可以配置默认的PrivacyContext
这将你的配置应用于 你的app启动的每个DNS解析
无论是当你使用URLSession任务
还是当你使用较低层的API 比如getaddrinfo
现在 你已经准备好尝试加密的DNS了 如果你提供公共DNS服务 编写一个使用 NEDNSSettingsManager的app 来交付你的设置
如果你有一个企业MDM解决方案 使用配置文件在网络上启用加密的DNS
如果你想直接从你的app中选择 在网络框架中采用PrivacyContexts 有关此主题的更多信息 请访问以下讲座网址 感谢观看 (2020全球开发者大会) (你好) (2020全球开发者大会)
-
-
4:16 - Create a DNS configuration
// Create a DNS configuration import NetworkExtension NEDNSSettingsManager.shared().loadFromPreferences { loadError in if let loadError = loadError { // ...handle error... return } let dohSettings = NEDNSOverHTTPSSettings(servers: [ "2001:db8::2" ]) dohSettings.serverURL = URL(string: "https://dnsserver.example.net/dns-query") NEDNSSettingsManager.shared().dnsSettings = dohSettings NEDNSSettingsManager.shared().saveToPreferences { saveError in if let saveError = saveError { // ...handle error... return } } }
-
6:40 - Apply network rules
// Apply network rules let workWiFi = NEOnDemandRuleEvaluateConnection() workWiFi.interfaceTypeMatch = .wiFi workWiFi.ssidMatch = ["MyWorkWiFi"] workWiFi.connectionRules = [ NEEvaluateConnectionRule(matchDomains: ["enterprise.example.net"], andAction: .neverConnect) ] let disableOnCell = NEOnDemandRuleDisconnect() disableOnCell.interfaceTypeMatch = .cellular let enableByDefault = NEOnDemandRuleConnect() NEDNSSettingsManager.shared().onDemandRules = [ workWiFi, disableOnCell, enableByDefault ]
-
10:47 - Use encrypted DNS with NWConnection
// Use encrypted DNS with NWConnection 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", port: 443) privacyContext.requireEncryptedNameResolution(true, fallbackResolver: .https(url, serverAddresses: [ address ])) } let tlsParams = NWParameters.tls tlsParams.setPrivacyContext(privacyContext) let conn = NWConnection(host: "www.example.com", port: 443, using: tlsParams) conn.start(queue: .main)
-
11:35 - Validate which DNS protocol was used
// Validate which DNS protocol was used import Network conn.requestEstablishmentReport(queue: .main) { report in if let report = report { for resolution in report.resolutions { switch resolution.dnsProtocol { case .https, .tls: print("Used encrypted DNS!”) case .udp, .tcp: print("Used unencrypted DNS") default: // Ignore unknown protocols } } }
-
12:07 - Use encrypted DNS for other APIs
// Use encrypted DNS for other APIs import Network if let url = URL(string: "https://dnsserver.example.net/dns-query") { let address = NWEndpoint.hostPort(host: "2001:db8::2", port: 443) NWParameters.PrivacyContext.default.requireEncryptedNameResolution(true, fallbackResolver: .https(url, serverAddresses: [ address ])) } let task = URLSession.shared.dataTask(with: ...) task.resume() getaddrinfo(...)
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。