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 解析设置。