CNAME 与 TXT 记录冲突影响泛域名证书申请
域名解析记录冲突:CNAME 与 TXT 记录同时存在导致的泛域名证书申请问题
DNS 记录冲突的隐藏陷阱
相信不少运维同学都知道 A 记录和 AAAA 记录无法与 CNAME 记录同时配置,但可能很少遇到 CNAME 记录与 TXT 记录之间的冲突问题。
那么在什么场景下,TXT 记录和 CNAME 记录会产生命名冲突呢?
最常见的情况是通过 Let’s Encrypt 申请 SSL 证书时,采用 DNS-01 验证方式来证明域名归属权。
证书申请的验证流程通常如下:
- Certbot 工具利用 API 密钥和令牌,在 DNS 中添加一条
_acme-challenge.example.com
类型的 TXT 验证记录 - Let’s Encrypt 服务器会查询这个 TXT 记录,验证申请者是否具备管理该域名 DNS 的权限
- 验证通过后,Let’s Encrypt 颁发相应的 SSL 证书
- 完成后,Certbot 会自动清除临时创建的
_acme-challenge.example.com
TXT 记录
问题在于:如果在创建 TXT 验证记录时,DNS 中已经存在同名的 _acme-challenge.example.com
CNAME 记录,那么 TXT 记录的创建就会失败,进而导致整个域名验证过程失败。
那么这个 CNAME 记录是怎么来的呢?
问题根源:阿里云 ESA 托管证书验证
阿里云最新发布的 ESA(边缘安全加速)服务,功能类似于 Cloudflare,实际上是之前 DCDN 全站加速服务的升级版本。在服务初期,用户无法直接申请和管理泛域名证书。
为了解决这个问题,我之前采用定时脚本的方式,将自行申请的泛域名证书定期上传到 ESA 平台,但这种方式管理起来相对繁琐。
后来阿里云推出了托管 DCV(Domain Control Validation)功能,允许用户自助申请和更新泛域名证书。按照官方指引配置后,确实可以实现证书的自动化管理。然而,这个看似便利的功能却埋下了一个隐患,直到几个月后才暴露出来。
ESA 的托管 DCV 会在 DNS 中创建一个长期存在的 CNAME 记录,这个记录一旦存在,就会阻止用户在其他场景下创建同名的 TXT 记录,从而影响在别的平台上进行域名归属验证。
问题解决思路
方案一:放弃使用托管 DCV 功能
托管 DCV 本质上要求将 _acme-challenge.example.com
的控制权交给第三方服务商,这意味着用户失去了对该子域名的完全控制权。
如果确实需要泛域名证书,可以考虑通过编写自动化脚本,调用 ESA 的 API 接口,定期将自行申请的泛域名证书上传到平台。
方案二:改用其他域名验证方式
Certbot 支持多种域名所有权验证方式,DNS-01 只是其中一种。还可以选择 HTTP-01 或 TLS-ALPN-01 等验证方法。
不过需要注意的是,HTTP-01 和 TLS-ALPN-01 验证方式要求目标域名已经部署了相应的 Web 服务,验证器会通过访问服务来确认域名控制权,然后才会颁发证书。
相比之下,DNS-01 验证方式的优势在于可以在部署服务之前就获取到证书。
方案三:改进阿里云内部服务集成
ESA 和云解析 DNS 虽然都属于阿里云的服务,但两者各自维护独立的 API 体系。理想情况下,ESA 应该能够直接操作云解析 DNS 的记录,在需要时自动创建 CNAME 或 TXT 记录,完成验证后再自动清理,这样就不会影响用户在其他场景下使用 DNS-01 验证。
方案四:迁移到 Cloudflare
在 Cloudflare 平台上没有这类问题,证书申请相对更加灵活便利。