ACME 客户端与自动化

acme.sh 用阿里云 DNS / DNSPod API 申请通配符证书

作者: · 最后核实

域名解析在阿里云 DNS 或腾讯云 DNSPod 时,acme.sh 用 dns_ali 或 dns_tencent 钩子调用 API 完成 DNS-01 验证,为 example.com 和 *.example.com 签发 Let's Encrypt 证书,再安装到 Nginx 并自动续期。整个过程不需要开放任何入站端口。

适用于 acme.sh 3.1.4 及以上的 Linux 服务器,包括宝塔、家用 NAS 和内网机器。

前提条件

DNS-01 验证只要求能通过 API 修改域名解析。

  • 域名解析托管在阿里云云解析 DNS 或腾讯云 DNSPod(NS 指向对应服务商)。
  • 一台能访问外网的 Linux 服务器,有 root 或能重载 Web 服务的用户。
  • 阿里云:在 RAM 访问控制 创建 RAM 用户,开启 OpenAPI 调用访问,授予 AliyunDNSFullAccess 权限,创建 AccessKey。
  • 腾讯云:在 访问管理(CAM) 创建子用户,授予 DNSPod 权限(如 QcloudDNSPodFullAccess,以控制台策略名为准),创建 SecretId/SecretKey。
  • 不要使用主账号密钥。

第一步:安装 acme.sh

acme.sh 用官方脚本安装,能顺畅访问 GitHub 时运行:

curl https://get.acme.sh | sh -s email=admin@example.com

访问 GitHub 慢时,按官方 wiki 从 Gitee 安装:

git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh
./acme.sh --install -m admin@example.com

安装后重新登录 Shell 或执行 source ~/.bashrc,然后把默认 CA 改为 Let's Encrypt:

acme.sh --set-default-ca --server letsencrypt

第二步:导出 DNS API 密钥

acme.sh 从环境变量读取密钥,阿里云和腾讯云的变量名不同。阿里云 DNS:

export Ali_Key="your-access-key-id"
export Ali_Secret="your-access-key-secret"

腾讯云 DNSPod:

export Tencent_SecretId="your-secret-id"
export Tencent_SecretKey="your-secret-key"

首次签发成功后,acme.sh 会把密钥保存到 ~/.acme.sh/account.conf,续期时自动读取。

第三步:签发通配符证书

按解析服务商选择钩子:阿里云 DNS 用 dns_ali,腾讯云 DNSPod 用 dns_tencent。阿里云 DNS:

acme.sh --issue --dns dns_ali -d example.com -d '*.example.com'

腾讯云 DNSPod:

acme.sh --issue --dns dns_tencent -d example.com -d '*.example.com'

acme.sh 自动添加 _acme-challenge TXT 记录,等待生效后完成验证并删除记录。国内 DNS 同步偶尔较慢,验证失败时加 --dnssleep 120 延长等待时间。想用 45 天证书加 --cert-profile tlsserver,见 Let's Encrypt 证书配置文件。

第四步:安装证书并设置重载命令

--install-cert 把证书复制到 Nginx 使用的固定路径,并记住续期后要执行的重载命令:

mkdir -p /etc/nginx/ssl
acme.sh --install-cert -d example.com --ecc \
  --key-file       /etc/nginx/ssl/example.com.key \
  --fullchain-file /etc/nginx/ssl/example.com.fullchain.pem \
  --reloadcmd      "systemctl reload nginx"

Nginx 里引用这两个文件:

ssl_certificate     /etc/nginx/ssl/example.com.fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/example.com.key;

宝塔用户可以把 --key-file 和 --fullchain-file 指向宝塔站点的证书目录,--reloadcmd 改成宝塔 Nginx 的重载命令(如 /etc/init.d/nginx reload,以实际安装为准),并关闭宝塔对该站点的自动续签。

验证

签发成功后,主域名和子域名都返回同一张 Let's Encrypt 证书。用 SSL 证书检查 检查主域名和子域名,或在终端运行:

curl ssl.sh/example.com
curl ssl.sh/www.example.com

本地查看:

acme.sh --list
openssl x509 -in /etc/nginx/ssl/example.com.fullchain.pem -noout -ext subjectAltName -enddate

自动续期

安装时创建的 cron 任务会定期运行 acme.sh --cron:3.1.4 起每 6 小时运行一次,默认按 Let's Encrypt 的 ARI 窗口续期(NO_ARI=1 可关闭),续期后自动执行安装步骤和 --reloadcmd。检查和手动触发:

crontab -l | grep acme.sh
acme.sh --cron --home ~/.acme.sh
acme.sh --upgrade --auto-upgrade

Let's Encrypt 默认证书 2027 年 2 月 10 日起改为 64 天、2028 年 2 月 16 日起改为 45 天,acme.sh 按 ARI 续期,不用改配置。RAM/CAM 子账号的密钥被禁用或删除后续期会失败,Let's Encrypt 也不再发到期提醒邮件,建议把域名加到 ssl.sh 监控(开发中)。

常见问题排查

  • InvalidAccessKeyId / Forbidden.RAM(阿里云):AccessKey 错误或 RAM 用户没有云解析权限,检查授权策略。
  • AuthFailure / UnauthorizedOperation(腾讯云):SecretId/SecretKey 错误或子用户没有 DNSPod 权限。
  • Verify error: no TXT record found:记录未同步到全部权威服务器,加 --dnssleep 120;或域名 NS 并不在你配置的服务商。
  • CAA 记录阻止签发:CAA 记录要允许 letsencrypt.org,见 CAA 记录阻止签发。
  • 触发频率限制:调试时反复签发,改用 --staging 测试,见 Let's Encrypt 频率限制。
  • 默认 CA 还是 ZeroSSL,提示要先注册邮箱:没执行第一步的 --set-default-ca --server letsencrypt。

常见问题

DNSPod 应该用 dns_tencent 还是 dns_dp?

推荐 dns_tencent,使用腾讯云 API 密钥(SecretId/SecretKey),权限可以通过 CAM 精细控制。dns_dp 使用 DNSPod 控制台里的 DNSPod Token(DP_Id、DP_Key),是较早的方式,老账号仍可使用。

域名的 DNS 服务商不支持 API 怎么办?

用 acme.sh 的 DNS 别名模式:在原域名添加一条 CNAME,把 _acme-challenge.example.com 指向一个托管在阿里云或 DNSPod 的验证专用域名,签发时加 --challenge-alias 验证域名。这样主域名的 DNS 不用开放 API。

签发后能自动部署到阿里云 CDN 吗?

能。acme.sh 有 ali_cdn 部署钩子,复用 Ali_Key/Ali_Secret,用 DEPLOY_ALI_CDN_DOMAIN 指定加速域名,每次续期后自动推送,见 阿里云 CDN 配置 HTTPS。

国内服务器访问 Let's Encrypt 慢或超时怎么办?

偶尔超时不影响使用,稍后重试即可。签发和续期只需短时间访问 Let's Encrypt API,cron 每 6 小时会自动重试。长期连不上时检查服务器的出站防火墙和 DNS 解析设置。

资料来源

  1. acme.sh wiki: How to use DNS API
  2. acme.sh wiki: dnsapi2(TencentCloud)
  3. acme.sh wiki: Install in China
  4. 阿里云云解析 DNS 帮助文档
  5. DNSPod 文档中心
  6. acme.sh releases