☰
使用 lego 通过 Yandex 360 完成 DNS-01 挑战:配置指南与源码解析
2026/9/25 9:52:59 网站建设 项目流程
  • 网络安全
  • 密码学

【免费下载链接】lego

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

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

导读:本文以 lego(Go 编写的 Let's Encrypt/ACME 客户端)官方 DNS 提供商文档为骨架,系统讲解如何配置yandex360提供商,通过 Yandex 360 的 Domain DNS 服务自动完成 ACME DNS-01 挑战。读完本文,你将掌握YANDEX360_OAUTH_TOKEN、YANDEX360_ORG_ID等核心凭据的获取与使用方式、全部可选调优参数(超时、轮询间隔、TTL)的含义,并能结合 lego 源码理解该提供商在后台调用 Yandex 360 API 的完整流程,从而在实际环境中正确签发和续期通配符证书。

一、Yandex 360 提供商概览

lego 内置了面向 Yandex 360 中,并由生成器自动渲染为官方文档 docs/content/dns/zz_gen_yandex360.md:

  • Code:yandex360(在lego命令行中通过--dns yandex360指定)
  • Since:v4.14.0(即该提供商自 lego v4.14.0 版本起可用)
  • 官方 API:Yandex 360 API 的 DomainDNSService(https://yandex.ru/dev/api360/doc/ref/DomainDNSService/)

与所有 DNS 提供商一样,它的定位是:在 ACME DNS-01 挑战期间,程序自动向你的 DNS 托管商(这里是 Yandex 360)写入一条_acme-challengeTXT 记录,待 ACME 服务器验证通过后,再自动删除该记录。因此,使用它之前你需要已经将待签发证书的域名解析托管在 Yandex 360 的组织(org)下。

二、快速上手:命令行用法

文档给出的最简用法是设置两个环境变量后直接运行lego run:

YANDEX360_OAUTH_TOKEN=<your OAuth Token> \ YANDEX360_ORG_ID=<your organization ID> \ lego run --dns yandex360 -d '*.example.com' -d example.com

其中:

  • -d '*.example.com'与-d example.com分别签发通配符域名和裸域名,二者都需要 DNS-01 挑战,因此适合使用 DNS 提供商方式;
  • --dns yandex360指定使用 Yandex 360 提供商;
  • 两个环境变量缺一不可,缺少任何一个都会在初始化阶段直接报错(详见下文"凭据"与"源码解析")。

这种方式的适用前提:你需要一个 Yandex 360 组织的 OAuth Token,且该 Token 具备管理组织下域名 DNS 记录的权限;同时,example.com的 DNS 解析必须托管在 Yandex 360 中。

三、凭据(Credentials)

文档定义的必填凭据共两项:

环境变量名描述
YANDEX360_OAUTH_TOKENOAuth Token
YANDEX360_ORG_ID组织 ID(organization ID)

凭据的_FILE后缀支持

文档特别说明:所有环境变量名都可以追加_FILE后缀,改为引用一个文件路径,而不是直接写值。例如:

YANDEX360_OAUTH_TOKEN_FILE=/path/to/oauth_token \ YANDEX360_ORG_ID_FILE=/path/to/org_id \ lego run --dns yandex360 -d '*.example.com'

/path/to/oauth_token文件内容即为 Token 字符串。这一机制适用于所有 lego 提供商,通用说明见 docs/content/dns/_index.md 中的 "Configuration and Credentials" 一节(以 Cloudflare 为例演示了CLOUDFLARE_EMAIL_FILE、CLOUDFLARE_API_KEY_FILE的用法)。它尤其适合在 CI/CD、容器或密钥管理场景中,避免把 Token 明文写进命令行或环境。

凭据校验逻辑(源码确认)

从源码 providers/dns/yandex360/yandex360.go 可以看到,NewDNSProvider()会调用env.Get(EnvOAuthToken, EnvOrgID)一次性读取两个变量,任何一个缺失都会返回错误;随后OrgID会通过strconv.ParseInt(values[EnvOrgID], 10, 64)解析为int64。对应的测试用例 providers/dns/yandex360/yandex360_test.go 覆盖了三种场景:

  • 两个变量都提供:成功创建 provider;
  • 缺少YANDEX360_ORG_ID:报错yandex360: some credentials information are missing: YANDEX360_ORG_ID;
  • 缺少YANDEX360_OAUTH_TOKEN:报错yandex360: some credentials information are missing: YANDEX360_OAUTH_TOKEN。

此外,在底层客户端 providers/dns/yandex360/internal/client.go 中,Token 为空或OrgID为 0 也会被拒绝(OAuth token is required/orgID is required)。因此请确保 OAuth Token 非空且组织 ID 是合法的非零数字。

四、附加配置(Additional Configuration)

除了凭据,该提供商还支持四项可选调优参数,文档给出的默认值如下:

环境变量名描述默认值
YANDEX360_HTTP_TIMEOUTAPI 请求超时(秒)30
YANDEX360_POLLING_INTERVALDNS 传播检查间隔(秒)2
YANDEX360_PROPAGATION_TIMEOUT等待 DNS 传播的最大时间(秒)60
YANDEX360_TTL挑战 TXT 记录的 TTL(秒)21600

这些变量同样支持_FILE后缀。

默认值在源码中的体现

从 providers/dns/yandex360/yandex360.go 的NewDefaultConfig()可以看到默认值的真实来源:

  • TTL:env.GetOrDefaultInt(EnvTTL, 21600),默认 21600 秒(6 小时);
  • PropagationTimeout:env.GetOrDefaultSecond(EnvPropagationTimeout, dns01.DefaultPropagationTimeout),即复用 lego 全局默认的 DNS 传播超时(60 秒);
  • PollingInterval:env.GetOrDefaultSecond(EnvPollingInterval, dns01.DefaultPollingInterval),即全局默认轮询间隔(2 秒);
  • HTTPClient.Timeout:env.GetOrDefaultSecond(EnvHTTPTimeout, 30*time.Second),默认 30 秒。

三个超时/轮询参数通过DNSProvider.Timeout()方法(yandex360.go)暴露给 lego 的挑战调度器,用于决定"写完 TXT 记录后等待多久、以什么频率去检查 DNS 传播是否完成"。如果 Yandex 360 的 DNS 生效较慢,可以适当增大YANDEX360_PROPAGATION_TIMEOUT;若 API 响应较慢,可增大YANDEX360_HTTP_TIMEOUT。

五、挑战流程与 Yandex 360 API 调用(源码级解析)

为了说明"程序到底做了什么",下面结合源码梳理 DNS-01 挑战在 Yandex 360 提供商中的完整链路。

1. Present:添加 TXT 记录

Present(yandex360.go)负责写入挑战记录,步骤如下:

  1. 由dns01.GetChallengeInfo计算挑战记录全限定名EffectiveFQDN(通常形如_acme-challenge.example.com.)与校验值;
  2. 调用dns01.DefaultClient().FindZoneByFqdn通过 DNS 查询找到权威区域(authZone),例如example.com.;
  3. 用dns01.ExtractSubDomain从全限定名中剥离区域,得到子域名_acme-challenge;
  4. 构造internal.Record{Name: "_acme-challenge", TTL: config.TTL, Text: 校验值, Type: "TXT"},调用client.AddRecord(ctx, authZone, record)。

底层 HTTP 调用在 providers/dns/yandex360/internal/client.go 中实现:

POST https://api360.yandex.net/directory/v1/org/{orgId}/domains/{domain}/dns

请求携带Authorization: OAuth <token>头与 JSON 请求体,成功后返回记录的recordId。Present会把recordId以 token 为键缓存在recordIDsmap 中(用互斥锁保护),供后续清理使用。

2. CleanUp:删除 TXT 记录

挑战验证完成后,CleanUp(yandex360.go)根据缓存的recordId调用:

DELETE https://api360.yandex.net/directory/v1/org/{orgId}/domains/{domain}/dns/{recordId}

删除成功后从缓存中移除对应记录。如果找不到缓存的 recordID,会返回yandex360: unknown recordID for %q错误。

3. 数据模型与错误处理

Yandex 360 API 返回的记录结构定义在 providers/dns/yandex360/internal/types.go,Record结构体包含recordId、name、text、ttl、type等字段(还有address、priority、weight等供其他记录类型使用)。非 2xx 响应会被解析为APIError{code, message, details}(types.go),错误信息形如[status code: %d] <code>: <message>: <details>。

4. 测试与模拟验证

该提供商的正确性由两类测试保障:

  • 单元/模拟测试:providers/dns/yandex360/internal/client_test.go 用httptest模拟服务器,断言请求路径为POST/DELETE /directory/v1/org/123456/domains/example.com/dns,请求体为{"name":"_acme-challenge","text":"txtxtxt","ttl":60,"type":"TXT"},并验证请求头包含Authorization: OAuth secret。对应的响应夹具在 add-record.json、delete-record.json、error.json。
  • 实况测试(Live Test):yandex360_test.go 中的TestLivePresent/TestLiveCleanUp需要真实凭据才会运行,默认跳过。

六、作为 Go 库使用(Programmatic Usage)

除了 CLI,你还可以在 Go 程序中直接使用该提供商。核心 API 有两个:

import "github.com/go-acme/lego/v5/providers/dns/yandex360" // 方式一:从环境变量读取凭据 provider, err := yandex360.NewDNSProvider() if err != nil { log.Fatal(err) } // 方式二:通过 Config 结构体手动配置 config := yandex360.NewDefaultConfig() config.OAuthToken = "your-token" config.OrgID = 123456 config.TTL = 300 // 自定义 TTL(秒) provider, err = yandex360.NewDNSProviderConfig(config) if err != nil { log.Fatal(err) }

Config结构体(yandex360.go)字段包括OAuthToken、OrgID(int64)、PropagationTimeout、PollingInterval、TTL和可选的HTTPClient。若HTTPClient为 nil,会使用默认 30 秒超时的 client。将provider传给 lego 的certificate.Obtain等流程即可;DNSProvider同时实现了challenge.Provider与challenge.ProviderTimeout接口(见 yandex360.go),因此 lego 能自动获取超时与轮询参数。

七、常见问题与排错建议

根据源码错误路径和测试用例,可以总结以下排查思路:

  1. 提示some credentials information are missing: ...:YANDEX360_OAUTH_TOKEN或YANDEX360_ORG_ID未设置。注意_FILE后缀变量与原变量只能二选一,且文件路径必须可读。
  2. 提示OAuth token is required/orgID is required:Token 为空字符串,或ORG_ID解析后为 0。
  3. API 返回 401(如测试中模拟的status code: 401):OAuth Token 无效或没有该组织域名的 DNS 管理权限,请检查 Token 的作用域。
  4. 提示could not find zone for domain ...:FindZoneByFqdn无法通过公共 DNS 找到该域名的权威区域,常见原因是域名并未托管在 Yandex 360,或 NS 记录尚未生效。
  5. 挑战验证超时:可适当调大YANDEX360_PROPAGATION_TIMEOUT与YANDEX360_POLLING_INTERVAL,以容忍 Yandex 360 DNS 生效延迟。

八、延伸阅读

  • 该提供商的生成文档源文件:docs/content/dns/zz_gen_yandex360.md
  • 提供商元数据配置(TOML):providers/dns/yandex360/yandex360.toml
  • 提供商实现: providers/dns/yandex360/yandex360.go
  • 底层 API 客户端:providers/dns/yandex360/internal/client.go
  • DNS 挑战通用配置与_FILE机制:docs/content/dns/_index.md

注:上述全部环境变量与默认值均以当前仓库 v4.14.0+ 的实现为准;使用前请确认你的 lego 版本不低于 v4.14.0,并遵循 README.md 中的安装与全局配置说明。

  • 网络安全
  • 密码学

【免费下载链接】lego

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

项目地址:https://gitcode.com/gh_mirrors/le/lego
点击查看免费下载
上一篇:番茄小说下载器完整指南:如何轻松搭建个人离线图书馆
下一篇:5款VLC皮肤主题:让你的播放器成为视觉享受的艺术品

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

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

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

立即咨询