Let's Encrypt通配符证书子域名TLS握手失败排查
问题原因分析
- Caddy证书复用逻辑问题:你已有包含
*.foo.duckdns.org的通配符证书,但Caddy默认会为每个新增子域名站点单独申请证书,不会自动复用已有通配符证书,导致它尝试为homeassistant.foo.duckdns.org重新发起证书申请流程。 - Pi-hole拦截ACME DNS挑战:从Caddy日志可见,DNS-01挑战时查询
_acme-challenge.homeassistant.foo.duckdns.org被返回REFUSED,这是Pi-hole作为本地DNS服务器拦截了该域名查询,导致ACME验证失败,Caddy无法获取有效证书。 - TLS握手失败本质:Caddy没有拿到
homeassistant.foo.duckdns.org的有效证书,TLS握手时无法提供合法证书,触发客户端TLS错误;而直接访问8123端口是HTTP协议,无需TLS验证,因此可以正常访问。
解决方案
以下三种方案按推荐程度排序:
方案一:让Caddy复用已有通配符证书(最直接)
找到Certbot生成的通配符证书路径(通常在/etc/letsencrypt/live/foo.duckdns.org/),在Caddyfile中为homeassistant.foo.duckdns.org站点指定使用该证书:
{ acme_dns duckdns <my-token> } nextcloud.foo.duckdns.org { reverse_proxy localhost:11000 } homeassistant.foo.duckdns.org { # 指定通配符证书路径 tls /etc/letsencrypt/live/foo.duckdns.org/fullchain.pem /etc/letsencrypt/live/foo.duckdns.org/privkey.pem reverse_proxy localhost:8123 }
修改后重启Caddy:
sudo systemctl restart caddy
方案二:配置Caddy自动管理通配符证书(自动化程度高)
修改Caddyfile全局配置,让Caddy自动为所有*.foo.duckdns.org子域名复用通配符证书,避免逐个站点配置:
{ acme_dns duckdns <my-token> tls { # 指定Let's Encrypt为证书颁发机构 issuer acme { ca https://acme-v02.api.letsencrypt.org/directory } # 加载已有的通配符证书 certificates { load /etc/letsencrypt/live/ } } } # 用通配符站点统一处理所有子域名,按Host头路由到对应服务 *.foo.duckdns.org { @nextcloud host nextcloud.foo.duckdns.org handle @nextcloud { reverse_proxy localhost:11000 } @homeassistant host homeassistant.foo.duckdns.org handle @homeassistant { reverse_proxy localhost:8123 } }
重启Caddy后,所有*.foo.duckdns.org子域名都会自动复用通配符证书,无需单独配置。
方案三:调整Pi-hole允许ACME DNS挑战查询
如果希望Caddy自动为每个子域名申请证书,需要在Pi-hole中添加白名单,允许_acme-challenge.*.foo.duckdns.org的DNS查询:
- 登录Pi-hole管理界面,进入
Whitelist页面 - 添加域名
_acme-challenge.foo.duckdns.org和_acme-challenge.homeassistant.foo.duckdns.org - 刷新Pi-hole的DNS缓存,确保规则生效
这样Caddy发起DNS-01挑战时,Pi-hole会正常转发查询到DuckDNS服务器,ACME验证通过后即可获取证书。
内容的提问来源于stack exchange,提问作者crissal
相关产品推荐
相关产品推荐

