cover

处理 Cloudflare 与 Let's Encrypt DNS-01 验证冲突的问题

问题

上个月某一天,GeekNote 的 Cloudflare 代理提示 Error 526。Error 526 是指 CloudFlare 的节点无法验证源服务的 SSL 证书。相关文档如下:

https://support.cloudflare.com/hc/en-us/articles/115003011431-Troubleshooting-Cloudflare-5XX-errors#526error

GeekNote 部署在 fly.io 平台,fly.io 为网站生成证书用的是 Let's Encrypt,按理说会自动更新证书,问题出在哪呢?

解决

我尝试到 fly.io 的控制台重新申请证书,但 Fly 的证书颁发进度一直卡在 Wating 状态。

随后我继续调试,发现在 DNS 记录有异常。Fly 申请证书需要将 _acme-challenge.<YOUR_DOMAIN> CNAME 到 Fly 的服务器上,由 Fly 的服务器代为完成 Let's Encrypt DNS-01 验证。

正常情况下,DNS 记录应该是这样:

$ dig _acme-challenge.geeknote.net txt
;; ANSWER SECTION:
_acme-challenge.geeknote.net. 300 IN	CNAME	geeknote.net.odnl9.flydns.net.
geeknote.net.odnl9.flydns.net. 60 IN	TXT	"Wuut_zK4Mq2VvaxJh1ebfKCJA3AqIrhRAR2fQpV1xxk"

但实际上却是这样:

$ dig _acme-challenge.geeknote.net txt
;; ANSWER SECTION:
_acme-challenge.geeknote.net. 300 IN TXT "5sEvmmByggxWUgSCRbrKHHSua6YhE4NJVnt5CIa__XA"
_acme-challenge.geeknote.net. 300 IN TXT "t5UpMqgvRkdU_M7I7P2-rcX0jkiSY8gfeldNvtSOvpM"

TXT 记录并不是从 Fly 服务器获取的。

经过一番搜索,我发现问题出在 Cloudflare。Cloudflare 同样使用 Let's Encrypt 申请证书,同样使用 DNS-01 验证,它自动为域名添加了 _acme-challenge TXT 记录,这个记录和 Fly 的 CNAME 记录冲突了。

麻烦的是,由于这些记录是自动添加的,Cloudflare 用户没法在控制台里清理记录。CloudFlare 的社区里有一群人在等待技术人员处理:

https://community.cloudflare.com/t/extra-acme-txt-records-preventing-renewal/412449

最后,我在 Fly 的社区里找到解决方法,那就是关掉 CloudFlare 自动颁发证书的功能:

0995b20669fed992a354e48d2626677252dd0048.png

关掉这个选项后,多余的 TXT 记录被去掉了,重新在 Fly 申请证书成功。但是关掉 CloudFlare 的证书也意味着不能使用 CloudFlare 的代理功能。

在关掉 CloudFlare 的代理模式后,网站恢复访问。

讨论

在解决问题的过程中,我发现 Cloudflare 免费用户是无法提交 Ticket 的,只能在社区发帖,祈求有工作人员抽空处理问题。我在社区提交的问题至今没有得到回复,这让我很失望。

Fly 虽然也是到社区发帖,但是 Fly 的 CTO 和员工会经常回复,问题通常都会得到解决,我对他们的好感度增加了。

叠加网络层容易出现配置冲突,尽量还是避免太多的层次。

1