- 网络安全
- 密码学
【免费下载链接】lego
Let's Encrypt/ACME client and library written in Go
导读
本指南以 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.com与example.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 | 客户端 ID | EnvClientID |
CLOUDDNS_EMAIL | 账户邮箱 | EnvEmail |
CLOUDDNS_PASSWORD | 账户密码 | EnvPassword |
凭据缺失时的校验行为
从源码看,凭据校验存在两道关卡:
- 环境变量存在性检查:
NewDNSProvider()调用env.Get(EnvClientID, EnvEmail, EnvPassword)读取三个环境变量,任一缺失即返回形如clouddns: some credentials information are missing: CLOUDDNS_CLIENT_ID的错误; - 值非空检查:
NewDNSProviderConfig()中,即使环境变量已设置但值为空字符串,也会返回clouddns: credentials missing。
这两类边界场景在 clouddns_test.go 的TestNewDNSProvider与TestNewDNSProviderConfig中均有完整测试用例覆盖,你可以据此确认自己的配置是否符合预期。
用_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_TIMEOUT | API 请求超时(秒) | 30 |
CLOUDDNS_POLLING_INTERVAL | DNS 传播检查的轮询间隔(秒) | 5 |
CLOUDDNS_PROPAGATION_TIMEOUT | DNS 传播最大等待时间(秒) | 120 |
CLOUDDNS_TTL | 挑战用 TXT 记录的 TTL(秒) | 300 |
参数含义与源码对应关系
CLOUDDNS_TTL:写入的 TXT 记录 TTL,同时被用作publish阶段请求体中的soaTtl字段(见下文发布流程),对应 internal/client.go 中的publishRecords方法。若你的权威 DNS 服务器刷新较慢,可适当调低以加速挑战验证。CLOUDDNS_PROPAGATION_TIMEOUT与CLOUDDNS_POLLING_INTERVAL:由DNSProvider.Timeout()返回给 lego 的挑战框架(clouddns.go),控制"写入记录后等待全局 DNS 生效"的总时限与轮询节奏。传播慢的 DNS 服务商建议调大超时。CLOUDDNS_HTTP_TIMEOUT:作用于内部http.Client的超时设置,可防止 CloudDNS API 长时间无响应导致挑战挂起。
与凭据一致,这四项同样支持_FILE后缀。
挑战流程与源码级实现原理
CloudDNS 提供商实现了 lego 的challenge.Provider接口(Present与CleanUp),核心逻辑位于 clouddns.go,底层通信由 internal/client.go 完成。
Present:创建挑战 TXT 记录
Present的执行链路如下:
- 通过
dns01.GetChallengeInfo计算挑战记录名(如_acme-challenge.example.com)与校验值; - 调用
FindZoneByFqdn自动推导权威 DNS 区域(zone); - 先登录换取访问令牌,再依次执行:
getDomain:向POST /clouddns/domain/search提交搜索请求,按clientId与domainName精确定位域名 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在挑战完成或失败后清理记录:
- 同样先定位 zone 与域名;
- 通过
GET /clouddns/domain/{id}拉取域名下的全部记录,按记录名与TXT类型匹配目标记录(internal/client.go); - 调用
DELETE /clouddns/record/{id}删除该记录; - 最后再次调用
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_ID、CLOUDDNS_EMAIL、CLOUDDNS_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
相关推荐
Jekyll Gitbook 主题 LaTeX 数学公式指南:MathJax 渲染公式一步到位
Jekyll Gitbook 主题 LaTeX 数学公式指南:MathJax 渲染公式一步到位 jekyll gitbook 是一款把 Jekyll 静态站点打
网络安全密码学GetQzonehistory:你的QQ空间时光机,一键备份十年青春回忆
GetQzonehistory:你的QQ空间时光机,一键备份十年青春回忆 你是否曾翻看QQ空间,发现那些承载着青春记忆的说说和照片正在慢慢消失?超过70%的QQ
网络安全密码学Karpenter v1.13 配置参考:环境变量、CLI 参数、Feature Gates 与 Batching 调优实战
Karpenter v1.13 配置参考:环境变量、CLI 参数、Feature Gates 与 Batching 调优实战 本篇指南基于 karpenter
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考