# acme.sh + 阿里云 DNS / DNSPod 申请通配符证书（DNS-01）

> 80 端口被封、域名未备案也能签证书：用 acme.sh 调用阿里云 DNS 或腾讯云 DNSPod API 申请 Let's Encrypt 通配符证书，安装到 Nginx 并自动续期。

Source: https://ssl.sh/zh/guides/acme-sh-dnspod-aliyun-dns/
Last updated: 2026-11-10

域名解析在阿里云 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 时运行：

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

访问 GitHub 慢时，按官方 wiki 从 Gitee 安装：

```bash
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：

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

## 第二步：导出 DNS API 密钥

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

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

腾讯云 DNSPod：

```bash
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：

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

腾讯云 DNSPod：

```bash
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 证书配置文件](https://ssl.sh/zh/guides/lets-encrypt-certificate-profiles/)。

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

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

```bash
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 里引用这两个文件：

```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 证书检查](https://ssl.sh/zh/tools/ssl-checker/) 检查主域名和子域名，或在终端运行：

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

本地查看：

```bash
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`。检查和手动触发：

```bash
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 监控](https://ssl.sh/zh/monitor/)（开发中）。

## 常见问题排查

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