AIGC标识 用 acme.sh 自动续签通配符证书并部署到 Nginx

背景

腾讯云免费 SSL 证书每 90 天需要手动申请一次,管理多个子域名证书非常繁琐。本文介绍如何使用 acme.sh + 阿里云 DNS API,在腾讯云服务器上实现通配符证书的全自动申请和续签,一张证书覆盖所有子域名,一次配置永久生效。

适用场景:

  • 域名在阿里云管理

  • 服务器在腾讯云(CentOS)

  • Web 服务器为 Nginx

  • 有多个子域名需要 HTTPS


原理

  • 通配符证书*.example.com 可覆盖所有子域名,无需每个域名单独申请

  • DNS-01 验证:通过阿里云 API 自动添加 TXT 记录完成域名所有权验证,无需开放 80 端口

  • acme.sh:开源 ACME 客户端,支持自动续签和 deploy hook

  • cron 自动化:安装时自动写入 cron,到期前 30 天自动续签并重新部署


准备工作

1. 阿里云 RAM 子账号 API 密钥

进入阿里云控制台 → 访问控制 RAM → 用户 → 创建用户,勾选"OpenAPI 调用访问",授予权限:

  • AliyunDNSFullAccess

记录生成的 AccessKey IDAccessKey Secret

建议使用子账号而非主账号,最小化权限范围。

2. 服务器安装 git

# CentOS 8 需要先换源(官方源已停止维护)
sed -i 's/mirrorlist.centos.org/mirrors.aliyun.com\/centos/g' /etc/yum.repos.d/*.repo
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://mirrors.aliyun.com|g' /etc/yum.repos.d/*.repo
yum clean all && yum makecache

yum install -y git

安装 acme.sh

使用 Gitee 镜像(国内服务器推荐):

git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh
./acme.sh --install -m your@email.com
source ~/.bashrc

安装完成后会自动写入 cron 任务,每天定时检查证书是否需要续签。


申请通配符证书

export Ali_Key="你的AccessKey_ID"
export Ali_Secret="你的AccessKey_Secret"

/root/.acme.sh/acme.sh --issue --dns dns_ali \
 -d example.com \
 -d *.example.com \
 --server zerossl \
 --dnssleep 60

参数说明:

  • --dns dns_ali:使用阿里云 DNS API 自动验证

  • --server zerossl:使用 ZeroSSL 作为 CA(对国内网络更友好)

  • --dnssleep 60:等待 60 秒让 DNS 记录生效后再验证

成功后证书保存在:/root/.acme.sh/example.com_ecc/


部署证书到 Nginx

将通配符证书复制到所有子域名对应的 Nginx 证书路径:

# 替换所有子域名的证书文件
for domain in example.com sub1.example.com sub2.example.com; do
 cp /root/.acme.sh/example.com_ecc/fullchain.cer /etc/nginx/${domain}_bundle.crt
 cp /root/.acme.sh/example.com_ecc/example.com.key /etc/nginx/${domain}.key
done

nginx -t && nginx -s reload

配置自动续签 Deploy Hook

每次 acme.sh 自动续签后,执行以下命令让 Nginx 加载新证书:

/root/.acme.sh/acme.sh --install-cert -d example.com \
 --reloadcmd "for domain in example.com sub1.example.com sub2.example.com; do \
  cp /root/.acme.sh/example.com_ecc/fullchain.cer /etc/nginx/\${domain}_bundle.crt; \
  cp /root/.acme.sh/example.com_ecc/example.com.key /etc/nginx/\${domain}.key; \
done && nginx -s reload"

配置完成后,后续续签全程无需人工介入。


Nginx 配置示例

每个子域名的 server 块保持原有配置不变,只需确保证书路径正确:

server {
   listen 443 ssl;
   server_name sub1.example.com;

   ssl_certificate     /etc/nginx/sub1.example.com_bundle.crt;
   ssl_certificate_key /etc/nginx/sub1.example.com.key;

   ssl_protocols TLSv1.2 TLSv1.3;
   ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
   ssl_prefer_server_ciphers on;

   location / {
       proxy_pass http://127.0.0.1:8080;
  }
}

验证证书

# 查看证书有效期
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates

# 确认 cron 已配置
crontab -l | grep acme

常见问题

服务器申请时报 DNSSEC 错误

.cn 域名可能存在 DNSSEC 残留配置,Let's Encrypt 的二次验证对此较严格。 解决方法:换用 ZeroSSL(--server zerossl),兼容性更好。

服务器网络无法连接 CA

部分 CA 节点在国内访问不稳定,加上 --dnssleep 60 参数延长 DNS 等待时间,或换用其他 CA:

# 测试服务器能否访问各 CA
curl -s --connect-timeout 10 https://acme.zerossl.com/v2/DV90 | grep newNonce
curl -s --connect-timeout 10 https://acme-v02.api.letsencrypt.org/directory | grep newNonce

续签失败排查

# 查看 acme.sh 日志
cat /root/.acme.sh/acme.sh.log

# 手动触发续签(调试)
/root/.acme.sh/acme.sh --renew -d example.com --server zerossl --dnssleep 60 --force --debug

# 确认阿里云 API 密钥未过期
# 登录阿里云 RAM 控制台检查 AccessKey 状态

总结

步骤操作
一次性配置 安装 acme.sh、申请证书、配置 deploy hook
日常维护 无需操作,cron 自动续签
出问题时 查日志、手动 renew、检查 API 密钥

配置完成后,原来需要每 90 天手动操作 8 次的工作变成了零维护。

posted @ 2026-08-31 17:22  峡谷风  阅读(18)  评论(0)    收藏  举报