使用 acme.sh 脚本如何实现 Let's Encrypt 泛域名证书自动续签?

文章导读
对于需要保护泛域名(如 *.example.com)的场景,最稳妥的方式是通过 DNS API 挑战模式签发证书。acme.sh 脚本会在安装时自动配置定时任务来完成后续续签,但需注意鉴权安全与命令规范。
📋 目录
  1. 安全提示与命令速用
  2. 原理简述
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 参考来源
A A

对于需要保护泛域名(如 *.example.com)的场景,最稳妥的方式是通过 DNS API 挑战模式签发证书。acme.sh 脚本会在安装时自动配置定时任务来完成后续续签,但需注意鉴权安全与命令规范。

先说结论:泛域名证书必须使用 DNS 验证,acme.sh 支持主流云厂商 API 自动完成验证和续签。

  • 适合:需要 *.domain.com 通配符保护的 Nginx、Apache 或后端服务。
  • 先准备:域名 DNS 解析托管在支持 API 修改的服务商处,并获取最小权限 API Token
  • 验收:检查系统定时任务是否存在,确保证书目录权限正确。

安全提示与命令速用

生产环境建议先下载脚本校验哈希后再执行,避免管道执行潜在风险。以下命令以 Cloudflare 为例,路径统一为 /etc/nginx/ssl/。

curl https://get.acme.sh | sh
source ~/.bashrc
# 配置 API Token(而非全局 Key)
export CF_Token="your_cloudflare_api_token"
# 签发证书(参数无反引号)
acme.sh `--issue` `--dns` dns_cf -d example.com -d *.example.com
# 安装证书
acme.sh `--install-cert` -d example.com \
`--key-file` /etc/nginx/ssl/key.pem \
`--fullchain-file` /etc/nginx/ssl/fullchain.pem \
`--reloadcmd` "systemctl reload nginx"

原理简述

Let's Encrypt 规定泛域名证书只能通过 DNS-01 挑战签发,不能通过 HTTP-01 验证。这意味着申请证书时,必须能自动修改域名的 TXT 记录。acme.sh 内置了多家 DNS 服务商的 API 接口,脚本通过调用 API 自动添加验证记录,签发完成后自动删除,从而实现无人值守。

关于续签,acme.sh 在安装后会自动注册一个 cron 定时任务,默认会在证书过期前一段时间自动检查并续签,无需手动干预。

使用 acme.sh 脚本如何实现 Let's Encrypt 泛域名证书自动续签?

分步处理

1. 安装脚本
使用官方安装命令,安装后会自动配置环境变量和定时任务。若担心管道执行风险,可前往 GitHub releases 下载源码校验后安装。

curl https://get.acme.sh | sh
source ~/.bashrc

2. 配置 DNS API Token
以 Cloudflare 为例,建议使用最小权限 Token 而非全局 API Key,降低泄露风险。

Token 创建步骤:

  1. 登录 Cloudflare 控制台,进入 My Profile -> API Tokens。
  2. 点击 Create Token,选择 Edit zone DNS 模板。
  3. 在 Zone Resources 中限定具体域名,避免权限过大。
  4. 复制 Token 并导出为环境变量。
export CF_Token="your_cloudflare_api_token"
# 注意:新版 acme.sh 推荐 CF_Token,旧版可能需 CF_Key/CF_Email

3. 签发证书
注意同时包含根域名和泛域名,否则部分客户端可能报警告。

acme.sh `--issue` `--dns` dns_cf -d example.com -d *.example.com

4. 安装证书
不要直接使用 acme.sh 内部目录的证书,使用 `--install-cert` 命令复制到业务目录,并配置重载命令。

使用 acme.sh 脚本如何实现 Let's Encrypt 泛域名证书自动续签?
acme.sh `--install-cert` -d example.com \
`--key-file` /etc/nginx/ssl/key.pem \
`--fullchain-file` /etc/nginx/ssl/fullchain.pem \
`--reloadcmd` "systemctl reload nginx"

怎么验证是否生效

1. 检查证书列表
查看已签发域名及过期时间。

acme.sh `--list`

2. 检查定时任务
确认 cron 任务已写入,这是自动续签的关键。

crontab -l

3. 模拟续签测试
使用 dry-run 参数测试续签逻辑是否正常,不会真正消耗配额。

acme.sh `--renew` `--dry-run` -d example.com

4. 查看证书有效期
通过 openssl 命令查看实际文件过期时间。

openssl x509 -in /etc/nginx/ssl/fullchain.pem -noout -dates

常见坑

  • DNS 传播延迟:某些 DNS 服务商 API 修改后生效慢,可能导致验证失败,可添加 `--dnssleep` 参数。
  • API 权限不足:确保 API Token 有修改 DNS 记录的权限,遵循最小权限原则。
  • cron 邮件骚扰:默认 cron 执行结果会发邮件,建议在 crontab 中重定向输出或配置 acme.sh 日志。
  • 升级脚本:定期运行 acme.sh `--upgrade` 更新脚本本身,以适配 CA 策略变更。
  • 路径不一致:确保安装证书时指定的路径与 Nginx 配置路径完全一致,注意权限问题。

参考来源

  • acme.sh 官方 Wiki - DNS API 列表:https://github.com/acmesh-official/acme.sh/wiki/dnsapi
  • Let's Encrypt 官方 FAQ - 泛域名证书:https://letsencrypt.org/faqs/#can-i-get-a-certificate-for-multiple-names-wildcard-certificates
  • acme.sh 官方 Wiki - 安装证书:https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E#%E5%AE%89%E8%A3%85%E8%AF%81%E4%B9%A6