lego 集成 CloudDNS DNS-01 挑战指南:环境变量配置、参数调优与源码实现解析
2026/9/24 15:07:53 网站建设 项目流程
  • 网络安全
  • 密码学

【免费下载链接】lego

Let's Encrypt/ACME client and library written in Go

项目地址:https://gitcode.com/gh_mirrors/le/lego
点击查看免费下载

导读

本指南以 lego 官方自动生成的 CloudDNS DNS 提供商文档(docs/content/dns/zz_gen_clouddns.md)为骨架,系统讲解如何利用 lego 的 DNS-01 挑战模式,通过 VS Hosting 旗下的 CloudDNS 服务自动签发和续期 Let's Encrypt 证书。阅读本文后,你将掌握 CloudDNS 提供商的三项核心凭据与四项可选参数的完整语义、_FILE后缀引用文件凭据的安全做法,以及从 CLI 命令到 Go 源码调用链的完整原理,能够直接投入生产环境签发通配符证书。

CloudDNS 提供商概览

CloudDNS 是 lego(Let's Encrypt/ACME client and library written in Go)内置的 DNS 提供商之一,负责通过 CloudDNS 的公开 API 自动创建和清理 DNS-01 挑战所需的 TXT 记录。

属性
提供商代码(Code)clouddns
引入版本(Since)v3.6.0
提供商来源clouddns.toml 中声明的 VS Hosting(vshosting.eu)CloudDNS 服务

在 lego 源码中,CloudDNS 提供商的注册位于 providers/dns/zz_gen_dns_providers.go,即NewDNSChallengeProviderByName工厂函数中的case "clouddns"分支,因此 CLI 中通过--dns clouddns即可直接选中该提供商。

快速开始:使用 CloudDNS 签发通配符证书

原文档给出的完整命令如下:

CLOUDDNS_CLIENT_ID=bLsdFAks23429841238feb177a572aX \ CLOUDDNS_EMAIL=you@example.com \ CLOUDDNS_PASSWORD=b9841238feb177a84330f \ lego run --dns clouddns -d '*.example.com' -d example.com

该命令一次命令同时为*.example.comexample.com两个域名发起 ACME 订单,其中:

  • --dns clouddns指定使用 CloudDNS 提供商完成 DNS-01 挑战;
  • -d '*.example.com'-d example.com是组合签发通配符证书的典型用法(通配符域名必须通过 DNS-01 验证,无法使用 HTTP-01 或 TLS-ALPN-01);
  • 三条CLOUDDNS_*环境变量为必需凭据,缺一不可。

凭据配置:三项必填环境变量

CloudDNS 提供商要求三个凭据,均通过环境变量注入,完整定义见 clouddns.go:

环境变量名说明对应源码常量
CLOUDDNS_CLIENT_ID客户端 IDEnvClientID
CLOUDDNS_EMAIL账户邮箱EnvEmail
CLOUDDNS_PASSWORD账户密码EnvPassword

凭据缺失时的校验行为

从源码看,凭据校验存在两道关卡:

  1. 环境变量存在性检查NewDNSProvider()调用env.Get(EnvClientID, EnvEmail, EnvPassword)读取三个环境变量,任一缺失即返回形如clouddns: some credentials information are missing: CLOUDDNS_CLIENT_ID的错误;
  2. 值非空检查NewDNSProviderConfig()中,即使环境变量已设置但值为空字符串,也会返回clouddns: credentials missing

这两类边界场景在 clouddns_test.go 的TestNewDNSProviderTestNewDNSProviderConfig中均有完整测试用例覆盖,你可以据此确认自己的配置是否符合预期。

_FILE后缀引用文件中的凭据

原文档明确指出:所有环境变量名均可追加_FILE后缀,改为从一个文件读取值。例如将密码保存在权限受限的文件中时:

CLOUDDNS_CLIENT_ID=bLsdFAks23429841238feb177a572aX \ CLOUDDNS_EMAIL=you@example.com \ CLOUDDNS_PASSWORD_FILE=/run/secrets/clouddns_password \ lego run --dns clouddns -d '*.example.com' -d example.com

这种方式适合容器、Kubernetes Secret 或 CI 流水线场景,避免在命令行历史或进程列表中泄露明文凭据。_FILE后缀机制是 lego 所有 DNS 提供商的通用约定,详见 DNS 提供商的配置与凭据通用说明(即原文档中dns#configuration-and-credentials锚点指向的页面)。

附加配置:四项可选参数

CloudDNS 提供商还支持四项可选环境变量,用于控制 API 请求与 DNS 传播等待行为,默认值定义于NewDefaultConfig()(clouddns.go):

环境变量名说明默认值
CLOUDDNS_HTTP_TIMEOUTAPI 请求超时(秒)30
CLOUDDNS_POLLING_INTERVALDNS 传播检查的轮询间隔(秒)5
CLOUDDNS_PROPAGATION_TIMEOUTDNS 传播最大等待时间(秒)120
CLOUDDNS_TTL挑战用 TXT 记录的 TTL(秒)300

参数含义与源码对应关系

  • CLOUDDNS_TTL:写入的 TXT 记录 TTL,同时被用作publish阶段请求体中的soaTtl字段(见下文发布流程),对应 internal/client.go 中的publishRecords方法。若你的权威 DNS 服务器刷新较慢,可适当调低以加速挑战验证。
  • CLOUDDNS_PROPAGATION_TIMEOUTCLOUDDNS_POLLING_INTERVAL:由DNSProvider.Timeout()返回给 lego 的挑战框架(clouddns.go),控制"写入记录后等待全局 DNS 生效"的总时限与轮询节奏。传播慢的 DNS 服务商建议调大超时。
  • CLOUDDNS_HTTP_TIMEOUT:作用于内部http.Client的超时设置,可防止 CloudDNS API 长时间无响应导致挑战挂起。

与凭据一致,这四项同样支持_FILE后缀。

挑战流程与源码级实现原理

CloudDNS 提供商实现了 lego 的challenge.Provider接口(PresentCleanUp),核心逻辑位于 clouddns.go,底层通信由 internal/client.go 完成。

Present:创建挑战 TXT 记录

Present的执行链路如下:

  1. 通过dns01.GetChallengeInfo计算挑战记录名(如_acme-challenge.example.com)与校验值;
  2. 调用FindZoneByFqdn自动推导权威 DNS 区域(zone);
  3. 先登录换取访问令牌,再依次执行:
    • getDomain:向POST /clouddns/domain/search提交搜索请求,按clientIddomainName精确定位域名 ID(internal/client.go);
    • addTxtRecord:向POST /clouddns/record-txt写入一条类型为TXT的记录(记录结构定义见 internal/types.go);
    • publishRecords:向PUT /clouddns/domain/{id}/publish提交发布请求,请求体仅含soaTtl字段(测试 fixture 见 internal/fixtures/publish-request.json)。

CleanUp:删除挑战 TXT 记录

CleanUp在挑战完成或失败后清理记录:

  1. 同样先定位 zone 与域名;
  2. 通过GET /clouddns/domain/{id}拉取域名下的全部记录,按记录名与TXT类型匹配目标记录(internal/client.go);
  3. 调用DELETE /clouddns/record/{id}删除该记录;
  4. 最后再次调用publishRecords发布变更,确保清理结果对外生效。

认证机制:登录换取 Bearer Token

每次挑战操作前,客户端都会调用POST https://admin.vshosting.cloud/api/public/auth/login(登录接口定义于 internal/identity.go),以邮箱 + 密码换取accessToken,随后所有 API 请求通过Authorization: Bearer <token>头发送。从源码结构看,登录令牌被放入 context 传递,属于"每次挑战即时登录"的实现方式,而非长期缓存。

测试验证

该流程有双层测试保障:

  • 单元测试:使用 mock HTTP 服务器逐段校验请求路径、请求体与 fixture 完全一致,见 internal/client_test.go,请求体 fixture 存放在 internal/fixtures;
  • 实时(live)测试TestLivePresent/TestLiveCleanUp(clouddns_test.go)会真实调用 CloudDNS API 完成一次完整的"创建 → 清理"验证,运行前需通过测试框架设置真实的CLOUDDNS_*环境变量与测试域名。

常见问题与排障提示

  • 提示凭据缺失:逐一确认CLOUDDNS_CLIENT_IDCLOUDDNS_EMAILCLOUDDNS_PASSWORD(或对应的_FILE变量)均已设置且非空;环境变量存在但值为空同样会被拒绝。
  • domain not found: <zone>getDomain搜索不到匹配 zone 时抛出该错误,请确认域名已加入你的 CloudDNS 账户且 zone 名称与-d参数一致。
  • 挑战等待超时:若 DNS 传播较慢,可调大CLOUDDNS_PROPAGATION_TIMEOUT、调小CLOUDDNS_POLLING_INTERVAL以提升成功率。
  • 确认 API 可达性:API 基地址固定为https://admin.vshosting.cloud/clouddns,若网络环境受限(如企业代理),请确保该域名可访问;相关 API 文档入口在 CloudDNS 管理后台的 Swagger 页面中提供。

小结

CloudDNS 提供商是 lego 通过 DNS-01 为通配符域名自动签发证书的标准通道之一:三必填一可选的简单配置模型、_FILE后缀的安全增强、以及对"定位域名 → 写记录 → 发布 → 轮询传播 → 清理记录"全链路的自动化实现,使其非常适合在无人值守的自动化运维环境中使用。本文涉及的配置清单可直接对照源码常量(clouddns.go)、客户端实现(internal/client.go)与测试用例(clouddns_test.go)继续深入研读。

  • 网络安全
  • 密码学

【免费下载链接】lego

Let's Encrypt/ACME client and library written in Go

项目地址:https://gitcode.com/gh_mirrors/le/lego
点击查看免费下载
上一篇:Portainer企业版 vs 社区版:如何选择最适合你的版本
下一篇:FunASR `funasr` 命令行接口实战指南:本地音频转写、结构化结果与 SRT 字幕生成

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询