拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Certbot Cloudflare DNS 插件实战指南:基于 dns-01 挑战的自动化通配符证书签发

Certbot Cloudflare DNS 插件实战指南基于 dns-01 挑战的自动化通配符证书签发【免费下载链接】certbotCertbot is EFFs tool to obtain certs from Lets Encrypt and (optionally) auto-enable HTTPS on your server. It can also act as a client for any other CA that uses the ACME protocol.项目地址: https://gitcode.com/gh_mirrors/ce/certbot导读本文围绕 Certbot 官方 DNS 认证插件certbot-dns-cloudflare仓库路径 certbot-dns-cloudflare/展开讲解如何借助 Cloudflare API 自动创建/删除 TXT 记录来完成 ACMEdns-01挑战从而为域名含通配符域名签发和续期 Lets Encrypt 证书。读完本文你将掌握插件安装、API 凭证配置Token 与 Global Key 两种模式、命令行使用与参数调优并从源码层面理解 TXT 记录的增删流程、zone 查找、错误码容错等底层实现细节。说明该插件的主文档位于 certbot-dns-cloudflare/docs/index.rst通过 Sphinxautomodule直接渲染模块 docstring 与 API 文档因此本文以 certbot-dns-cloudflare/src/certbot_dns_cloudflare/init.py 中的模块文档即实际渲染的正文为核心骨架展开。一、插件定位与 dns-01 挑战原理certbot-dns-cloudflare是 EFF Certbot 项目官方维护的 DNS 认证插件之一。它通过 Cloudflare API 完成 ACME 协议的dns-01挑战挑战阶段为每个待验证域名创建一条_acme-challenge.域名的 TXT 记录记录内容为 ACME 服务器下发的验证值validation token验证阶段等待 DNS 传播后ACME 服务器回读该 TXT 记录并确认身份清理阶段挑战结束后删除该 TXT 记录恢复 DNS 原状。模块 docstring 中对此有精确定义“automates the process of completing adns-01challenge (~acme.challenges.DNS01) by creating, and subsequently removing, TXT records using the Cloudflare API”对应实现见 certbot-dns-cloudflare/src/certbot_dns_cloudflare/_internal/dns_cloudflare.py。相比 HTTP-01DNS-01 的优势在于不依赖 80 端口、不要求 Web 服务器配置因此特别适合通配符证书*.example.com以及无法开放 80 端口的生产环境。二、安装方式插件默认不随 Certbot 一起安装需要单独安装对于普通用户可前往 certbot.eff.org 选择自己的系统和发行版并选中Wildcard标签页按页面指引安装对于开发者也可以从源码安装本插件在仓库根目录下执行pip install ./certbot-dns-cloudflare依赖certbot与cloudflarePython 模块。安装后插件通过 certbot-dns-cloudflare/pyproject.toml 中声明的 entry point 注册到 Certbot[project.entry-points.certbot.plugins] dns-cloudflare certbot_dns_cloudflare._internal.dns_cloudflare:Authenticatorpyproject.toml还声明了插件支持 Python 3.10含 3.13/3.14分类为 Production/Stable 级别许可证为 Apache-2.0。三、命令行参数Named Arguments插件向 Certbot CLI 注册两个参数参数说明是否必填--dns-cloudflare-credentialsCloudflare 凭证 INI 文件的路径必填--dns-cloudflare-propagation-seconds提交挑战前等待 DNS 传播的秒数默认 10可选其中--dns-cloudflare-propagation-seconds由基类 certbot/src/certbot/plugins/dns_common.py 统一注册--dns-cloudflare-credentials由本插件在 dns_cloudflare.py 中通过add_parser_arguments追加完整参数名自动带上插件前缀dns-cloudflare。参数在代码中的实际消费路径凭证路径经_setup_credentials()dns_cloudflare.py交给基类的_configure_credentials读取 INI 文件传播秒数在基类DNSAuthenticator.perform()中用于sleep()dns_common.py并在挑战失败时通过auth_hint()dns_common.py提示用户调大该参数。四、凭证配置两种认证方式插件支持 Cloudflare 的两种 API 认证方式凭证统一放在一个 INI 文件中通过--dns-cloudflare-credentials传入。4.1 方式一受限 API Token推荐在 Cloudflare Dashboard 的 API Tokens 页面创建 Token只需授予目标 zone 的Zone:DNS:Edit权限即可。Token 可以限定到特定域名与特定操作泄漏风险远低于 Global Key。# Cloudflare API token used by Certbot dns_cloudflare_api_token 0123456789abcdef0123456789abcdef01234567使用 Token 认证要求cloudflarePython 模块版本不低于 2.3.1该版本开始支持 Token如果随插件自动安装的版本过低且系统无法升级则只能退回 Global Key 方式。4.2 方式二Global API Key不推荐Global Key 可以访问账户下所有域名的全部 Cloudflare API一旦泄漏可能造成严重破坏文档明确标注 “not recommended”。# Cloudflare API credentials used by Certbot dns_cloudflare_email cloudflareexample.com dns_cloudflare_api_key 0123456789abcdef0123456789abcdef012344.3 凭证文件的校验规则凭证文件的路径既可以在命令行传入也可以在交互式提示中输入。Certbot 会在续期时记录该路径但不会存储文件内容。凭证校验逻辑位于_validate_credentials()dns_cloudflare.py规则如下只提供api-token合法推荐路径同时提供api-token与email/api-key抛出PluginError提示使用 Token 时不需要 email 与 Global Key只提供email或只提供api-key抛出PluginError提示两者必须成对出现email 应为 Cloudflare 账户邮箱什么都不提供抛出PluginError提示必须提供 Token 或 emailkey 二者之一。这些规则与单元测试 certbot-dns-cloudflare/src/certbot_dns_cloudflare/_internal/tests/dns_cloudflare_test.py 中的test_no_creds、test_missing_email_or_key、test_email_or_key_with_token等用例一一对应。4.4 凭证安全注意事项模块文档对凭证安全提出明确警告凭证文件应像 Cloudflare 账户密码一样妥善保护。能读取该文件的用户可以利用凭证以你的名义发起任意 API 调用能诱导 Certbot 使用这些凭证运行的用户可以完成dns-01挑战来签发新证书或吊销相关域名的既有证书即使这些域名并非由本服务器管理Certbot 检测到凭证文件权限过宽可被系统其他用户访问时会输出警告 “Unsafe permissions on credentials configuration file”每次使用凭证包括续期都会触发无法关闭只能通过chmod 600等命令收紧权限来消除。4.5 与 cloudflare 模块其他凭证来源的优先级cloudflarePython 模块本身支持环境变量、cloudflare.cfg配置文件等方式提供凭证但 Certbot不支持这些方式。模块文档特别提示若同时使用这些额外方式它们提供的凭证必须与传给 Certbot 的凭证文件一致同为 emailkey 或同为 Token否则cloudflare模块会报错传给 Certbot 的凭证优先级更高会覆盖其他方式提供的凭证。五、实战示例签发与续期以下示例均来自模块文档可直接复制运行注意 Windows 下反斜杠续行改为^。5.1 为单个域名签发证书certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \ -d example.com5.2 一张证书覆盖多个域名certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \ -d example.com \ -d www.example.com5.3 调大 DNS 传播等待时间certbot certonly \ --dns-cloudflare \ --dns-cloudflare-credentials ~/.secrets/certbot/cloudflare.ini \ --dns-cloudflare-propagation-seconds 60 \ -d example.com当 ACME 服务器回读 TXT 记录失败时Certbot 的auth_hint()会建议调大--dns-cloudflare-propagation-seconds当前值会显示在提示中。证书签发后的自动续期由 Certbot 的 renewal 机制接管续期时会复用凭证文件路径。5.4 通配符证书DNS-01 认证天然支持通配符域名使用-d *.example.com即可。需要注意通配符与裸域apex可能映射到相同的 TXT 记录名称与内容这正是源码中把 “记录已存在” 错误码当作成功处理的原因之一详见下文。六、源码级原理认证与清理的完整调用链6.1 生命周期总览插件核心类Authenticatordns_cloudflare.py继承自 certbot/src/certbot/plugins/dns_common.py 中的DNSAuthenticator实现_setup_credentials/_perform/_cleanup三个抽象方法。基类定义了完整流程perform()调用_setup_credentials()加载并校验凭证然后对每个 challenge 计算验证域名validation_domain_name即_acme-challenge.域名与验证值validation调用_perform()创建 TXT 记录dns_common.py全部记录创建成功后perform()输出 “Waiting %d seconds for DNS changes to propagate” 并sleep()传播秒数ACME 服务器验证通过后cleanup()dns_common.py调用_cleanup()删除 TXT 记录。测试用例test_perform与test_cleanupdns_cloudflare_test.py验证了调用链perform→add_txt_record(DOMAIN, _acme-challenge.DOMAIN, ...)cleanup→del_txt_record(...)。6.2_CloudflareClient与 Cloudflare API 的封装层_CloudflareClient封装了所有 Cloudflare API 通信构造时根据是否有 email 选择认证方式有 email 则使用cloudflare.Cloudflare(api_email..., api_key...)Global Key否则使用cloudflare.Cloudflare(api_token...)Token与凭证校验规则一一对应dns_cloudflare.pyadd_txt_record()dns_cloudflare.py先解析 zone再调用cf.dns.records.create(zone_id..., typeTXT, name..., content..., ttl...)创建记录TTL 由插件常量ttl 120决定dns_cloudflare.pydel_txt_record()dns_cloudflare.py通过 zone_id 精确匹配的 name/content 查找记录 ID 后删除。删除失败只记录 warning 不抛错保证清理阶段的幂等性。6.3 zone 自动查找多级域名猜测_find_zone_id()dns_cloudflare.py使用dns_common.base_domain_name_guesses(domain)生成从完整域名到上级域名的猜测序列逐个调用cf.zones.list(namezone_name, per_page1)查找命中第一个带有效 ID 的 zone 即返回。因此凭证只需对相应 zone 有权限即可无需手动指定 zone_id。6.4 错误码容错与友好提示源码中针对 Cloudflare API 错误码做了细致处理创建重复记录容错add_txt_record()将错误码 81057“Record already exists”与 81058“A record with identical settings already exists”视为成功返回。这是因为以下场景下同名同内容的 TXT 记录可能已存在上一次 certbot 运行在创建记录后、清理前非正常终止ACME 服务器重放同一 pending 授权同一张证书的裸域 通配符验证映射到相同的 TXT 名称与内容并发运行的 certbot 实例先创建了记录。 该行为与 lexicon 的 cloudflare provider 兼容dns_cloudflare.py对应测试test_add_txt_record_already_exists权限提示错误码 1009 时追加提示 “Does your API token haveZone:DNS:Editpermissions?”dns_cloudflare.py凭证问题定位zone 查找阶段遇到 6003Token/Key 未完整复制、9103email/Global Key 错误、9109Token 无效时抛出带具体排查提示的PluginErrordns_cloudflare.py对应测试test_add_txt_record_bad_credszone 未找到若所有域名猜测都无结果会提示确认域名输入正确、域名已关联到该 Cloudflare 账户或 Token 具有该域名访问权限dns_cloudflare.py网络异常APIConnectionError统一包装为带 “Network error” 的PluginError对应测试test_add_txt_record_connection_error_on_create等。所有 API 错误统一封装为certbot.errors.PluginError抛出由 Certbot 上层统一处理。6.5 删除阶段的健壮性del_txt_record()设计为“尽力而为”zone 查找失败时记录 debug 日志并直接返回无需清理的场景记录不存在时记录 debug 日志并返回删除失败API 错误或网络错误仅输出 warning不中断流程。这样保证了清理阶段绝不因 Cloudflare 侧问题导致 Certbot 主流程报错。对应的测试用例覆盖了 zone 查找失败、记录不存在、删除失败、网络错误等各种路径dns_cloudflare_test.py。七、测试与代码组织插件的测试集中在 certbot-dns-cloudflare/src/certbot_dns_cloudflare/_internal/tests/dns_cloudflare_test.py分为两组AuthenticatorTest基于dns_test_common.BaseAuthenticatorTest与test_util.TempDirTestCasemock 掉_get_cloudflare_client验证 perform/cleanup 的调用参数、凭证校验的各种组合CloudflareClientTest直接对_CloudflareClient的增删记录、zone 查找、错误码容错、网络错误处理进行单测。测试中使用test_util.patch_display_util()屏蔽交互式提示用dns_test_common.write写临时凭证文件。安装测试依赖后可运行pip install -e ./certbot-dns-cloudflare[test] pytest certbot-dns-cloudflare/src/certbot_dns_cloudflare/_internal/tests/八、常见问题排查速查现象原因与处置提示dns_cloudflare_email is required when using a Global API Key使用 Global Key 时 email 与 key 必须成对提供检查 INI 文件提示Unsafe permissions on credentials configuration file凭证文件权限过宽执行chmod 600 ~/.secrets/certbot/cloudflare.inizone_id 查找失败且提示 6003/9103/9109凭证本身有问题检查 Token/Key 是否复制完整、email 是否正确、Token 是否有效Cloudflare 后台 API Tokens 页面可管理zone_id 查找失败且提示 “Token has access to the domain”确认域名输入正确且已托管在 Cloudflare 账户下Token 已授予对应 zone 的Zone:DNS:Edit权限创建记录时报错 1009检查 API Token 是否具备Zone:DNS:Edit权限ACME 验证失败适当增大--dns-cloudflare-propagation-seconds默认 10后再试九、补充手动 hook 方案对比Certbot 主文档 certbot/docs/using.rst 还给出了一个“仅作示例、勿直接使用”的手动 DNS-01 方案通过--manual-auth-hook/--manual-cleanup-hook配合 curl 脚本调用 Cloudflare API v4 增删 TXT 记录。相比该方案本插件将凭证校验、zone 查找、错误码容错、传播等待、清理幂等全部自动化并接入 Certbot 续期流程是生产环境的推荐做法。相关资源插件文档certbot-dns-cloudflare/docs/index.rst 与 certbot-dns-cloudflare/docs/api.rst插件实现certbot-dns-cloudflare/src/certbot_dns_cloudflare/_internal/dns_cloudflare.py插件测试certbot-dns-cloudflare/src/certbot_dns_cloudflare/_internal/tests/dns_cloudflare_test.py基类实现certbot/src/certbot/plugins/dns_common.py插件打包声明certbot-dns-cloudflare/pyproject.toml【免费下载链接】certbotCertbot is EFFs tool to obtain certs from Lets Encrypt and (optionally) auto-enable HTTPS on your server. It can also act as a client for any other CA that uses the ACME protocol.项目地址: https://gitcode.com/gh_mirrors/ce/certbot创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门