# 前言
近期在准备将自己的一个玩具项目 Code: Certs (opens new window) 打磨打磨开放出来给大家用一用,
于是搭建了一个简单的项目介绍网站, 将其托管在了 GitHub Pages (opens new window) 上,
并分配了自定义域名 https://code-certs.dengchao.fun (opens new window) 进行访问.
谁知后续 SSL 证书更新时遇到了 Verify error:CAA record for XXX prevents issuance
错误无法生成证书的问题.
Code: Certs 是一项适用于个人与小型团队的 HTTPS 证书免运维服务.
# 正文
# 启用 GitHub Pages 强制 HTTPS 访问功能
为了避免网站内容被劫持, Code: Certs (opens new window) 的项目介绍网站一开始就打算启用强制 HTTPS 访问. 正好 GitHub Pages 也支持启用强制 HTTPS 访问, 于是配置好自定义域名后便开启了此项功能. 此时, 网站已经能够顺利地将 HTTP 流量重定向到 HTTPS 了, 一切看起来都那么地自然与美好🌞.
# 更新 SSL 证书报错
随后不久, 我的其他网站和应用使用的 HTTPS 证书也即将到期了, 于是我打算用这个项目来完成自身 HTTPS 证书的更新.
然而 *.dengchao.fun
这个通配符却一直没法申请到 Let's Encrypt (opens new window) 颁发的新证书,
并不断提示 Verify error:CAA record for XXX prevents issuance
错误.
错误信息很直白, 就是 CAA 记录导致 CA 机构 Let's Encrypt 无法为指定的通配符域名颁发新证书.
由于本就打算一直使(白)用(嫖) Let's Encrypt 来签发证书, 早早的就给裸域名 dengchao.fun
添加的了值为 0 issuewild "letsencrypt.org"
的 CAA 记录.
反复尝试申请这个通配符域名的证书失败, 并且对比其他启用了相同 CAA 记录的域名后, 确定不是 CA 机构或者网络故障导致的问题, 又回想起前一段时间刚部署到 GitHub Pages 上的 Code: Certs (opens new window) 也开启了强制 HTTPS 访问, 于是开始猜测是 GitHub Pages 引发了此次异常 🤔.
# 调查原因
由于是 CAA 记录引发的异常, 因此开始对比分配给 Code: Certs (opens new window)
服务的域名 code-certs.dengchao.fun
与裸域名 dengchao.fun
的 CAA 记录, 结果发现 code-certs.dengchao.fun
的 CAA
记录不是 0 issuewild "letsencrypt.org"
😮:
# dig code-certs.dengchao.fun CAA
;; Warning: Message parser reports malformed message packet.
; <<>> DiG 9.16.1-Ubuntu <<>> code-certs.dengchao.fun CAA
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64915
;; flags: qr rd ad; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0
;; WARNING: recursion requested but not available
;; QUESTION SECTION:
;code-certs.dengchao.fun. IN CAA
;; ANSWER SECTION:
code-certs.dengchao.fun. 0 IN CAA 0 issue "letsencrypt.org"
code-certs.dengchao.fun. 0 IN CAA 0 issue "digicert.com"
code-certs.dengchao.fun. 0 IN CAA 0 issuewild "digicert.com"
. 0 IN OPT
;; Query time: 109 msec
;; SERVER: 172.28.0.1#53(172.28.0.1)
;; WHEN: Sun Feb 05 12:11:52 CST 2023
;; MSG SIZE rcvd: 169
进一步查看 CAA 记录的文档后发现当域名是 CNAME 类型的记录时, CA 会优先解析 CNAME 的值的 CAA 记录, 而不是像 A
类型记录一样继续检查上一级域名:
也就是说当 CA 机构查询 code-certs.dengchao.fun
的 CAA 记录时, 会优先查看 code-certs.github.io
是否有 CAA 记录,
结果 github.io
刚好配置了 CAA, 并且允许 Let's Encrypt 颁发单域名证书以及允许 Digi Cert 颁发单域名与通配符证书.
# 尝试与 GitHub 沟通
发现问题出在 github.io
的 CAA 记录上后, 我立即尝试与 GitHub 进行沟通 (opens new window),
出于自身的安全政策与影响范围等方面的考虑, GitHub 并没有采纳修改 CAA 记录相关的意见, 但给出了一个可行的应对方案.
# 应对方案
经过探索以及与 GitHub 的沟通, 我得出了如下几个可行的应对方案:
- 继续将网站托管在 GitHub Pages 上, 并继续使用 Let's Encrypt 来颁发通配符证书,
但将自定义域名的类型由 CNAME 类型变更为 A 类型 (opens new window),
以避免 CA 机构查询 CAA 记录时获取到
github.io
的 CAA 记录. 虽然 GitHub Pages 文档中关于自定义域名方面的文档 (opens new window) 提到用户需要使用 CNAME 类型来解析自定义域名到<repo>.github.io
来启用自定义域名功能, 但实际上将自定义域名设置为 A 类型, 并解析到任意<repo>.github.io
对应的 ip 上也能启用自定义域名功能. - 继续将网站托管在 GitHub Pages 上, 但使用 Digi Cert 来颁发通配符证书. 由于 Digi Cert 不提供免费证书, 因此暂不考虑.
- 将网站迁出 GitHub Pages, 并继续使用 Let's Encrypt 来颁发通配符证书. 毕竟网站是你自己的, 没人要求你一定要托管在 GitHub Pages 上.
# 相关内容
- Code: Certs | 一项适用于个人与小型团队的 HTTPS 证书免运维服务. (opens new window)
- 什么是 GitHub Pages (opens new window)
- 什么是 CAA?
- CAA records will be added after enforcing HTTPS for GitHub Pages (opens new window)
# 推广
欢迎大家尝试使用 Code: Certs | https://code-certs.dengchao.fun (opens new window) 来申请免费的 HTTPS 证书, Code: Certs (opens new window) 还支持自动部署到部分公有云的产品上, 降低 HTTPS 证书运维工作量. 大家遇到什么使用问题或者有任何建议都可以私信我, 或者提交到 https://github.com/code-certs/code-certs/issues (opens new window) 也行.
欢迎大家领取 阿里云优惠券 (opens new window), 新购续费更优惠, 详询 钉钉 (opens new window): (opens new window)