HTTPS 上的 DNS(可信递归解析器)¶
术语¶
HTTPS 上的 DNS (DoH) 允许以增强的隐私、安全的传输和相当的性能来解析 DNS。该协议在 RFC 8484 中进行了描述。
可信递归解析器 (TRR) 是 Firefox 对该协议的实现以及 策略 的名称,该策略确保 Firefox 仅推荐尊重隐私的 DoH 提供商。
在本页中,我们将在引用协议时使用 DoH,在引用实现时使用 TRR。
未加密的 DNS (Do53) 是大多数程序解析 DNS 名称的常规方式。这通常由操作系统通过向通常侦听端口 53 的 DNS 服务器发送未加密的数据包来完成。
DoH 推出¶
DoH 推出 指的是前端代码,该代码决定是否会自动为 推出人群 中的用户启用 TRR。
此模块的功能在此处进行了描述 此处。
代码位于 browser/components/doh 中。
实施¶
启用后,TRR 可以以两种模式工作,TRR-first (2) 和 TRR-only (3)。这些由 network.trr.mode 或 doh-rollout.mode 首选项控制。区别在于,当 DoH 请求在 TRR-first 模式下失败时,我们会回退到 Do53。
对于 TRR-first 模式,我们有一个严格回退设置,可以通过将 network.trr.strict_native_fallback 设置为 true 来启用。这样,虽然我们仍然会完全跳过某些请求的 TRR(例如受限门户检测、引导 TRR 提供商等),但我们只会由于三个可能的原因在 TRR 失败后回退到 Do53
我们通过确认检测到 TRR 当前在网络上处于停用状态。这可能意味着提供商已关闭或被阻止。
通过 TRR 成功解析的地址无法连接。
TRR 结果为 NXDOMAIN。
当 DNS 解析不使用 TRR 时,我们通常会以 TRRSkippedReason 的形式保留这些数据。每个数据的详细说明可在 此处 获得。
在其他情况下,我们不会回退,而是会触发新的确认(这将启动我们与提供商的新连接)并再次尝试使用 TRR 进行查找。我们只重试一次。
DNS 名称解析在 nsHostResolver::ResolveHost 中执行。如果找不到请求的缓存响应,nsHostResolver::NameLookup 将触发 DoH 或 Do53 请求。首先,它检查请求的有效 TRR 模式,因为请求可能与全局模式不同。如果请求可以使用 TRR,那么我们在 nsHostResolver::TrrLookup 中分派请求。由于我们通常解析 IPv4 和 IPv6 名称,因此会创建一个 TRRQuery 对象来执行并组合这两个响应。
完成后,将调用 nsHostResolver::CompleteLookup。如果 DoH 服务器返回有效响应,我们将使用它,否则我们在 TRR-only 模式下报告错误,或在 TRR-first 模式下尝试 Do53。
TRRService 控制该功能的全局状态和设置。每个单独的请求都由 TRR 类执行。
由于 Firefox 中的 HTTP 通道通常在主线程上工作,因此 TRR 使用称为 TRRServiceChannel 的特殊实现来避免主线程上的拥塞。
动态黑名单¶
为了提高性能,TRR 服务会管理一个动态黑名单,用于无法使用 DoH 解析但可以使用本地解析器解析的主机名。黑名单中的条目在一分钟内不会通过 DoH 重试(请参阅 network.trr.temp_blocklist_duration_sec 首选项)。当将域添加到黑名单时,我们还会检查其父域是否有 NS 记录,如果有,我们会将其添加到黑名单中。此功能由 network.trr.temp_blocklist 首选项控制。
TRR 确认¶
TRR 请求通常具有 1.5 秒的超时时间。如果由于某种原因我们没有在该时间内收到响应,我们将回退到 Do53。为了避免在 DoH 服务器不可访问时所有请求都出现此延迟,我们执行确认检查。如果检查失败,我们得出结论,服务器不可用,并将直接使用 Do53。确认检查会定期重试以检查 TRR 连接是否再次正常工作。
确认状态具有以下值之一
CONFIRM_OFF:TRR 已关闭,因此服务未处于活动状态。
CONFIRM_TRING_OK:TRR 已打开,但我们尚不确定 DoH 服务器是否可访问。我们乐观地尝试通过 DoH 进行解析,并在 1.5 秒后回退到 Do53。在此状态下,TRRService 将执行对 DoH 服务器的 NS 记录请求作为连接检查。根据成功的响应,它将过渡到 CONFIRM_OK 或 CONFIRM_FAILED 状态。
CONFIRM_OK:TRR 已打开,并且我们已确认 DoH 服务器的行为足够。将对所有请求使用 TRR(并在超时、NXDOMAIN 等情况下回退到 Do53)。
CONFIRM_FAILED:TRR 已打开,但 DoH 服务器不可访问。我们要么没有网络连接,要么服务器已关闭。我们不会在此状态下执行 DoH 请求,因为它们肯定会失败。
CONFIRM_TRYING_FAILED:这等同于 CONFIRM_FAILED,但当我们定期检查 DoH 服务器是否可访问时,我们将进入此状态。
CONFIRM_DISABLED:如果浏览器处于 TRR-only 模式,或者通过首选项显式禁用确认,我们将处于此状态。
确认的状态机在 TRRService.cpp 中的 HandleConfirmationEvent 方法中定义。
如果启用了严格回退模式,确认将设置一个标志以刷新我们与提供商的连接。
排除的域¶
某些域永远不会通过 TRR 解析。这包括
network.trr.builtin-excluded-domains 首选项中列出的域(通常是等于或以 localhost 或 local 结尾的域)
network.trr.excluded-domains 首选项中列出的域(由用户选择)
网络的 DNS 后缀的子域(例如,如果网络具有 lan 后缀,则 computer.lan 等域将不使用 TRR)
Firefox 为检查受限门户的存在而发出的请求
Firefox 为检查网络的 IPv6 功能而发出的请求
/etc/hosts 中列出的域
转向¶
一小部分 TRR 提供商仅在某些网络上可用。检测在 DoHHeuristics.sys.mjs 中执行,然后调用 TRRService::SetDetectedURI。这会导致 Firefox 使用特定于网络的 TRR 提供商,直到网络发生更改。
用户选择¶
TRR 功能旨在优先考虑用户选择而不是用户代理决策。这意味着用户可以通过将 network.trr.mode 设置为 5(TRR-disabled)来显式禁用 TRR,并且 doh-rollout 不会覆盖用户设置。用户对 TRR URL 或 TRR 模式的更改将禁用启发式使用用户配置的设置。