最近手头几个二级域名的业务准备上线,如果按照以前的做法,每个子域名都去单独申请一张单域名证书,不仅容易撞上 Let's Encrypt 的单周申请频次限额,维护起来也格外繁琐。索性花点时间在宝塔面板里配置通配符泛域名证书(*.example.com),并通过 DNS API 实现无人值守自动续期。
顺手把具体操作路径和排查踩坑记录下来,方便日后自己重装服务器时翻阅,也给有类似需求的朋友一个参考。
1. 为什么泛域名证书必须走 DNS 验证
申请单域名证书时,我们最常用的是文件验证(HTTP-01):Let's Encrypt 往站点根目录的 .well-known/acme-challenge/ 写入一个临时验证文件,公网访问成功即签发。
但泛域名证书(通配符证书,形如 *.yourdomain.com)机制不同,CA 机构无法通过单一站点的 HTTP 路径确认你对整个根域名的控制权,因此必须走 DNS 验证(DNS-01),即在域名的 DNS 解析里添加一条指定的 _acme-challenge TXT 记录。
这里有一个关键点:如果选择手动在域名控制台添加 TXT 记录,证书能正常签发,但90天后绝对无法自动续期,因为没有机器能替你手动去网页后台改记录。要实现自动续期,必须使用 DNS 服务商提供的 API 密钥。
2. 准备 DNS API 授权与申请步骤
在申请前,先在你的域名解析服务商后台获取相应的 API 凭证。建议按最小权限原则创建子账号或专有 Token,不要给全局管理员权限。
| DNS 服务商 | 所需配置参数 | 权限建议 |
|---|---|---|
| 阿里云 (Aliyun) | AccessKey ID, AccessKey Secret | 仅赋予 AliyunDNSFullAccess 策略 |
| 腾讯云 (DNSPod) | DP_Id, DP_Key | 建议使用 DNSPod 专有的 API Token |
| Cloudflare | API Token (优先) 或 Global API Key | 权限仅需 Zone - DNS - Edit |
获取到密钥后,进入宝塔面板操作:
- 打开【网站】-> 找到目标站点,点击【设置】-> 切换到【SSL】标签页。
- 选择【Let's Encrypt】选项卡,验证方式选择【DNS 接口】。
- 点击齿轮图标或下拉菜单配置对应服务商的 API 密钥。
- 在域名输入框中,务必同时填入根域名和通配符域名,一行一个:
如果只写textexample.com *.example.com
*.example.com,访问根域名 https://example.com 时浏览器会报证书名称不匹配(Name Mismatch)错误,这一步很容易漏掉。
- 点击【申请】,后台会调用 acme.sh 脚本自动添加 TXT 记录,等待 1 到 2 分钟左右即可完成签发并自动部署。
3. 验证自动续期与定时任务机制
证书签发完成后,宝塔面板会在系统的 crontab 里写入自动续期脚本。可以在【计划任务】中看到一条名为 [Let's Encrypt 续签证书] 的定时任务。
该任务默认每天凌晨执行一次检测,但并不意味着每天都会重新签发证书。acme.sh 脚本只有在检测到证书有效剩余时间少于 30 天时,才会真正触发 DNS API 写入并请求新证书。
如果想确认续期链路是否通畅,不要干等两个月。可以直接在【计划任务】中找到该条目,点击右侧的【执行】,然后查看任务日志:
- 如果日志显示跳过未到期的域名(Skip),说明逻辑执行正常;
- 如果日志提示 API 连接超时、权限校验失败或找不到 Zone ID,就要立即检查上一步保存的 API 密钥是否有效。
4. 几个容易踩坑的常见问题
- Cloudflare 解析代理问题:开启了 Cloudflare 代理(小黄云)的域名,验证 DNS-01 并不会受到 CDN 阻断,因为验证请求直接查询的是 TXT 记录。但如果使用 API Token 验证,Cloudflare 的 Token 权限必须选对具体的域名 Zone,否则会报
403 Forbidden。 - TTL 缓存导致的验证超时:部分国内域名服务商的默认 TXT 记录 TTL 时间较长。当 acme.sh 刚写入记录去向公共 DNS 查询时,可能因为缓存未更新导致校验失败。遇到这种情况,在 DNS 后台将域名的默认 TTL 改为 1 分钟或最小值重试即可。
- 多台独立服务器共用证书:泛域名证书签发在当前服务器后,只能保护本机上的 Nginx/Apache。如果你有其他云服务器部署了不同的子系统,可以手动从当前站点的证书目录(
/www/server/panel/vhost/cert/)导出证书公私钥,或通过脚本分发至对应节点。