- 网络安全
- 密码学
【免费下载链接】lego
Let's Encrypt/ACME client and library written in Go
本指南完整讲解 Go 编写的 Let's Encrypt/ACME 客户端 lego 中 Hetzner DNS 提供商(provider code:hetzner)的配置与使用:包括获取 API Token、通过 DNS-01 挑战为域名(含通配符域名)签发证书的命令行示例、全部可调环境变量及其默认值、_FILE后缀与 dotenv 等凭据加载方式,并结合仓库源码剖析其底层调用链(Hetzner Cloud API 的 RRSet 操作与 action 轮询机制),帮助你快速落地并在遇到问题时能定位到具体实现。
Hetzner Provider 概览
Hetzner 是 lego 官方内置的 DNS-01 挑战提供商之一,自v3.7.0起可用(见 hetzner.toml)。它的作用是在 Hetzner DNS 中自动创建/删除 ACME 挑战所需的TXT记录,从而让 lego 无需人工干预即可完成 DNS-01 验证并签发证书。
在 lego 的 DNS 提供商目录(docs/content/dns/_index.md)中,Hetzner 被登记为:
| 属性 | 值 |
|---|---|
| Code(命令行中使用名) | hetzner |
| 引入版本 | v3.7.0 |
| 官方站点 | hetzner.com |
从源码结构看(providers/dns/hetzner/),该 provider 由统一入口hetzner.go对接到两套内部实现:
internal/hetznerv1/:基于Hetzner Cloud API(https://api.hetzner.cloud/v1),使用HETZNER_API_TOKEN,是当前推荐路径;internal/legacy/:基于旧的Hetzner DNS API(https://dns.hetzner.com),使用HETZNER_API_KEY,已被标记为废弃(deprecated)。
两套实现都实现了 lego 的challenge.ProviderTimeout接口(Present/CleanUp/Timeout),对外行为一致,下文会分别说明其内部差异。
快速开始:签发通配符证书
在 Hetzner Cloud 控制台创建 API Token 后,使用官方文档给出的命令即可发起证书签发:
HETZNER_API_TOKEN="xxxxxxxxxxxxxxxxxxxxx" \ lego run --dns hetzner -d '*.example.com' -d example.com要点说明:
--dns hetzner指定使用本 provider,-d(等价于--domains)声明要签发证书的域名;同时给出*.example.com与example.com可签发覆盖根域与所有子域的通配符证书,这正是 DNS-01 挑战相对 HTTP-01 的核心优势——无需对外暴露 80/443 端口。- lego 会自动完成:在 Hetzner 中添加挑战
TXT记录 → 等待 DNS 传播 → 向 ACME 服务器发起验证 → 验证通过后清理TXT记录。 - 若想先了解该 provider 支持的全部 CLI 选项,可运行
lego run --help查看--dns相关参数,详见参考文档 ref-flags。
凭据配置:HETZNER_API_TOKEN
Hetzner provider 唯一必需的凭据环境变量是HETZNER_API_TOKEN(API token),可在 Hetzner Cloud 项目中创建并授予 DNS 读写权限。
基础用法与_FILE后缀
所有凭据类环境变量都支持两种取值方式:
直接给值:
HETZNER_API_TOKEN="xxxxxxxxxxxxxxxxxxxxx" lego run --dns hetzner -d example.com引用文件(变量名追加
_FILE后缀,文件内容即凭据值,文件内只能包含该值本身):HETZNER_API_TOKEN_FILE=/etc/lego/hetzner_token \ lego run --dns hetzner -d example.com该机制对后文所有
HETZNER_*变量均适用,相关约定详见 DNS Providers 文档 的 "Configuration and Credentials" 一节。
使用 dotenv 文件
当凭据较多或希望与命令解耦时,可用--env-file加载 dotenv 文件(格式为KEY=value,每行一个):
lego run --dns hetzner -d example.com --env-file .env.hetzner.env.hetzner内容示例:
HETZNER_API_TOKEN=xxxxxxxxxxxxxxxxxxxxx HETZNER_TTL=120使用配置文件(.lego.yml)
如果使用 lego 的 YAML 配置文件(见 file-configuration),可在 DNS 挑战段声明 provider,并通过envFile指定 dotenv 路径:
challenges: hetzner-challenge: dns: provider: hetzner envFile: .env.hetzner certificates: example: domains: - example.com - '*.example.com'之后直接运行lego即可。
凭据缺失时的行为
从测试用例(hetzner_test.go)可以看到,若HETZNER_API_TOKEN与HETZNER_API_KEY均为空,NewDNSProvider()会返回错误hetzner: some credentials information are missing: HETZNER_API_TOKEN;而在NewDNSProviderConfig路径下则返回hetzner: credentials missing(见 hetzner.go)。因此排错时应优先检查 Token 是否已正确注入环境。
附加配置参数
除凭据外,Hetzner provider 还支持以下可调参数(均通过环境变量设置,同样支持_FILE后缀):
| 环境变量 | 说明 | 默认值 |
|---|---|---|
HETZNER_HTTP_TIMEOUT | API 请求超时(秒) | 30 |
HETZNER_POLLING_INTERVAL | DNS 传播检查间隔(秒) | 2 |
HETZNER_PROPAGATION_TIMEOUT | 等待 DNS 传播的最大时长(秒) | 60 |
HETZNER_TTL | DNS 挑战 TXT 记录的 TTL(秒) | 120 |
这些默认值在源码中有明确落点:
HETZNER_HTTP_TIMEOUT(30s):见 hetzner.go,构造http.Client时读取。HETZNER_POLLING_INTERVAL(2s)与HETZNER_PROPAGATION_TIMEOUT(60s):直接对应 lego 全局常量dns01.DefaultPollingInterval与dns01.DefaultPropagationTimeout(见 dns_challenge.go)。HETZNER_TTL(120s):对应dns01.DefaultTTL(见 dns_challenge.go)。
配置示例:
HETZNER_API_TOKEN="xxxxxxxxxxxxxxxxxxxxx" \ HETZNER_TTL=60 \ HETZNER_PROPAGATION_TIMEOUT=120 \ HETZNER_POLLING_INTERVAL=2 \ HETZNER_HTTP_TIMEOUT=30 \ lego run --dns hetzner -d example.com注意 TTL 的下限约束:在 legacy(HETZNER_API_KEY)实现中,TTL 被硬性要求不小于 60 秒,否则NewDNSProviderConfig直接返回错误invalid TTL, TTL (N) must be greater than 60(见 internal/legacy/hetzner.go)。因此当你想调低 TTL 加速传播时,需留意 legacy 路径会拒绝小于 60 的值。
源码级实现解析
双 API 的自动选择逻辑
统一入口NewDNSProvider()根据环境变量决定走哪套实现(hetzner.go):
- 检测到
HETZNER_API_TOKEN→ 使用hetznerv1(Hetzner Cloud API); - 否则检测到
HETZNER_API_KEY→ 使用legacy(旧 Hetzner DNS API),并打印警告APIKey (legacy Hetzner DNS API) is deprecated, please use APIToken (Hetzner Cloud API) instead.; - 两者都未设置 → 尝试创建
hetznerv1provider,最终因缺少凭据而失败。
如果同时设置了 Token 与 Key,Token 优先(见测试用例 "success (both)",hetzner_test.go)。因此新用户应统一使用HETZNER_API_TOKEN,HETZNER_API_KEY仅用于兼容旧脚本。
v1:基于 Cloud API 的 RRSet 操作
hetznerv1实现(hetznerv1.go)的挑战流程如下:
- 定位授权区:
dns01.DefaultClient().FindZoneByFqdn()找到域名所属 zone;随后用dns01.ExtractSubDomain()拆出子域,并用idna.ToASCII处理国际化域名(IDN)。 - 添加记录:调用
AddRRSetRecords,通过POST /zones/{zone}/rrsets/{name}/TXT/actions/add_records在现有 RRSet 上追加挑战记录(internal/client.go)。TXT 记录值会先经strconv.Quote包装,符合 TXT 记录的引号规范。 - 等待 action 完成:Hetzner Cloud API 的 RRSet 修改是异步的,返回一个
Action;waitAction以HETZNER_POLLING_INTERVAL为周期轮询GET /actions/{id},直到状态变为success;若为error或running持续超过HETZNER_PROPAGATION_TIMEOUT则返回错误(hetznerv1.go)。轮询采用指数退避(backoff)库实现。 - 验证后清理:
CleanUp调用RemoveRRSetRecords(POST .../actions/remove_records)删除相同记录,同样等待 action 完成。
请求鉴权通过 OAuth2 静态 Token(Bearer)注入(internal/client.go),请求/响应的 JSON 编解码与错误解析都在该 client 中完成,错误信息会带上 Hetzner API 返回的code、message与字段级详情。
legacy:基于旧 DNS API 的记录操作
legacy实现(internal/legacy/hetzner.go)的流程更直接:
- 通过
GetZoneID在GET /api/v1/zones?name=...中按域名找到 zone ID; CreateRecord直接POST /api/v1/records创建 TXT 记录;CleanUp先GetTxtRecord按名称与值匹配记录,再DeleteRecord删除(DELETE /api/v1/records/{id})。
鉴权方式是把 API Key 放在自定义请求头Auth-API-Token中(internal/client.go)。由于该 API 已废弃,建议尽快迁移到HETZNER_API_TOKEN。
排错与提示
- DNS 传播检查:lego 在添加记录后等待
HETZNER_PROPAGATION_TIMEOUT(默认 60s),若你的 DNS 服务器刷新较慢可适当调大该值与HETZNER_POLLING_INTERVAL的比值。 - zone 定位失败:报错
could not find zone for domain时,先确认该域名确实托管在 Hetzner DNS 且 Token 有对应 zone 的权限(见 hetznerv1.go)。 - 多 SOA 环境:当 zone 同时存在内网与公网解析(多个权威服务器)时,可用
--dns.resolvers指定外部权威解析器,例如lego run --dns hetzner --dns.resolvers 9.9.9.9:53 -d example.com,避免传播检测命中内网记录,详见 DNS-01 挑战指南 与 tips。 - 请求超时:
HETZNER_HTTP_TIMEOUT只控制单次 HTTP 请求超时;传播等待总时长由HETZNER_PROPAGATION_TIMEOUT控制,两者职责不同。 - 调试:lego 默认会在出错时打印 HTTP 请求/响应摘要(client 层通过
clientdebug.Wrap包装),可结合 log 的调试级别观察实际 API 交互。
参考文档
- Hetzner provider 自动生成文档(本文依据)
- DNS Providers 总览与环境变量约定
- DNS-01 挑战使用指南
- Provider 入口实现
- v1 实现与 RRSet 操作
- legacy 实现
- Provider 选择逻辑测试
- 配置模板 hetzner.toml
- 网络安全
- 密码学
【免费下载链接】lego
Let's Encrypt/ACME client and library written in Go
相关推荐
lego 使用 Epik DNS Provider 签发证书:配置、参数与源码解析
lego 使用 Epik DNS Provider 签发证书:配置、参数与源码解析 导读 本文聚焦 lego(Let's Encrypt/ACME client
网络安全密码学lego 使用 Bluecat v2 DNS Provider 签发证书:配置、原理与源码级解析
lego 使用 Bluecat v2 DNS Provider 签发证书:配置、原理与源码级解析 本篇指南聚焦 lego(Let's Encrypt/ACME
网络安全密码学Mordecai API完全指南:10个高级用法提升地理数据处理效率
Mordecai API完全指南:10个高级用法提升地理数据处理效率 Mordecai是一个强大的Python地理解析库,专门用于从英文文本中提取地名并将其解析
网络安全密码学
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考