news 2026/8/29 9:01:09

Caddy ECH 配置教程:两步隐藏 TLS 握手里的真实域名

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Caddy ECH 配置教程:两步隐藏 TLS 握手里的真实域名

Caddy ECH 配置教程:两步隐藏 TLS 握手里的真实域名

【免费下载链接】caddyFast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS项目地址: https://gitcode.com/GitHub_Trending/ca/caddy

读完这篇,你能给自己的 Caddy 站点开启 ECH(Encrypted Client Hello,加密客户端问候),让握手阶段暴露的服务器名称变成你指定的公共名称。

你的访问域名正在明文传输

把任意一次 HTTPS 连接抓包看,最扎眼的一帧就是 ClientHello(TLS 握手的第一条客户端消息)。它里面夹着一个 SNI(Server Name Indication,服务器名称指示)字段,值就是用户正在访问的域名——明文,任何中间节点都能读。

你的网站内容加密得好好的,域名本身却像没贴封条的包裹标签,谁都能看。运营商、公共 Wi-Fi 节点、公司网关,全都顺理成章地知道"这台设备正在访问 example.com"。

Caddy 在 TLS 应用里内置了 ECH 支持(实现位于 modules/caddytls/ech.go),能自动帮你生成密钥、轮转密钥,并把配置发布到 DNS。注意:该模块在代码里标注为 EXPERIMENTAL(实验性),接口可能随版本调整。

原理拆解:一次"共享快递柜"式的握手

打个比方:你把包裹寄到共享快递柜,面单只写"中心快递柜"这个地址(公共名称),自己取件的格口号通过加密短信单独发给你。邻居只能看到有人频繁往同一个快递柜寄包裹,猜不出里面是谁寄给谁的。

具体到 Caddy 的工作机制:

  1. 生成密钥对:首次启动时,Caddy 用 DHKEM(X25519, HKDF-SHA256) 算法自动生成一对 HPKE 密钥(HPKE 是基于混合公钥的封装加密,负责把对称密钥安全地交给对方),连同公共名称一起打包成 ECHConfig 存进本地存储。
  2. 发布到 DNS:配置了 DNS 提供商后,Caddy 把你保护域名的 HTTPS 记录(RFC 9460 定义的 DNS 记录类型)写入该域名,ECHConfig 以 base64 形式放在ech参数里。
  3. 客户端封装请求:支持 ECH 的浏览器在解析域名时读到这条记录,把真实 ClientHello(含真实 SNI)加密后,套一层使用公共名称的外层 ClientHello 发出去。
  4. 服务端拆包:外层用公共名称完成证书验证,Caddy 再用私钥解开内层,按真实域名路由到对应站点。整个机制要求 TLS 1.3 及以上,Caddy 会对启用 ECH 的连接策略自动抬高最低版本。

兼容性检查清单

动手前先确认四件事:

  • 🧱 Caddy 版本包含 ECH 模块(当前仓库实现见 modules/caddytls/ech.go),且你的 Caddyfile 解析走的是 caddyconfig/httpcaddyfile/options.go 中的ech全局选项
  • 🌐 你的域名支持写入 HTTPS 记录,且 DNS 服务商提供可写入的 API(Caddy 需要带 DNS 提供商模块的自定义构建)
  • 📜 公共名称(public_name)的解析已指向这台服务器,Caddy 要给它签发证书
  • 🧪 客户端侧:浏览器较新版本 + 启用了 DoH(DNS over HTTPS)或 DoT,否则 DNS 里的 ECH 配置读不到

最小可运行配置

Caddyfile 里只加一个ech全局选项:行内写公共名称,块内用dns子指令指定发布用的 DNS 提供商。

{ ech ech.example.com { dns cloudflare { api_token $CLOUDFLARE_TOKEN } } } https://shop.example.com { respond "hi" 200 }

保存后跑caddy reload --config Caddyfile。Caddy 会自动为ech.example.com申请证书(代码里已把公共名称加入自动化策略,见 caddyconfig/httpcaddyfile/tlsapp.go),并为shop.example.com写入 HTTPS 记录。

ECH 验证三步

dig +short HTTPS shop.example.com curl --ech https://shop.example.com -I
  • 第一条应返回带ech=参数的记录;没有就先检查 DNS 提供商配置
  • 第二条用 curl 以 ECH 模式握手,能正常返回响应头即服务端链路通
  • 第三步:Chrome 里打开chrome://net-internals/#ech,确认该域名出现在已加载的 ECH 配置列表中,抓包时 SNI 应显示为公共名称

避坑指南:三个高频故障

现象:日志出现 "domain has CNAME record",站点始终走明文 SNI。原因:HTTPS 记录不能与 CNAME 共存,Caddy 检测到 CNAME 会直接跳过发布。解法:把该域名的 CNAME 换成 A/AAAA 记录后重新加载配置。

现象:域名下没有任何 DNS 记录,只靠通配符 A 记录兜底,发布日志提示 "does not have any existing records"。原因:给一个没有任何记录的域名写 HTTPS 记录,会让通配符解析对它失效,Caddy 为避免打断解析主动跳过。解法:先给域名加一条真实的 A/AAAA 记录,再让 Caddy 发布。

现象:客户端偶尔退回明文 SNI 握手。原因:公共名称证书没签下来(域名没解析到本服务器),客户端拿不到可用的 ECH 配置,只能裸连。解法:确认ech.example.com的解析指向本机且证书状态正常;另外用了 On-Demand TLS(按需签证书)的域名,要在publication.domains里显式列出,否则首次连接仍会暴露真实域名。

一页收束:开启 ECH 前后的差别

对比项普通 TLS开启 Caddy ECH
中间节点看到的 SNI真实域名公共名称
握手最低版本取决于配置强制 TLS 1.3
密钥管理自动生成,约 30 天轮转、90 天后清理
配置分发自动写入 DNS HTTPS 记录

现在就去改你的 Caddyfile:加一段ech选项,reload,然后跑上面两条验证命令,看 SNI 是否已变成公共名称。

【免费下载链接】caddyFast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS项目地址: https://gitcode.com/GitHub_Trending/ca/caddy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/29 9:01:00

136 门精选课程的 CS 自学指南:如何 3 年从零基础走到全栈

136 门精选课程的 CS 自学指南:如何 3 年从零基础走到全栈 【免费下载链接】cs-self-learning 计算机自学指南 项目地址: https://gitcode.com/GitHub_Trending/cs/cs-self-learning 我也曾把上百 G 的资源加进收藏夹,却连一门课都没学完。问题不…

作者头像 李华
网站建设 2026/8/29 8:57:23

Django排课系统开发实战:从数据库设计到自动排课算法

简介:教务管理系统中,排课一直是复杂度最高的模块之一,其本质是一个多资源约束分配问题,涉及教师、班级、教室、时间等多维度的冲突规避。借助Python生态中成熟的Django框架,可以高效地搭建一套通用排课系统。本文从基…

作者头像 李华
网站建设 2026/8/29 8:55:20

AI企业第一品牌顶层设计:从认知站到行业定义

从世界人工智能大会WAIC出来后,我脑子里最挥之不去的问题不是“哪家技术最强”,而是“为什么有些AI企业能成为第一品牌,有些企业只能成为背景板”。这个问题直接决定了一家AI企业的资源配置方向。技术最强的企业不一定成为第一品牌&#xff0…

作者头像 李华