- 网络安全
- 密码学
【免费下载链接】lego
Let's Encrypt/ACME client and library written in Go
本指南以 lego(Let's Encrypt/ACME client,Go 语言实现)内置的 Simply.com DNS 解析服务商(Provider Code:simply)为主线,完整讲解如何通过 DNS-01 挑战为域名(含通配符域名)自动签发 Let's Encrypt 证书。读完本文,你将掌握 Simply.com 账号凭据与全部环境变量的配置方法、通配符证书签发命令、DNS 传播等待参数的调优方式,并理解 lego 在底层如何调用 Simply.com API 完成 TXT 记录的创建与清理。
Simply.com Provider 简介
Simply.com 是一家丹麦域名注册与 DNS 托管服务商,其公开 API 允许第三方程序以编程方式管理 DNS 记录。lego 从 v4.4.0 起内置了对 Simply.com 的支持,Provider 代码为simply,其声明与文档模板位于 providers/dns/simply/simply.toml,自动生成的官方使用文档即 docs/content/dns/zz_gen_simply.md。
该 Provider 的核心用途是解决DNS-01 挑战:lego 在验证域名所有权时,会通过 Simply.com API 在域名所在的 DNS zone 中自动创建一个_acme-challenge子域名的 TXT 记录,等待记录全球生效后由 ACME 服务器完成验证,验证结束后再自动删除该记录。整个过程无需人工登录 Simply.com 控制台操作,非常适合证书自动化续期场景,也是签发*.example.com这类通配符证书的唯一可行方式(通配符域名只能使用 DNS-01 挑战)。
前置准备:账号与 API Key
使用前需要准备两项凭据,均可在 Simply.com 控制台获取:
| 凭据 | 环境变量 | 说明 |
|---|---|---|
| 账号名(Account Name) | SIMPLY_ACCOUNT_NAME | 形如S000000的 Simply.com 账号标识 |
| API Key | SIMPLY_API_KEY | 控制台中生成的 API 密钥 |
从源码 providers/dns/simply/simply.go 可以看到,所有环境变量统一使用SIMPLY_前缀命名空间,其中EnvAccountName = "SIMPLY_ACCOUNT_NAME"、EnvAPIKey = "SIMPLY_API_KEY"。若这两项凭据缺失,NewDNSProvider会直接返回错误,错误信息会明确列出缺失的变量名。
快速开始:签发通配符证书
配置好环境变量后,一条命令即可同时签发*.example.com与example.com的证书(lego 会自动生成证书私钥并向 Let's Encrypt 提交订单):
SIMPLY_ACCOUNT_NAME=xxxxxx \ SIMPLY_API_KEY=yyyyyy \ lego run --dns simply -d '*.example.com' -d example.com参数说明:
--dns simply:指定使用 Simply.com DNS Provider 完成 DNS-01 挑战;-d '*.example.com':签发通配符证书,注意用引号包裹星号防止 Shell 展开;-d example.com:同时把根域名加入同一张证书(实践中常与通配符一并申请,避免根域名无证书可用)。
证书签发成功后,默认保存在当前目录的.lego目录下,具体路径与证书、密钥的归档细节可参考仓库文档 docs/content/advanced/certificates.md。
凭据配置详解
环境变量表
| 环境变量名 | 描述 |
|---|---|
SIMPLY_ACCOUNT_NAME | 账号名 |
SIMPLY_API_KEY | API Key |
使用_FILE后缀引用文件
所有环境变量名都可以追加_FILE后缀,改为从文件中读取值,避免把密钥直接写在 Shell 历史或命令行中:
SIMPLY_ACCOUNT_NAME_FILE=/path/to/my/account_name \ SIMPLY_API_KEY_FILE=/path/to/my/api_key \ lego run --dns simply -d '*.example.com' -d example.com对应的文件内容只需包含纯值即可,例如/path/to/my/api_key文件内容为一行 API Key 字符串。该机制是 lego 所有 DNS Provider 的通用约定,完整说明见 docs/content/dns/_index.md 中的 "Configuration and Credentials" 章节。lego 会在启动时读取_FILE变量指向的文件内容作为对应配置值。
附加配置参数
| 环境变量名 | 描述 | 默认值 |
|---|---|---|
SIMPLY_HTTP_TIMEOUT | API 请求超时(秒) | 30 |
SIMPLY_POLLING_INTERVAL | DNS 传播检查间隔(秒) | 10 |
SIMPLY_PROPAGATION_TIMEOUT | DNS 传播最大等待时间(秒) | 300 |
SIMPLY_TTL | 用于 DNS 挑战的 TXT 记录 TTL(秒) | 120 |
这些参数同样支持_FILE后缀。它们的默认值定义在 providers/dns/simply/simply.go 的NewDefaultConfig中,实现细节如下:
SIMPLY_HTTP_TIMEOUT:作用于内部 HTTP 客户端,NewDefaultConfig通过env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second)构造http.Client{Timeout: ...},控制每一次 Simply.com API 调用的请求超时;SIMPLY_POLLING_INTERVAL与SIMPLY_PROPAGATION_TIMEOUT:通过DNSProvider.Timeout()方法(simply.go)暴露给挑战框架,分别控制"轮询间隔"与"总等待上限"。需要说明的是,lego 在 challenge/dns01/dns_challenge.go 中定义的全局默认值是传播超时 60 秒、轮询间隔 2 秒,而 Simply.com Provider 将默认值放宽为 300 秒 / 10 秒,以适应该服务商较慢的记录生效速度;SIMPLY_TTL:作为 TXT 记录创建请求中的ttl字段,默认值与 dns01 包的DefaultTTL(120 秒)一致。
若你的域名解析生效较快,可适当缩小SIMPLY_PROPAGATION_TIMEOUT以缩短失败等待时间;若经常遇到传播超时,则可增大该值。
底层实现:挑战如何驱动 Simply.com API
创建 TXT 记录(Present)
DNSProvider.Present(simply.go)负责写入挑战记录,流程为:
- 通过
dns01.GetChallengeInfo计算挑战所需的完整 FQDN 与 TXT 值; - 使用 lego 的
FindZoneByFqdn在 DNS 中定位权威 zone,并剥离末尾点号; - 用
ExtractSubDomain从完整挑战域名中抽出子域名(例如_acme-challenge.example.com中的_acme-challenge); - 构造
internal.Record{Name: subDomain, Data: 挑战值, Type: "TXT", TTL: 配置值},调用AddRecord写入记录; - 将返回的
record_id以挑战 token 为键缓存到recordIDsmap 中(使用互斥锁保护,见 simply.go),供后续清理使用。
从 internal/client.go 可以看到,新增记录实际发送的是POST请求到https://api.simply.com/2/my/products/{zone}/dns/records/端点,请求体格式可由测试夹具 internal/fixtures/add_record-request.json 印证:
{ "name": "_acme-challenge", "data": "ADw2sEd82DUgXcQ9hNBZThJs7zVJkR5v9JeSbAb9mZY", "type": "TXT", "ttl": 120 }删除 TXT 记录(CleanUp)
验证完成后,DNSProvider.CleanUp(simply.go)根据之前缓存的record_id调用DeleteRecord发送DELETE请求到.../dns/records/{id}/端点删除记录,随后将记录 ID 从 map 中移除。若找不到对应记录 ID,会返回明确错误。这种"先记 ID、后删 ID"的设计确保只清理本次挑战创建的记录,不会误删用户原有的 DNS 记录。
API 客户端与鉴权
内部客户端 internal/client.go 还提供了GetRecords(列出 zone 全部记录)与EditRecord(编辑记录)两个方法。所有请求均通过req.SetBasicAuth(c.accountName, c.apiKey)使用 HTTP Basic Auth 鉴权,且要求 JSON 请求/响应格式(Accept: application/json、Content-Type: application/json)。完整 API 交互测试见 internal/client_test.go,其中覆盖了增删改查以及各类错误响应。
常见错误与排查
以下错误信息来自源码与测试夹具,可直接用于排错:
| 错误信息 | 触发场景 | 对应依据 |
|---|---|---|
simply: some credentials information are missing: SIMPLY_ACCOUNT_NAME | 未设置账号名 | simply_test.go |
simply: some credentials information are missing: SIMPLY_API_KEY | 未设置 API Key | 同上 |
Invalid account authorization | 账号名或 API Key 错误 | internal/fixtures/bad_auth_error.json |
Unknown or invalid product reference | zone 域名与账号下托管的域名不匹配 | internal/fixtures/bad_zone_error.json |
Unknown DNS record | 删除/编辑的记录 ID 不存在 | internal/fixtures/invalid_record_id_error.json |
排错建议:先确认SIMPLY_ACCOUNT_NAME与SIMPLY_API_KEY拼写无误,且该账号在 Simply.com 上确实托管了你要签发证书的域名 zone;若 API 返回鉴权错误,请到控制台重新生成 API Key。
测试与验证
仓库为 Simply.com Provider 提供了完整的单元测试与可选的在线测试:
- providers/dns/simply/simply_test.go:验证凭据缺失时的错误分支、
Present/CleanUp的请求路由与响应处理,以及带SIMPLY_DOMAIN环境变量时运行的 live 测试(TestLivePresent/TestLiveCleanUp); - providers/dns/simply/internal/client_test.go:基于 mock 服务器验证四个 API 方法及其错误路径。
若需在本地运行这些测试,可在仓库根目录执行:
go test ./providers/dns/simply/...总结
Simply.com DNS Provider 是 lego 生态中接入成本最低的解析商之一:只需SIMPLY_ACCOUNT_NAME与SIMPLY_API_KEY两个环境变量,配合--dns simply即可自动完成 DNS-01 挑战记录的全生命周期管理,天然支持通配符证书签发与到期自动续期。通过SIMPLY_TTL、SIMPLY_PROPAGATION_TIMEOUT等附加参数,你还可以针对 Simply.com 的记录生效速度对签发流程做精细调优;而源码中的Present/CleanUp实现与 API 测试夹具,则为你排查认证、zone 归属、记录 ID 等各类异常提供了清晰依据。
- 网络安全
- 密码学
【免费下载链接】lego
Let's Encrypt/ACME client and library written in Go
相关推荐
Hindsight 集成指南:为 OpenAI Codex CLI 注入持久化记忆(Auto-Recall / Auto-Retain 实战)
Hindsight 集成指南:为 OpenAI Codex CLI 注入持久化记忆(Auto Recall / Auto Retain 实战) 本文档基于仓库
网络安全密码学lego 使用 Beget.com DNS Provider 签发通配符证书:配置详解与源码原理
lego 使用 Beget.com DNS Provider 签发通配符证书:配置详解与源码原理 本指南聚焦 lego(Let's Encrypt/ACME c
网络安全密码学使用 lego + Namesilo 签发通配符证书:DNS-01 挑战配置、参数详解与实现原理
使用 lego + Namesilo 签发通配符证书:DNS 01 挑战配置、参数详解与实现原理 本指南围绕 lego(Let's Encrypt/ACME 客
网络安全密码学
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考