news 2026/9/24 19:54:31

使用 lego 通过 Domeneshop 完成 DNS-01 挑战:凭证配置、超时调优与源码实现解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 lego 通过 Domeneshop 完成 DNS-01 挑战:凭证配置、超时调优与源码实现解析
  • 网络安全
  • 密码学

【免费下载链接】lego

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

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

导读

Domeneshop(也写作 "Domainnameshop")是挪威的一家域名与托管服务商。lego 项目从 v4.3.0 起内置了domeneshop这个 DNS 提供商,用于在自动签发 Let's Encrypt 证书时解决 DNS-01 挑战:通过 Domeneshop 公开 API 自动创建 / 删除_acme-challengeTXT 记录。本文将基于官方文档 docs/content/dns/zz_gen_domeneshop.md(该文档由 providers/dns/domeneshop/domeneshop.toml 自动生成)与仓库源码,完整介绍凭证获取、环境变量配置、超时参数调优,并深入解读其底层实现与测试用例,帮助你真正把该提供商跑起来并理解其工作原理。

一、Provider 基本信息

项目
Code(命令行使用名)domeneshop
别名domainnameshop
引入版本v4.3.0
支持挑战类型DNS-01(TXT 记录)
实现源码providers/dns/domeneshop/domeneshop.go

从源码结构看,该提供商由两层组成:对外暴露的 DNSProvider 负责与 lego 的挑战框架对接(实现PresentCleanUpTimeout等接口),内部则封装了一个精简的 Domeneshop API 客户端 internal/client.go,仅处理 ACME 场景所需的 TXT 记录增删操作。

二、前置条件

在使用该提供商前需要确认:

  1. 待签发证书的域名(或其权威 DNS 区域)托管在 Domeneshop,且该域名在 Domeneshop 侧已启用 DNS 服务
    • 这一点在源码中有明确校验:internal.Client.GetDomainByName遍历域名列表时,会跳过Services.DNS == false的域名(internal/client.go),因为未启用 DNS 服务的域名无法添加记录。
  2. 已拥有 Domeneshop API 凭证(API token + API secret)。创建方法见 Domeneshop API 文档的 "Authentication" 章节,凭证本质是一对用于 HTTP Basic Auth 的 token/secret 组合(见下文源码解析)。

三、快速上手:签发证书

官方文档给出的典型用法如下,通过环境变量注入凭证,然后使用--dns domeneshop指定提供商:

DOMENESHOP_API_TOKEN=<token> \ DOMENESHOP_API_SECRET=<secret> \ lego run --dns domeneshop -d '*.example.com' -d example.com

要点说明:

  • -d '*.example.com'签发通配符证书时必须走 DNS-01 挑战,这是dns domeneshop的核心场景;
  • 同时传入根域名example.com可以在一张证书里同时覆盖根域与所有子域;
  • 命令执行过程中,lego 会调用Present自动在 Domeneshop 创建 TXT 记录,等待 DNS 传播验证通过后,再调用CleanUp删除记录(详见第五节)。

四、凭证与环境变量配置

4.1 必填凭证

环境变量名说明
DOMENESHOP_API_SECRETAPI secret
DOMENESHOP_API_TOKENAPI token

两个变量缺一不可。源码中 NewDNSProvider 通过env.Get(EnvAPIToken, EnvAPISecret)一次性读取并校验,缺失时会直接报错;对应的测试用例 domeneshop_test.go 覆盖了四种情况:

  • 两者齐全 → 创建成功;
  • 两者都缺失 → 报错domeneshop: some credentials information are missing: DOMENESHOP_API_TOKEN,DOMENESHOP_API_SECRET
  • 仅缺 token → 报错并指明缺失项;
  • 仅缺 secret → 同上。

因此排查问题时,先确认终端里两个变量都已正确 export(或使用_FILE变体,见 4.3)。

4.2 可选调优参数

环境变量名说明默认值
DOMENESHOP_HTTP_TIMEOUTAPI 请求超时时间(秒)30
DOMENESHOP_POLLING_INTERVAL两次 DNS 传播检测之间的间隔(秒)20
DOMENESHOP_PROPAGATION_TIMEOUT等待 DNS 传播的最长时间(秒)300

这些默认值在 NewDefaultConfig 中均有对应实现,且与Timeout()接口直接挂钩:Timeout()返回的(timeout, interval)就是PropagationTimeoutPollingInterval(domeneshop.go),lego 将依据这两个值决定轮询_acme-challengeTXT 记录何时在全球 DNS 中生效。

调优建议(依据源码默认行为推断):

  • 若你的 DNS 服务商传播较慢,可调大DOMENESHOP_PROPAGATION_TIMEOUT,避免在 300 秒内未生效时签发失败;
  • 若想加快签发速度,可适当调小DOMENESHOP_POLLING_INTERVAL(20 秒是相对保守的轮询间隔);
  • DOMENESHOP_HTTP_TIMEOUT只影响与 API 的单次请求时长,一般无需修改。

4.3_FILE后缀:用文件代替值

文档明确说明:"环境变量名可通过_FILE后缀改为引用文件而不是直接写值"。例如:

DOMENESHOP_API_TOKEN_FILE=/run/secrets/domeneshop_token \ DOMENESHOP_API_SECRET_FILE=/run/secrets/domeneshop_secret \ lego run --dns domeneshop -d '*.example.com' -d example.com

这在 Docker/Kubernetes Secret 挂载等场景下非常实用。该机制由 lego 统一的 platform/env/env.go 实现:优先读取KEY本身,为空时再尝试读取KEY_FILE指向的文件内容,并自动去除结尾的换行符(strings.TrimRight(..., "\r\n"))。注意:当KEYKEY_FILE同时存在时,直接的环境变量值优先。

4.4 使用配置文件(File Configuration)

除环境变量外,lego 还支持基于 YAML 的 文件配置模式(lego run --config config.yml)。在文件配置中同样使用DOMENESHOP_*命名空间下的键来提供凭证与调优参数,适合需要把证书签发参数化、版本化的团队。更完整的通用凭证与配置约定可参见 DNS 提供商总览文档。

五、工作原理:Present / CleanUp 与 API 交互

5.1 挑战记录的生命周期

DNSProvider实现了 lego 挑战框架要求的两个核心方法(domeneshop.go):

  • Present(ctx, domain, _, keyAuth):签发前调用。流程为——
    1. dns01.GetChallengeInfo根据域名与keyAuth计算出挑战记录内容;
    2. splitDomain把完整挑战 FQDN 拆成「权威区域 zone」与「主机名 host」两部分(基于 DNS 查询FindZoneByFqdn,splitDomain);
    3. client.GetDomainByName找到对应的域名对象;
    4. client.CreateTXTRecordhost上写入 TXT 记录。
  • CleanUp(ctx, domain, _, keyAuth):验证完成后调用,按相同的 zone/host 拆解逻辑定位域名,再按「host + 记录内容」双重匹配删除对应记录。

5.2 底层 API 客户端

internal/client.go 是对 Domeneshop API(https://api.domeneshop.no/v0)的轻量封装,关键实现细节:

  • 认证方式:每个请求通过req.SetBasicAuth(c.apiToken, c.apiSecret)设置 HTTP Basic Auth(client.go),即 token 作为用户名、secret 作为密码;
  • 创建记录POST /domains/{domainId}/dns,写入的记录固定为Type: "TXT"TTL: 300(CreateTXTRecord),请求体结构可见测试夹具 create_record-request.json;
  • 查询域名GET /domains,返回结构见 getDomains.json,其中services.dns用于过滤未启用 DNS 服务的域名;
  • 删除记录:先GET /domains/{domainId}/dns找到HostData都匹配的记录,再DELETE /domains/{domainId}/dns/{recordId}(DeleteTXTRecord),匹配逻辑见 getDNSRecordByHostData;
  • 数据结构Domain/Service/DNSRecord的 JSON 字段定义在 internal/types.go。

5.3 验证与测试

仓库为 providers/dns/domeneshop/domeneshop_test.go 提供了两类测试:

  • 单元测试TestNewDNSProvider/TestNewDNSProviderConfig校验凭证缺失时的报错行为与默认配置的生成;
  • 在线测试(live test)TestLivePresent/TestLiveCleanUp会真实调用 API 写入123d==这条挑战记录再删除,需要设置真实凭证与DOMENESHOP_DOMAIN环境变量才会执行(envTest.IsLiveTest()判定)。如果你想在接入前做一次真实链路冒烟验证,可以仿照这两个用例进行。

六、以库的形式接入(进阶用法)

除了 CLI,lego 还提供 Go 库接口。若你在自己的程序里调用该提供商,可以使用NewDNSProviderConfig传入一个 Config 结构体:

import "github.com/go-acme/lego/v4/providers/dns/domeneshop" config := domeneshop.NewDefaultConfig() config.APIToken = "your-token" config.APISecret = "your-secret" // 可选:覆盖超时 // config.PropagationTimeout = 10 * time.Minute // config.PollingInterval = 10 * time.Second provider, err := domeneshop.NewDNSProviderConfig(config) if err != nil { log.Fatal(err) }

NewDNSProviderConfig会做两道校验(domeneshop.go):config 不能为 nil;APITokenAPISecret不能为空。同时,注入的HTTPClient会被包上一层clientdebug.Wrap,用于在LEGO_DEBUG开启时输出调试信息,便于排查 API 交互问题。

七、注意事项与常见问题

  1. 凭证必填DOMENESHOP_API_TOKEN/DOMENESHOP_API_SECRET缺一不可,缺失时报错信息会明确点名缺失的变量,可按提示逐个核对。
  2. 域名必须启用 DNS 服务GetDomainByName会跳过services.dns == false的域名,若报 "failed to find matching domain name",请先到 Domeneshop 控制台确认该域名的 DNS 服务状态。
  3. 删除记录依赖内容匹配CleanUp按 host + data 双重匹配删除,如果挑战记录已被第三方手动修改,可能匹配失败,此时需人工清理残留 TXT 记录。
  4. 通配符证书只能走 DNS-01-d '*.example.com'无法使用 HTTP-01,必须搭配--dns,这正是本提供商的使用场景。
  5. 传播等待可调:默认最多等 300 秒、每 20 秒检查一次;遇到 "timeout waiting for record" 类错误时,优先考虑调大DOMENESHOP_PROPAGATION_TIMEOUT
  6. 敏感信息保护:生产环境推荐使用_FILE后缀从 Secret 文件注入凭证,避免 token 出现在进程列表或 shell 历史中。
  • 网络安全
  • 密码学

【免费下载链接】lego

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

项目地址:https://gitcode.com/gh_mirrors/le/lego
点击查看免费下载
上一篇:终极Hyperscan部署指南:从源码编译到生产环境的完整流程
下一篇:RVC-WebUI全攻略:从安装到精通的语音转换神器指南

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 19:53:31

YOLOv5-6.0吸烟检测实战:从训练到部署的避坑指南

简介&#xff1a;这份资源面向计算机视觉方向的学习者与开发者&#xff0c;提供基于YOLOv5-6.0训练完成的吸烟行为检测模型&#xff0c;可用于公共场所、工地、加油站等场景下的吸烟行为识别与预警。包内包含YOLOv5m与YOLOv5s两个已训练权重&#xff0c;目标类别为smoke&#x…

作者头像 李华
网站建设 2026/9/24 19:53:20

回归代码详解:从线性回归到XGBoost的实战指南

1. 内容整体设计与思路拆解1.1 为什么第五天必须讲回归&#xff0c;而且是代码优先先说一个我自己的观察。前四天学员还在跟数据结构、基础语法、可视化缠斗&#xff0c;到了第五天突然进入回归&#xff0c;很多人第一反应是&#xff1a;“是不是有点早&#xff1f;”但恰恰相反…

作者头像 李华
网站建设 2026/9/24 19:53:14

电脑蓝屏开不了机?5步自检法从蓝屏代码到DMP文件找出真凶

电脑蓝屏开不了机&#xff0c;这几年我帮身边朋友处理过至少几十次&#xff0c;说句实话&#xff0c;真正需要送修的重来不超过两成。系统崩溃、驱动打架、外设捣乱&#xff0c;这些软件层面的问题占了大多数&#xff0c;明明自己花半小时就能搞定&#xff0c;结果抱着主机去维…

作者头像 李华
网站建设 2026/9/24 19:53:14

2026年Jira国产替代核心指标:权限模型、硬件流程与API稳定性

1. 这不是“又一个工具测评”&#xff0c;而是研发团队在2026年必须面对的真实选型现场 你刚收到通知&#xff1a;公司启动“研发管理平台国产化替代专项”&#xff0c;要求Q3前完成Jira迁移&#xff0c;预算卡得死&#xff0c;法务对SaaS数据出境有明确红线&#xff0c;运维只…

作者头像 李华
网站建设 2026/9/24 19:53:14

用DailyMed API构建药物情报检索:SPL解析与说明书结构化实践

做医药数据相关开发这几年&#xff0c;我越来越觉得 DailyMed 是个被低估的宝藏数据源。很多人一上手药物情报抓取&#xff0c;第一反应就是扑向 openFDA&#xff0c;因为它的接口直观&#xff0c;返回的是 JSON&#xff0c;文档也花哨&#xff1b;但真正跑起来做药品说明书结构…

作者头像 李华