在 Firefox 上设置 DoH 和 ECH (ESNI),完成加密浏览的最后一块拼图

Out65
·
·
IPFS

TLS 1.3 是 TLS 很大的一步。它新增的特性中相当令人瞩目的两个,一个是 0-RTT,另一个就是随着 KeyShareEntry 的出现而变为现实的 ESNI (Encrypted SNI,现称 ECH,即 Encrypted Client Hello,下文将以 ECH 指代之)草案。这份草案目前已经有了八个版本(最新的在这里:draft-ietf-tls-esni-08),也受部分浏览器(主要是 Firefox,Chromium 似乎还不太想做)以及部分服务商(主要是 CloudFlare)的支持。

SNI (Server Name Indication) 主要用于同 IP 托管多个域名的情况。在这种情况下,客户端需要告知服务端其所访问的域名,服务端才能回复正确的证书,从而继续 TLS 握手过程。因此,虽然 TLS 使得用户的浏览内容和 HTTP 头都受到加密,第三方无法解密(如果你像 CNNIC 一样能用根证书做中间人攻击,当我没说),但在访问使用了 SNI 的网站时,客户端告知域名的信息需要以明文的形式传递。这是一个鸡生蛋、蛋生鸡的问题:没有域名就无法发送证书,而没有证书就不能进行加密。此时,中间人便可以从 SNI 信息获取客户端所访问的域名,从而进行相应的处理(例如拦截)。这也是 SNI 封锁的原理。有了 ECH 的加持,HTTP 的整个过程就都被 TLS 等组件保护,变得全副武装。因此,也有人说 ECH 是加密浏览的最后一块拼图。

基于国家安全和网络主权原因,在某些国家和地区, ECH 已经全部被封锁。不过,不受此影响的用户可以继续往下看。

那 ECH 的加密是怎么来的?

没有 SNI,就没有服务器证书,那 ECH 考靠什么进行身份验证和加密呢?答案是 DNS。DoH (DNS over HTTPS) 和 DoT (DNS over TLS) 的广泛应用已经使 DNS 请求的机密性和完整性 (integrity) 得到了良好的保护。因此,在 DoH 和 DoT 下, DNS 可以被认为是安全和私密的。在这种背景下,近期的一个新草案 DNS SVCB 和 HTTPS RR (draft-ietf-dnsop-svcb-https-01) 推出了一些基于 DNS 进行查询的扩展。 ECH 就利用了这个扩展,通过 DNS 查询得到的信息和服务器建立加密信道。这两个草案蛮复杂的,这里就不展开讲了。

上手 ECH

配置 DNS over HTTPS

前文说到,为了实现 ECH,浏览器需要一些 DNS 扩展。考虑到操作系统一般没有除了获取 IP 地址(getaddrinfo())之外的 DNS 相关 API,Firefox 另辟蹊径,通过其添加的 DNS over HTTPS 支持来实现自己需要的功能。因此,为了开启 ECH,需要先启用 DNS over HTTPS。

这并不复杂。在设置页面(about:preferences)搜索 DNS,点击「网络设置」一节的设置按钮,翻到最底下,就能看到 DNS over HTTPS 的设定。

开启 DNS over HTTPS

在这里,可以按照自己的喜好选择 DNS 服务提供商。如果对隐私有担忧,可以选择一些其它的 DoH 提供商,而不是那个位于美国的世界最大 MitM 公司

开启 ECH

这个比较简单。在 about:config 搜索条目 network.security.esni.enabled,将其设定改为 true 即可。

测试

配置完成后(可能需要重新启动浏览器),可以访问 https://www.cloudflare.com/ssl/encrypted-sni/ ,按下 “Check My Browser” 按钮,就可以测试自己是否开启了 ECH (Encryped SNI) 了。

“Your browser encrypted the SNI...”

常见问题

Cloudflare 提醒我 ESNI 未启用!

可能是你的 DNS over HTTPS 并没有生效,Firefox 还在使用普通的 DNS 请求方式。这种情况下 ECH 无法工作。

你可以尝试按照 Mozilla Wiki 的指示,在 about:config 中将 network.trr.mode设置为 3,即只使用 TRR(也就是我们的 DNS over HTTPS),强制 Firefox 使用 DoH,这样就能确保使用 ESNI 了。

我按上条开启了 DoH only,但有的网站无法访问了!

主要有两种情况:

  • Firefox 默认不会接受通过 DoH 解析得来的本地地址结果([1], [2])。对于这种情况,在 about:config 中将 network.trr.allow-rfc1918 设置为 true 即可。
  • 如果你使用默认的 Cloudflare DNS,并且访问的是 archive.is 的话:包括 archive.is 在内的少数网站要求对其服务器 IP 进行查询的客户端支持 ECS 拓展,以提供最优化的解析结果,而 Cloudflare DNS 出于隐私原因故意不支持 ECS。两边无法调和,于是使用 Cloudflare DNS 的用户就无法访问这些站点了(除非更换 DNS 服务器)。

本文为 Blog 上原文稍作修改后的版本。所有修改均以 Blog 原文为准。由于 IPFS 的不可变性,Matters 的副本无法更新。欲查看原文,请参见 Re:Linked
本文以 CC BY-NC-SA 4.0 协议发布。


CC BY-NC-ND 2.0 授权

喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!