Hotdry.
security

DNS-Persist-01 TXT 记录格式规范与客户端实现指南

解析 DNS-Persist-01 提案的 TXT 记录格式规范,对比与传统 DNS-01 的差异,给出客户端实现要点与测试验证方法。

在 ACME 协议的发展历程中,DNS-01 挑战类型一直是验证域名控制权的核心机制。然而,每次证书签发或续期都需要更新 DNS TXT 记录的操作,在大规模自动化场景中带来了显著的运维负担。DNS-Persist-01 作为 IETF 正在标准化的新型挑战类型,提出了一种持久化授权的思路:通过在域名 DNS 区域中放置一条长期有效的 TXT 记录,绑定证书颁发机构与 ACME 账户,从而在后续的证书操作中省去重复的 DNS 更新步骤。理解 DNS-Persist-01 的 TXT 记录格式规范,是实现兼容客户端的基础前提。

TXT 记录名称与放置位置

DNS-Persist-01 挑战的 TXT 记录并非放置在传统的 _acme-challenge 前缀下,而是使用专用的授权域名名称。根据 IETF 草案规定,记录应放置在 _validation-persist.<授权域名> 的位置。以域名 example.com 为例,TXT 记录的完整名称为 _validation-persist.example.com。这一命名约定明确区分了传统的 DNS-01 挑战记录与持久化授权记录,避免在 ACME 客户端处理时的混淆。部分实现中也出现过 _acme-persist 的变体命名,但 Let's Encrypt 官方文档明确采用前者作为标准。

从 DNS 区域文件的角度看,记录的典型配置如下所示:_validation-persist.example.com. IN TXT "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1234567890"。客户端在构建授权请求时,需要根据目标域名动态生成对应的 TXT 记录名称,并确保该记录在 CA 验证前已成功传播至全局 DNS。

RDATA 格式与必选字段

DNS-Persist-01 的 TXT 记录值采用 RFC 8659 定义的 issue-value 语法,本质上是一个由分号分隔的键值对序列。记录值由两部分组成:首先是证书颁发机构的标识名称,称为 issuer-domain-name;随后是必选的 accounturi 参数,用于指定获得授权的 ACME 账户 URI。

issuer-domain-name 必须是 CA 在挑战响应中提供的标识符之一。以 Let's Encrypt 为例,其标识符为 letsencrypt.org。accounturi 参数则采用 RFC 8555 规定的账户 URI 格式,例如 https://acme-v02.api.letsencrypt.org/acme/acct/1234567890。这两个字段构成了 DNS-Persist-01 授权记录的最小合法集合,缺少其中任何一项都将导致验证失败。

完整的必选字段格式可以表示为:"<issuer-domain-name>; accounturi=<account-URI>"。在实际部署中,由于 TXT 记录值可能被 DNS 库拆分为多个引号括起的字符串,客户端在解析时需要将同一条记录的所有字符串片段进行逻辑拼接后再进行处理。

可选字段与扩展参数

除了必选字段外,DNS-Persist-01 规范还定义了若干可选参数,以支持更灵活的授权策略。

persistUntil 参数 用于指定授权失效的时间戳,值为 UNIX 纪元秒数。当该字段被设置时,CA 仅在当前时间早于该时间戳时接受该持久化授权。如果省略此字段,授权将在记录被删除或修改前持续有效。例如,persistUntil=1767225600 对应 2026 年 1 月 1 日的时间戳。

policy 参数 用于声明授权的适用范围,常见的值包括 wildcard,表示该授权同时适用于普通域名和通配符域名。客户端在构造记录时可以根据实际需求添加相应策略声明。

需要特别注意的是,当需要授权多个证书颁发机构时,应在同一名称下放置多条 TXT 记录,每条记录对应一个 CA 的 issuer-domain-name。CA 在验证时会遍历所有记录,匹配自身标识符的那一条记录即为该 CA 的有效授权。

与传统 DNS-01 的核心差异

理解 DNS-Persist-01 与 DNS-01 的本质区别,对于正确选择和使用新挑战类型至关重要。

操作频率方面,DNS-01 要求在每次证书签发或续期时创建全新的 TXT 记录,记录值包含 CA 提供的随机令牌;DNS-Persist-01 则只需在初始设置时创建一次持久化授权记录,后续所有证书操作均可复用该记录,无需再次修改 DNS。

凭证管理方面,DNS-01 的核心安全依赖是 DNS API 写入权限,这些凭证需要在自动化流程中广泛分发;DNS-Persist-01 将安全依赖转移至 ACME 账户私钥,一旦持久化记录生效,后续操作不再需要 DNS 写入凭证。

验证模型方面,DNS-01 提供每次签发时的即时控制权证明,验证的是请求时刻的 DNS 状态;DNS-Persist-01 则采用长期授权模式,控制权证明在记录创建时 "快照" 并持续有效,虽然运营成本更低,但失去了每次签发时的动态验证保障。

客户端实现要点

实现 DNS-Persist-01 支持的 ACME 客户端需要在以下几个技术点上进行重点处理。

记录构造阶段:客户端应首先从 CA 获取挑战响应中的 issuer-domain-names 列表,然后根据配置的 ACME 账户 URI 构建符合格式要求的 TXT 记录值。对于支持通配符的场景,还需考虑添加 policy=wildcard 参数。最后,将构造完成的记录推送至 DNS 提供商。

记录解析阶段:当客户端作为 CA 侧验证程序时,需要从 DNS 中查询目标域名的所有 TXT 记录,筛选出符合 _validation-persist.<domain> 前缀的记录。解析时应将多条引号字符串进行拼接,然后按分号分割提取各个键值对。验证流程需检查 issuer-domain-name 与 CA 自身标识的匹配关系、accounturi 与请求方账户的一致性,以及可选的 persistUntil 时间戳是否仍然有效。

多记录处理阶段:DNS 查询可能返回多条 TXT 记录,客户端需要逐条解析并分别验证。任意一条记录通过验证即可认定授权有效。

错误恢复阶段:应妥善处理记录格式错误、账户 URI 不匹配、授权已过期等异常情况,并向运维人员提供清晰的错误诊断信息。

测试验证方法

部署或开发 DNS-Persist-01 客户端时,可采用以下验证手段确保实现的正确性。

使用 dig 或 nslookup 工具直接查询目标域名的 TXT 记录,验证记录是否正确发布。例如:dig TXT _validation-persist.example.com +short 应返回符合格式要求的记录值。

通过 ACME 客户端的调试模式观察完整的挑战响应与验证过程,检查客户端是否正确构造了所需的 issuer-domain-name 和 accounturi 参数。

在测试环境中人为设置错误的 issuer-domain-name、不匹配的 accounturi、过期的 persistUntil 时间戳,验证客户端能否正确拒绝这些非法授权并返回预期的错误信息。

可以使用独立的验证脚本模拟 CA 侧的验证逻辑,对生产环境中已部署的 DNS-Persist-01 记录进行合规性检查。

安全考量

DNS-Persist-01 引入的持久化授权模型在提升运维效率的同时,也带来了需要评估的安全权衡。核心变化在于安全边界的转移:传统 DNS-01 模式下,攻击者需要同时获得 DNS 写入权限和 ACME 账户私钥才能实现非法证书签发;DNS-Persist-01 模式下,由于 DNS 写入在初始配置后不再需要,攻击者只需获取 ACME 账户私钥即可在授权记录有效期内持续签发证书。因此,保护 ACME 账户私钥成为部署 DNS-Persist-01 时的首要安全任务。此外,建议为持久化授权设置合理的 persistUntil 时间,避免在账户不再使用时仍保留有效授权。


参考资料:IETF 草案定义了 DNS-Persist-01 的通用格式规范,明确了 issuer-domain-name 与 accounturi 的必选地位;Let's Encrypt 官方博客则提供了该挑战类型在实际部署中的操作细节与安全考量。

查看归档