自动 HTTPS
Caddy 是首个也是唯一一个能自动且默认使用 HTTPS 的 Web 服务器。
自动 HTTPS 会为你所有站点配置 TLS 证书并保持其续期。它还会为你将 HTTP 重定向到 HTTPS!Caddy 使用安全且现代的默认值 —— 无需停机、额外配置或单独工具。
下面是一个 28 秒的视频,演示它的工作方式:
目录:
概览
默认情况下,Caddy 对所有站点都使用 HTTPS 提供服务。
- Caddy 使用自签名证书为 IP 地址和本地/内部主机名提供 HTTPS,这些证书会在本地自动被信任(如果允许的话)。
- 例如:
localhost、127.0.0.1
- 例如:
- Caddy 使用来自公共 ACME 证书颁发机构(如 Let's Encrypt
或 ZeroSSL
)的证书为公共 DNS 名称提供 HTTPS。
- 例如:
example.com、sub.example.com、*.example.com
- 例如:
Caddy 会维护所有受管理证书的续期,并自动将 HTTP(默认端口 80)重定向到 HTTPS(默认端口 443)。
关于本地 HTTPS:
- Caddy 可能会提示输入密码以将其唯一的根证书安装到你的信任存储中。每个根只会提示一次;你随时可以移除它。
- 任何未信任 Caddy 根 CA 证书的客户端访问站点时都会显示安全错误。
关于公共域名:
- 如果你的域名的 A/AAAA 记录指向你的服务器,
- 端口
80和443在外部开放, - Caddy 能绑定到这些端口(或者这些端口被转发到 Caddy),
- 你的 数据目录 可写且持久,
- 且你的域名在配置中某处出现,
那么站点将自动通过 HTTPS 提供服务。你无需再做其它任何事。就是这么简单!
因为 HTTPS 利用了共享的公共基础设施,作为服务器管理员,你应当阅读本页的其余信息,以便避免不必要的问题、在问题发生时进行故障排查,并正确配置高级部署。
激活
当 Caddy 知道它要提供服务的域名(即主机名)或 IP 地址时,会隐式激活自动 HTTPS。根据你如何运行或配置 Caddy,有多种方法可以告知 Caddy 你的域名/IP:
以下任何情况都会阻止自动 HTTPS 被激活,全部或部分地:
- 通过 JSON 或 Caddyfile 显式禁用它
- 配置中未提供任何主机名或 IP 地址
- 仅在 HTTP 端口上监听
- 在 Caddyfile 中将 站点地址 前缀为
http:// - 手动加载证书(除非设置了
ignore_loaded_certificates)
特殊情况:
- 以
.ts.net结尾的域名将不会由 Caddy 管理。相反,Caddy 会在握手时自动尝试从本地运行的 Tailscale实例获取这些证书。这要求在你的 Tailscale 帐户中启用了 HTTPS 功能
,且 Caddy 进程必须以 root 身份运行,或你必须配置
tailscaled以授予你的 Caddy 用户获取证书的权限。
作用
当自动 HTTPS 被激活时,会发生以下情况:
自动 HTTPS 永远不会覆盖显式配置,它只会增强配置。
如果你已经有一个在 HTTP 端口上监听的服务器,HTTP->HTTPS 的重定向路由会在使用 host matcher 的你的路由之后插入,但会在用户定义的 catch-all 路由之前。
如果必要,你可以自定义或禁用自动 HTTPS;例如,你可以跳过某些域名或禁用重定向(在 Caddyfile 中,通过全局选项 来实现)。
主机名要求
如果主机名满足以下条件,则所有主机名(域名)都有资格获得完全托管的证书:
- 非空
- 仅由字母数字、连字符、点和通配符(
*)组成 - 不以点开头或结尾(RFC 1034)
此外,如果主机名满足以下条件,则有资格获得公共受信任的证书:
- 不是 localhost(包括
.localhost、.local、.internal和.home.arpa顶级域) - 不是 IP 地址
- 仅在最左侧标签使用单个通配符
*
本地 HTTPS
Caddy 对所有在配置中指定了主机(域名、IP 或主机名)的站点自动使用 HTTPS,包括内部和本地主机。有些主机要么并非公共的(例如 127.0.0.1、localhost),要么通常不符合公共受信任证书的资格(例如 IP 地址 —— 虽然可以为它们获取证书,但只有部分 CA 支持)。这些站点仍然会通过 HTTPS 提供服务,除非被禁用。
为了为非公共站点提供 HTTPS,Caddy 会生成自己的证书颁发机构(CA)并使用它来签发证书。信任链由根证书和中间证书组成。叶证书由中间证书签发。它们存储在 Caddy 的数据目录 下的 pki/authorities/local 中。
Caddy 的本地 CA 由 Smallstep 库 提供支持。
本地 HTTPS 不使用 ACME,也不执行任何 DNS 验证。它仅在本机上工作,并且只有在安装了该 CA 的根证书的地方才被信任。
根 CA
根的私钥使用加密安全的伪随机源唯一生成,并以有限权限持久化到存储中。它仅在执行签名任务时加载到内存,之后便离开作用域以便垃圾回收。
尽管 Caddy 可以配置为直接用根签名(以支持不合规的客户端),但默认情况下这是禁用的,根密钥仅用于签发中间证书。
第一次使用根密钥时,Caddy 会尝试将其安装到系统的本地信任存储中。如果没有权限,它会提示输入密码。如果不希望此行为,可在配置中禁用它。如果由于以非特权用户运行而导致安装失败,你可以以特权用户重试运行 caddy trust。
在安装了 Caddy 的本地根 CA 后,你会在本地信任存储中看到它名为 “Caddy Local Authority”(除非你配置了其他名称)。如果愿意,你可以随时卸载它(caddy untrust 命令可以轻松完成此操作)。
请注意,将证书自动安装到本地信任存储只是为了方便,并不能保证在所有情况下都能成功,特别是当使用容器或以非特权系统服务运行 Caddy 时。最终,如果你依赖内部 PKI,确保 Caddy 的根 CA 正确添加到必要的信任存储是系统管理员的责任(这超出了 Web 服务器的范围)。
中间 CA
还会生成一个中间证书和私钥,用于签发叶(单个站点)证书。
与根证书不同,中间证书的有效期更短,并会在需要时自动续期。
测试
要测试或试验你的 Caddy 配置,请确保将 ACME 端点更改为暂存或开发 URL,否则你可能会触及速率限制,导致最多一周的时间内无法访问 HTTPS(具体取决于你触及的是哪种速率限制)。
Caddy 的默认 CA 之一是 Let's Encrypt ,它有一个暂存端点
不受相同的速率限制
约束:
https://acme-staging-v02.api.letsencrypt.org/directory
ACME 挑战
获取公共受信任的 TLS 证书需要由受信任的第三方机构进行验证。如今,这一验证过程通过 ACME 协议 自动化,并可以通过三种方式之一(“挑战类型”)来执行,下面进行说明。
前两种挑战类型默认启用。如果启用了多个挑战,Caddy 会随机选择其中一种以避免对某一种挑战产生意外依赖。随着时间推移,Caddy 会学习哪种挑战类型最成功,并会优先尝试该种类型,但在必要时会回退到其他可用的挑战类型。
HTTP 挑战
HTTP 挑战会对候选主机名的 A/AAAA 记录执行权威 DNS 查找,然后在端口 80 上通过 HTTP 请求一个临时的加密资源。如果 CA 看到了预期的资源,则会签发证书。
此挑战要求端口 80 可从外部访问。如果 Caddy 无法在端口 80 上监听,则必须将来自端口 80 的数据包转发到 Caddy 的 HTTP 端口。
此挑战默认启用且不需要显式配置。
TLS-ALPN 挑战
TLS-ALPN 挑战会对候选主机名的 A/AAAA 记录执行权威 DNS 查找,然后在端口 443 上通过包含特殊 ServerName 和 ALPN 值的 TLS 握手请求一个临时的加密资源。如果 CA 看到了预期的资源,则会签发证书。
此挑战要求端口 443 可从外部访问。如果 Caddy 无法在端口 443 上监听,则必须将来自端口 443 的数据包转发到 Caddy 的 HTTPS 端口。
此挑战默认启用且不需要显式配置。
DNS 挑战
DNS 挑战会对候选主机名的 TXT 记录执行权威 DNS 查找,并查找具有特定值的特殊 TXT 记录。如果 CA 看到了预期的值,则会签发证书。
此挑战不要求打开任何端口,请求证书的服务器也不需要可从外部访问。然而,DNS 挑战需要配置。Caddy 需要知道访问你域名的 DNS 提供商的凭据,以便它可以设置(并清除)特殊的 TXT 记录。如果启用了 DNS 挑战,其他挑战默认会被禁用。
由于 ACME CA 在查找用于挑战验证的 TXT 记录时遵循 DNS 标准,你可以使用 CNAME 记录将回答挑战的权责委派给其他 DNS 区域。这可用于将 _acme-challenge 子域委派给另一个区域。如果你的 DNS 提供商没有提供 API,或未被 Caddy 的某个 DNS 插件支持,这一点尤其有用。
DNS 提供商支持是社区协作的成果。在我们的维基上了解如何为你的提供商启用 DNS 挑战。
按需 TLS
Caddy 开创了一项我们称之为 按需 TLS(On-Demand TLS) 的新技术,该技术在首次需要证书的 TLS 握手期间动态获取新证书,而不是在配置加载时获取。关键是,这并不要求你在配置中预先硬编码域名。
许多企业依赖此独特功能来在为数万个站点提供服务时以更低成本并免去运维痛苦地扩展其 TLS 部署。
按需 TLS 有用的场景包括:
- 在启动或重新加载服务器时,你并不知道所有域名,
- 域名可能并不会立即正确配置(DNS 记录尚未设置),
- 你不控制这些域名(例如,它们是客户的域名)。
当启用按需 TLS 时,你无需在配置中指定域名即可为其获取证书。相反,当接收到一个 TLS 握手,其中的服务器名(SNI)是 Caddy 尚无证书的域名时,该握手会被挂起,同时 Caddy 会获取一个证书用来完成握手。延迟通常只有几秒,并且只有最初的握手较慢。所有后续握手都很快,因为证书会被缓存和重用,并且续期在后台进行。未来的握手可能会触发证书维护以保持其续期,但只要证书尚未过期,这些维护会在后台进行。
使用按需 TLS
按需 TLS 必须既被启用又被限制以防止滥用。
在使用 JSON 配置时,通过 TLS 自动化策略 启用按需 TLS;如果使用 Caddyfile,则在站点块中使用 tls 指令来启用 在站点块中使用 TLS 指令。
为防止滥用此功能,你必须配置限制。这在 JSON 配置的 automation 对象 中完成,或在 Caddyfile 的全局选项 on_demand_tls 中完成。限制是“全局”的,无法按站点或按域名进行配置。主要的限制是一个 “ask” 端点,Caddy 将向该端点发送 HTTP 请求,以询问是否被允许为握手中的域名获取并管理证书。这意味着你需要一些内部后端,例如可以查询你数据库中的帐户表,查看某个客户是否已注册该域名。
注意你的 CA 签发证书的速度。如果签发需要超过几秒,这将对用户体验造成负面影响(仅首次客户端会受影响)。
由于其延迟性质和为防止滥用所需的额外配置,我们建议仅在确实符合上述用例时才启用按需 TLS。
参见我们的维基文章,了解有关有效使用按需 TLS 的更多信息。
错误
在证书管理出现错误时,Caddy 会尽力继续运行。
默认情况下,证书管理在后台执行。这意味着它不会阻塞启动或减慢站点速度。然而,这也意味着服务器在所有证书可用之前就会运行。后台运行使 Caddy 能够以指数退避的方式在较长时间内重试。
如果获取或续期证书出现错误,处理流程如下:
- Caddy 在短暂停后重试一次,以防是偶发问题
- Caddy 暂停片刻,然后切换到下一个启用的挑战类型
- 在尝试了所有启用的挑战类型后,它会尝试下一个配置的颁发者
- Let's Encrypt
- ZeroSSL
- 在尝试了所有颁发者后,它会以指数退避方式退回
- 重试间隔最长为 1 天
- 持续时间最长为 30 天
在与 Let's Encrypt 重试期间,Caddy 会切换到它们的暂存环境 以避免速率限制问题。这并不是完美的策略,但总体上有帮助。
ACME 挑战至少需要几秒钟的时间,内部速率限制有助于减轻意外滥用。除了你或 CA 配置的速率限制外,Caddy 还使用内部速率限制,以便即使你给 Caddy 一大堆域名,它也会逐步 —— 但尽可能快速地 —— 为所有域名获取证书。Caddy 当前的内部速率限制是每个 ACME 帐户每 10 秒 10 次尝试。
为避免资源泄露,当配置更改时,Caddy 会中止正在进行的任务(包括 ACME 事务)。虽然 Caddy 能够处理频繁的配置重载,但请注意此类操作的运维考虑,并考虑批量变更以减少重载,给 Caddy 一个机会在后台实际完成证书获取。
颁发者回退
Caddy 是首个(也是目前唯一一个)支持在无法成功获取证书时自动冗余地故障转移到其他 CA 的服务器。
默认情况下,Caddy 启用两个兼容 ACME 的 CA:Let's Encrypt 和 ZeroSSL
。如果 Caddy 无法从 Let's Encrypt 获取证书,它将尝试使用 ZeroSSL;如果两者都失败,它将退避并稍后重试。在你的配置中,你可以自定义 Caddy 用于获取证书的颁发者,既可以是全局性的,也可以针对特定名称进行设置。
存储
Caddy 会将公共证书、私钥以及其他资产存储在其配置的存储设施(如果未配置则为默认存储 —— 详情见链接)中。
使用默认配置时你需要知道的主要事情是:$HOME 文件夹必须可写且持久。 为帮助故障排查,如果指定了 --environ 标志,Caddy 会在启动时打印其环境变量。
任何配置为使用相同存储的 Caddy 实例将自动共享这些资源并在集群中协调证书管理。
在尝试任何 ACME 事务之前,Caddy 会测试配置的存储以确保其可写并具有足够的容量。这有助于减少不必要的锁争用。
通配符证书
当配置为服务具有符合条件的通配符名称的站点时,Caddy 可以获取和管理通配符证书。如果站点名称仅在最左侧域标签使用通配符,则该站点名称符合通配符条件。例如,*.example.com 符合条件,但以下不符合:sub.*.example.com、foo*.example.com、*bar.example.com、*.*.example.com。(这是 WebPKI 的限制。)
如果使用 Caddyfile,Caddy 会字面上地将站点名称视为证书主题名称。换句话说,将站点定义为 sub.example.com 会使 Caddy 管理 sub.example.com 的证书,而将站点定义为 *.example.com 会使 Caddy 管理 *.example.com 的通配符证书。你可以在我们的 常见 Caddyfile 模式 页面看到此演示。如果你需要不同的行为,使用 JSON 配置 可让你对证书主题和站点名称(“host matchers”)有更精确的控制。
从 Caddy 2.10 起,在自动化通配符证书时,Caddy 会使用通配符证书为配置中的单个子域提供服务。除非显式配置,否则它不会为单个子域获取证书。
通配符证书代表了较大的权限范围,仅在你拥有大量子域以至于为它们管理单独证书会给 PKI 带来压力或导致触及 CA 强制的速率限制,或隐私权衡值得在密钥泄露时暴露大量 DNS 区域时,才应使用。注意,通配符证书本身并不能隐藏具体子域的隐私:除非启用了加密 ClientHello(ECH),否则它们在 TLS ClientHello 数据包中仍然会被暴露。(见下文。)
注意: Let's Encrypt 要求 使用 DNS 挑战 来获取通配符证书。
加密 ClientHello(ECH)
通常,TLS 握手涉及以明文发送 ClientHello,包括服务器名称指示(SNI;所连接的域名)。这是因为它包含加密握手后连接所需的参数。当然,这会将域名(ClientHello 中最敏感的部分)暴露给任何可以窃听连接的观察者,即便他们不在你当前的物理附近。它会揭示当目标 IP 提供许多不同站点时你正在连接哪个服务,并且正是某些政府用来审查互联网的方法。
通过 Encrypted ClientHello,客户端可以通过将真实的 ClientHello 包装在“外层” ClientHello 中来保护域名,该“外层”确定了解密“内层” ClientHello 的参数。不过,为了使其奏效并带来实际隐私收益,许多环节需要完美配合。
首先,客户端需要知道用来加密 ClientHello 的参数或配置。这些信息包括公钥和“外层”域(“公共名称”),以及其他参数。该配置必须以可靠的方式发布或分发。
理论上你可以把它写在纸上分发给每个人,但大多数主流浏览器支持在连接到站点时查找包含 ECH 参数的 HTTPS 类型 DNS 记录。因此,你需要:(1)生成 ECH 配置(公/私钥对以及其他参数),然后(2)创建一个包含 base64 编码 ECH 配置的 HTTPS 类型 DNS 记录。
或者……你可以让 Caddy 为你完成这一切。Caddy 是第一个也是唯一一个可以自动生成、发布并提供 ECH 配置的 Web 服务器。
一旦 HTTPS 记录发布,客户端在连接到你的站点时需要对 HTTPS 记录进行 DNS 查找。通常 DNS 查找是明文的,这会危及 ECH 握手的安全性,因此浏览器需要使用像 DNS-over-HTTPS(DoH)或 DNS-over-TLS(DoT)这样的安全 DNS 协议。根据浏览器的不同,这可能需要手动启用。
一旦客户端安全地下载了 ECH 配置,它就会使用其中嵌入的公钥来加密 ClientHello,然后继续连接到你的站点。Caddy 然后解密内层 ClientHello 并继续为你的站点提供服务,而域名在链路上从未以明文形式出现。
部署注意事项
ECH 是一项细致的技术。即便 Caddy 完全自动化了 ECH,仍需考虑许多因素以获得最大的隐私收益。你还应了解各种权衡。
发布
只有当域已有记录时,Caddy 才会为该域创建 HTTPS 记录。这可避免破坏可能由通配符覆盖的子域的 DNS 查找。确保你的站点至少有一条 A/AAAA 记录指向你的服务器。如果你仅对 DNS 记录使用通配符,那么通配符域也需要出现在你的 Caddy 配置中。
对于有 CNAME 记录的域,Caddy 不会发布 HTTPS 记录。
ECH GREASE
如果你打开 Wireshark 然后在现代浏览器(如 Firefox 或 Chrome 的新版,即使禁用了 ECH)中连接到任意站点,你可能会注意到其握手包含 encrypted_client_hello 扩展:

其目的是使真正的 ECH 握手与明文握手难以区分。如果 ECH 握手与普通握手看起来不同,审查者就可以简单地封锁 ECH 握手而不产生太多连带影响。但如果他们封锁任何包含类似 ECH 扩展的握手,他们实际上会关闭互联网上的大部分流量。(目标是提高大规模审查的成本。)
这在排查连接问题时尤其重要。
密钥轮换
像证书密钥一样,长时间使用同一把密钥并不是好做法(甚至可能十分不安全)。因此,ECH 密钥应定期轮换。与证书不同,ECH 配置并不严格过期。但服务器仍应进行轮换。
密钥轮换很棘手,因为客户端需要知道更新后的密钥。如果服务器简单地用新密钥替换旧密钥,除非客户端立即获悉新密钥,否则所有 ECH 握手都会失败。但仅发布更新后的密钥也不够。现实是,DNS 记录有 TTL,解析器会缓存响应等。客户端可能需要几分钟、几小时甚至几天的时间来查询更新后的 HTTPS 记录并开始使用新的 ECH 配置。
因此,服务器应在一段时间内继续支持旧的 ECH 配置。不这样做会有在大规模范围内暴露服务器名称为明文的风险。
不过,这仍可能不够。一些客户端因为各种原因仍可能无法获取更新后的密钥,每次发生这种情况时,就存在暴露服务器名称的风险。因此需要另一种方法,即在连接中“带内”提供更新的配置。这就是“外层名称”的用途。
公共名称
“外层” ClientHello 是一个普通的 ClientHello,但有两个只有源服务器知道的微妙差别:
- SNI 扩展是伪造的
- ECH 扩展是真实的
该“外层” SNI 扩展包含保护你真实域名的公共名称。这个名称可以是任意的,但你的服务器必须对该公共名称具有权威性,因为 Caddy 会为其获取证书。
如果客户端尝试建立 ECH 连接但服务器无法解密内层 ClientHello,服务器实际上可以使用外层 ClientHello 并为外层名称提供的证书完成握手。这个安全连接严格地仅用于向客户端发送当前的 ECH 配置;即它是一个临时的 TLS 连接,仅用于完成初始 TLS 连接。不会传输应用数据:只有 ECH 密钥。一旦客户端获得了更新的密钥,它就可以按预期建立 TLS 连接。
通过这种方式,真实的服务器名称保持受保护,且不同步的客户端仍能连接,这两点都是安全的重要组成部分。
外层名称可以是你站点的某个域名、子域或指向你服务器的任何其他域名。我们建议选择一个通用名称。例如,Cloudflare 在 cloudflare-ech.com 后面为数百万站点提供服务。这有助于增大匿名集合的规模。
公共名称不应为空;也就是说,必须为公共名称进行配置才能使其工作。Caddy 目前不会强制这一点(将来可能会),但 ECH 规范要求公共名称至少为 1 字节长。一些软件会接受空名称,另一些则不会。这可能导致例如浏览器使用 ECH 而服务器将其视为无效并拒绝;或者浏览器不使用 ECH(因为它无效),即便配置已正确发布在 DNS 记录中。确保正确的 ECH 配置和发布以保障隐私是站点所有者的责任。
匿名集合
为最大化 ECH 的隐私收益,应努力增大你的“匿名集合”的规模。该集合本质上由面向客户端的服务器组成,这些服务器对观察者而言具有相同的行为。目的是让观察者难以缩小或推断出客户端正在连接的可能站点或服务。
在实践中,我们建议为所有站点只使用一个公共名称。(每个 ECH 配置只有 1 个公共名称,这意味着在任何给定时间只有 1 个活动的 ECH 配置。)如果你在集群中运行 Caddy,Caddy 会自动与其他实例共享和协调 ECH 配置,这会为你处理此问题。
极端地讲,这意味着互联网上的每个站点都可以或应该位于单个 IP 地址和一个公共名称之后……
集中化
……这就引出了我们的下一个话题:集中化。对 ECH 的一个批评是它倾向于推动集中化。它至少在两方面促成这一点:(1)客户端偏好使用 DoH/DoT 进行 DNS 查找,这会将所有 DNS 查找发送到少数提供商;(2)通过最大化匿名集合的规模来实现集中化。
当使用 DoH 或 DoT 时,DNS 查找都会通过 DoH/DoT 提供商。在客户端与提供商之间,DNS 数据是加密的,但在提供商与 DNS 服务器之间并非加密。全局性的 DoH/DoT 实际上会将所有有价值的明文 DNS 流量汇聚到几条大管道中,这些管道容易被观察……或发生故障。
同样,如果我们确实在规模上最大化匿名集合,所有站点都将被一个公共名称所保护,比如 cloudflare-ech.com。这对隐私有利,但整 个互联网就会受制于 Cloudflare 和那一个域名。当然,最大化到这种程度既不必要也不现实,但理论影响仍然存在。
我们建议每个组织或个人为其所有站点选择一个名称并使用它,在大多数情况下这应提供足够的隐私保障。然而,请根据你的具体威胁模型咨询专家以获得针对你个案的建议。
子域隐私
使用 ECH,如果部署得当,现在理论上可以将子域从侧信道中保密/隐藏。
大多数站点不需要此功能,因为一般来说子域是公开信息。我们建议不要在域名中放置敏感信息。尽管如此……
为了避免将敏感子域泄露到证书透明(CT)日志中,请使用通配符证书。换言之,与其在配置中放 sub.example.com,不如放 *.example.com。(有关详情见通配符证书。)
然后,在 Caddy 中启用 ECH。通配符证书与 ECH 结合应能适当隐藏子域,只要所有尝试连接的客户端都使用 ECH 且实现良好。(你仍然依赖客户端来维护隐私。)
启用 ECH
由于正常工作的 ECH 需要将配置发布到 DNS 记录,你需要一个带有对应 DNS 提供商的 caddy-dns 模块 的 Caddy 构建。
然后,在 Caddyfile 中,在全局选项里指定你的 DNS 提供商配置以及你想使用的 ECH 公共名称:
{
dns <provider config...>
ech example.com
}
请记住:
- 必须插入 DNS 提供商模块,并且你必须为你的提供商/帐户提供正确的配置。
- ECH 公共名称应指向你的服务器。Caddy 会为其获取证书。它不必是你站点的域名之一。
如果使用 JSON,则将这些属性添加到 tls 应用中:
"encrypted_client_hello": {
"configs": [
{
"public_name": "example.com"
}
]
},
"dns": {
"name": "<provider name>",
// provider configuration
}
注意将注释翻译为中文以保持一致性:
"encrypted_client_hello": {
"configs": [
{
"public_name": "example.com"
}
]
},
"dns": {
"name": "<provider name>",
// 提供商配置
}
这些配置将启用 ECH 并为你所有的站点发布 ECH 配置。如果需要自定义行为或拥有高级设置,JSON 配置提供了更多灵活性。
验证 ECH
目前围绕 ECH 的工具还不多,因此在撰写本文时,验证其工作与否最通用的方式是使用 Wireshark 并在 ServerName 字段中查找你的公共名称。
首先,启动你的服务器并查看日志是否提到你的域名“已发布 ECH 配置列表”等类似信息。(如果发布过程中出现任何错误,请确保你的 DNS 提供商模块支持 libdns 1.0,如果遇到问题,请在你提供商的仓库中提交 issue。)Caddy 也应为公共名称获取证书。
接下来,确保你的浏览器已启用 ECH;这可能需要启用 DoH/DoT。同样建议清除浏览器(或系统)的 DNS 缓存,以确保它会获取新发布的 HTTPS 记录。我们还建议关闭浏览器或至少打开一个新的隐私窗口,以确保不重用现有连接。
然后打开 Wireshark 并开始在相应的网络接口上监听。当 Wireshark 收集数据包时,在浏览器中加载你的网站。然后暂停 Wireshark。找到你的 TLS ClientHello,你应在 ServerName 字段中看到“公共名称”,而不是你实际连接的域名。
记住:即便未使用 ECH,你也可能仍会看到 encrypted_client_hello 扩展。关键指标是 SNI 值。如果 ECH 正常工作,你在 Wireshark 中永远不应该看到真实站点名称的明文。
如果在部署 ECH 时遇到问题,首先在我们的论坛上询问。如果是 bug,你可以在 GitHub 上提交 issue。
ECH 在存储中的位置
ECH 配置存储在 数据目录 中,使用配置的存储模块(默认为文件系统),路径位于 ech/configs 文件夹下。
下一级目录是一个 ECH 配置 ID,该 ID 是随机生成的,相对不重要。规范建议使用随机性以帮助缓解指纹识别/跟踪。
一个元数据侧车文件帮助 Caddy 跟踪上次发布的时间。这可以防止在每次配置重载时对你的 DNS 提供商进行频繁请求。如果你必须重置此状态,可以安全地删除该元数据文件。不过,这也可能重置密钥轮换的时间。你也可以打开该文件,仅清除有关发布的信息。