如何在我自己的服务器上设置加密 SNI?

Jos*_*ica 10 ssl virtualhost

我有运行多个虚拟主机的 Web 服务器,我想让窃听者不知道客户端正在访问哪个虚拟主机。已经有一个 TLS 扩展可以解决这个问题:加密 SNI。我看到 Cloudflare 在其服务器上支持它,并且 Firefox 有一个设置可以在客户端上启用它。但是,我找不到有关如何在我自己的服务器上启用此功能的任何文档。我该怎么做呢?(我不依赖于任何特定的服务器堆栈,除了“将其置于 Cloudflare 之后”之外,我将接受任何工作设置/架构。)

Lek*_*eyn 15

加密服务器名称指示 (ESNI) 仍然是 Internet 草案,您不会在任何主要服务器实现中找到它,因为它可能会发生变化。其实Firefox实现的draft版本支持draft-ietf-tls-esni-01,它与较新的草稿版本不兼容。

我在此处发布了 2019 年 4 月观察到的生态系统状态

如您所见,Nginx 和 Apache 使用的 OpenSSL 不支持它。您可以尝试使用打过补丁的 Go 加密/tls 库来构建Caddy(使用tls-tris 中的这个 PR),但随着时间的推移它可能无法正常工作。

实验

出于实验或教育目的,您可以使用tls-tris 中的esnitool 和 tris-localserver 。假设你在 Linux 或 macOS 上安装了合适的 Go 工具链,这样的事情应该可以工作:

# Get source code and build stuff
git clone https://github.com/cloudflare/tls-tris -b pwu/esni
cd tls-tris
make build-esnitool
(cd _dev/tris-localserver && ../go.sh build -v -i .)

# Generate ESNI key material, valid for 24 hours (one day)
_dev/esnitool/esnitool -validity=24h -esni-keys-file=esni.pub -esni-private-file=esni.key
Run Code Online (Sandbox Code Playgroud)

它将创建两个文件:

  • esni.pub -/wFsX6klACQA...AAAA=您必须在 DNS 中配置的值。如果要为 配置 ESNI www.example.com,请_esni.www.example.com使用该/wFsX6klACQA<snip>AAAA=值为其创建 TXT 记录。此格式符合 Firefox 和 Cloudflare 支持的 Draft-ietf-tls-esni-01 规范。它并没有采用最新的规范草案。
  • esni.priv - 专用密钥文件,特定于测试实现。

可以按如下方式启动测试服务器:

_dev/tris-localserver/tris-localserver -esni-keys=esni.pub -esni-private=esni.priv
Run Code Online (Sandbox Code Playgroud)

然后配置 Firefox 以启用使用 ESNI,打开about:config并设置network.security.esni.enabled为 true。您还必须启用 DNS-over-HTTPS,可以在该页面上找到 Firefox 说明。还可以在此处找到有关每个首选项的更多详细信息:https : //bagder.github.io/TRRprefs/

这些说明现在可能有效,但将来会失效,因为 Firefox 可能会更新以支持更新的草稿版本。上面的 esnitool 还对允许的密码套件 (AES128-GCM) 和密钥交换算法 (X25519) 进行了硬编码。这反映了 Cloudflare 使用的参数。

评论

ESNI 暗示 TLS 1.3,因此证书及其嵌入的主机名将被加密。启用 ESNI 并使用安全 DNS 传输,例如 DNS-over-HTTPS (DoH) 或 DNS-over-TLS (DoT),服务器名称确实不会在线上可见,这可以在 Wireshark 中使用过滤器,如frame contains "wireshark"访问时wireshark.org

但是,如果单个 IP 仅托管几个域,则任何被动对手都可以猜测您正在访问其中一个域。Cloudflare 等大型运营商拥有更多的域,这不是什么大问题。

由于 ESNI 使用半静态密钥,私钥泄露意味着任何窃听者都可以解密加密的服务器名称。这就是为什么 ESNI 密钥经常轮换,并且需要自动化的原因。Cloudflare 具有这种集成良好的功能,DNS 中的 ESNI 密钥和 HTTPS 服务会定期更新。

总而言之,ESNI 很有前途,但需要客户端(Web 浏览器)、通过安全传输 (DoH/DoT) 的 DNS 服务器和 Web 服务器的支持。它仍在开发中,除非您密切关注它的开发,否则将它设置为除实验之外的其他用途可能不是一个好主意。