用户登录
个人主页 用户中心 我的订单 添加授权 管理授权
退出登录
用户登录 用户注册
欢迎来到 UC建站系统

acme.sh加Let's Encrypt一条命令给100个域名自动申请通配符证书并部署到Nginx到期前自动续签,全程零人工介入

acme.sh + Let's Encrypt一条命令就能给100个域名自动申请通配符证书、自动部署到Nginx、到期前自动续签,全程零人工介入,而手动一个个登录宝塔面板点按钮、上传证书、配置路径、重启服务,100个域名折腾一整天还不保证没有漏掉的

批量部署SSL证书的四个核心问题

· 证书从哪来?——免费(Let's Encrypt / ZeroSSL / Google Trust Services)还是付费(DigiCert / Sectigo)

· 怎么批量申请?——一个域名一张证书,还是一张通配符证书覆盖所有子域名

· 怎么自动部署到服务器?——acme.sh、cert-manager、宝塔脚本、Ansible,选哪个取决于你的基础设施

· 怎么保证到期前自动续签?——crontab定时任务 + 续签钩子自动重启服务

1 - acme.sh加Let's Encrypt一条命令给100个域名自动申请通配符证书并部署到Nginx到期前自动续签,全程零人工介入 - UC建站系统

一、证书选型:免费和付费的真正差距不在加密,在信任等级和有效期

从加密强度看,Let's Encrypt的免费证书和DigiCert几千块一年的付费证书用的是同一套TLS协议,加密效果没有区别。真正的差异在三个维度:

对比维度免费证书(Let's Encrypt)付费证书(DigiCert / Sectigo)
有效期90天,必须自动化续签1年,到期手动续费
验证级别仅DV(域名验证),不显示企业名DV / OV(组织验证)/ EV(扩展验证),地址栏显示公司名
通配符支持支持 *.example.com(需DNS验证)支持,OV/EV通配符价格更高
多域名一张证书最多100个域名基础版3-5个,多域名SAN证书按域名数加钱
赔付保障$10,000-$1,750,000
年费¥0DV ¥200-800/年,OV ¥1500-5000/年,EV ¥3000-10000+/年

对于站群场景来说,Let's Encrypt免费证书基本是唯一合理的选择。100个域名如果全用付费证书,年费轻松过万,而用acme.sh + Let's Encrypt自动化的成本是零。付费证书的赔付保障和OV/EV验证在电商、金融、政务场景有意义,在内容站和工具站场景下没有实际价值。

一个容易被忽略的细节:Let's Encrypt的DV证书在浏览器地址栏显示的锁图标和付费DV证书完全一样,用户根本看不出来区别。只有EV证书才会在地址栏显示公司名称(绿色条),但这个特性在Chrome和Safari的最新版本中已经被弱化到几乎看不见了。

二、acme.sh:一条命令接管所有域名的证书生命周期

acme.sh是目前最成熟的ACME协议客户端,纯Shell脚本实现,无额外依赖,支持超过100家DNS服务商的API自动验证。它的核心价值是把"申请证书→部署到Web服务器→到期前自动续签→续签后自动重启服务"这整条链路全部自动化。

第一步:安装acme.sh

# 在线安装(服务器能访问GitHub)
curl https://get.acme.sh | sh

# 国内服务器用Gitee源
git clone https://gitee.com/neilpang/acme.sh.git
cd acme.sh && ./acme.sh --install

# 设置别名
alias acme.sh=~/.acme.sh/acme.sh

安装完成后acme.sh会自动添加crontab定时任务,每天检查证书到期情况。不需要额外配置,开箱即用。

第二步:配置DNS API密钥

通配符证书(*.example.com)只能用DNS验证方式,不能HTTP验证。所以需要先在DNS服务商后台获取API密钥,配置到acme.sh里:

# 腾讯云DNSPod
export Tencent_SecretId="你的SecretId"
export Tencent_SecretKey="你的SecretKey"

# 阿里云DNS
export Ali_Key="你的AccessKey"
export Ali_Secret="你的AccessKey Secret"

# Cloudflare
export CF_Token="你的API Token"

密钥写入 ~/.acme.sh/account.conf 持久化保存,之后不用每次export。

第三步:批量申请——一张证书覆盖多个域名

acme.sh支持在一张证书里塞多个域名(SAN证书),也支持每个域名单独申请一张证书。两种策略的适用场景不同:

# 策略A:一张通配符证书覆盖一个域名下的所有子域名
acme.sh --issue --dns dns_tencent \
-d example.com \
-d *.example.com

# 策略B:一张证书覆盖多个不相关的域名(SAN证书,最多100个)
acme.sh --issue --dns dns_tencent \
-d site1.com -d *.site1.com \
-d site2.com -d *.site2.com \
-d site3.cn -d *.site3.cn

# 策略C:不同DNS服务商的域名混在一张证书里
acme.sh --issue \
--dns dns_tencent -d site1.com -d *.site1.com \
--dns dns_cf -d site2.com -d *.site2.com

# 策略D:每个域名单独一张证书(适合证书需要分发到不同服务器)
for domain in site1.com site2.com site3.com; do
acme.sh --issue --dns dns_tencent -d "$domain" -d "*.$domain"
done

对于站群来说,策略D(每个域名单独一张证书)最合理。虽然申请命令多了,但好处是:某个域名的证书出问题不会影响其他域名;续签时只续过期的;证书文件独立存储,方便分发到不同服务器。

2 - acme.sh加Let's Encrypt一条命令给100个域名自动申请通配符证书并部署到Nginx到期前自动续签,全程零人工介入 - UC建站系统

Let's Encrypt的速率限制:每域名每周最多申请5次证书,每个IP每小时最多10个注册账户。批量申请时注意控制频率,如果一次要申请超过50个域名,分批次跑,每批间隔10-15分钟。测试阶段用Let's Encrypt的staging环境(--server letsencrypt_test),不消耗正式配额。

第四步:自动部署到Nginx并重载服务

证书申请下来了,下一步是把证书文件放到Nginx能读到的位置,然后重载Nginx让它生效。acme.sh的 --install-cert 命令把这步也自动化了:

# 单个域名部署
acme.sh --install-cert -d example.com --ecc \
--cert-file /etc/nginx/ssl/example.com/cert.pem \
--key-file /etc/nginx/ssl/example.com/key.pem \
--fullchain-file /etc/nginx/ssl/example.com/fullchain.pem \
--reloadcmd "nginx -s reload"

--reloadcmd 是核心参数:证书部署完成后自动执行你指定的命令。不仅限于重载Nginx,还可以是重启Docker容器、同步证书到CDN、发送钉钉通知等任何操作。

批量部署的Shell脚本写法:

#!/bin/bash
# deploy-all-ssl.sh - 批量部署所有域名的SSL证书

DOMAINS=(
"site1.com"
"site2.com"
"site3.cn"
)

for domain in "${DOMAINS[@]}"; do
echo "正在处理: $domain"

CERT_DIR="/etc/nginx/ssl/$domain"
mkdir -p "$CERT_DIR"

acme.sh --install-cert -d "$domain" --ecc \
--cert-file "$CERT_DIR/cert.pem" \
--key-file "$CERT_DIR/key.pem" \
--fullchain-file "$CERT_DIR/fullchain.pem" \
--reloadcmd "nginx -s reload"

echo "$domain 部署完成"
done

这段脚本一次跑完,100个域名的证书全部部署到位,Nginx自动重载。整个过程不超过5分钟。

三、宝塔面板:用Shell脚本绕过图形界面的一次一个

宝塔面板的SSL管理在图形界面下只能一个一个站点点按钮操作。但它的计划任务功能支持执行Shell脚本,我们可以利用acme.sh + 宝塔的标准证书路径实现全自动批量部署。

宝塔的证书存储路径是固定的:/www/server/panel/vhost/cert/{域名}/。只要把acme.sh生成的证书文件复制到这个目录,宝塔就会自动识别。不需要登录面板手动上传。

完整的宝塔批量部署脚本:

#!/bin/bash
# bt-batch-ssl.sh - 宝塔面板多站点批量申请并部署SSL证书

DOMAIN_FILE="/root/domains.txt"
LOG_FILE="/var/log/batch_ssl.log"

# 宝塔标准证书路径
BT_CERT_BASE="/www/server/panel/vhost/cert"

while IFS= read -r domain; do
[[ -z "$domain" || "$domain" == \#* ]] && continue

echo "[$(date +%Y-%m-%d\ %H:%M:%S)] 处理: $domain" >> "$LOG_FILE"

# 申请证书(HTTP验证,需80端口开放)
~/.acme.sh/acme.sh --issue -d "$domain" \
-w /www/wwwroot/"$domain" --force >> "$LOG_FILE" 2>&1

if [ $? -eq 0 ]; then
# 部署到宝塔标准路径
mkdir -p "$BT_CERT_BASE/$domain"
~/.acme.sh/acme.sh --install-cert -d "$domain" \
--key-file "$BT_CERT_BASE/$domain/privkey.pem" \
--fullchain-file "$BT_CERT_BASE/$domain/fullchain.pem"
echo "[OK] $domain" >> "$LOG_FILE"
else
echo "[FAIL] $domain" >> "$LOG_FILE"
fi
done < "$DOMAIN_FILE"

# 统一重载Nginx
/etc/init.d/nginx reload
echo "全部处理完成,Nginx已重载" >> "$LOG_FILE"

把这段脚本保存到 /root/bt-batch-ssl.sh,在宝塔面板 → 计划任务中添加一条Shell脚本任务,每月执行一次。日志输出到 /var/log/batch_ssl.log,出问题随时排查。

3 - acme.sh加Let's Encrypt一条命令给100个域名自动申请通配符证书并部署到Nginx到期前自动续签,全程零人工介入 - UC建站系统

注意事项:脚本假设站点目录是 /www/wwwroot/{域名},如果实际路径不同需要修改 -w 参数。另外HTTP验证方式需要服务器80端口开放,如果用DNS验证方式(推荐,不依赖端口),把 --issue 那一行改成 --dns dns_tencent 即可。

四、cert-manager:Kubernetes集群的证书全自动方案

如果你用的是Kubernetes,cert-manager是事实上的标准方案。它通过CRD(Custom Resource Definition)把证书管理变成了Kubernetes的原生资源,申请、部署、续签全部自动化,不需要写任何Shell脚本。

cert-manager的核心工作流:创建Issuer/ClusterIssuer(指定用哪个CA、哪种验证方式) → 创建Certificate资源(指定哪些域名需要证书) → cert-manager自动调用ACME协议申请证书 → 证书存入Kubernetes Secret → Ingress自动引用Secret中的证书 → 到期前自动续签。

快速上手:

# 安装cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml

# 创建ClusterIssuer(使用Let's Encrypt + DNS01验证)
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your@email.com
privateKeySecretRef:
name: letsencrypt-account-key
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-token
key: api-token
EOF

# 创建Certificate资源(一张证书覆盖多个域名)
cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: all-sites-tls
namespace: default
spec:
secretName: all-sites-tls-secret
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- site1.com
- *.site1.com
- site2.com
- *.site2.com
duration: 2160h # 90天
renewBefore: 360h # 提前15天续期
EOF

创建完Certificate资源之后,cert-manager会自动处理后续所有事情。在Ingress里只需要引用 secretName: all-sites-tls-secret,HTTPS就通了。证书过期前15天自动续签,不需要任何人工介入。

cert-manager的运维命令速查:

# 查看所有证书状态
kubectl get certificate -A

# 查看证书过期时间
kubectl get secret all-sites-tls-secret -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates

# 手动触发续期
cmctl renew all-sites-tls -n default

# 排查申请失败(Challenge → Order → CertificateRequest链路)
kubectl get challenge,order,certificaterequest -n default

五、多服务器证书分发:Ansible + acme.sh 批量推送到所有机器

如果站群分布在多台服务器上,证书需要同步分发到每一台。方案是在一台"证书管理机"上用acme.sh统一申请所有证书,然后通过Ansible或rsync推送到各台Web服务器。

Ansible playbook示例(证书管理机 → 所有Web服务器):

# sync-ssl.yml
- hosts: web_servers
tasks:
- name: 同步证书目录
synchronize:
src: /etc/nginx/ssl/
dest: /etc/nginx/ssl/
delete: no

- name: 重载Nginx
shell: nginx -s reload

更简单的方案:证书管理机和Web服务器共享同一个NFS存储,acme.sh直接把证书输出到NFS挂载目录,所有Web服务器自动读取最新证书。但NFS方案有单点故障风险,生产环境建议Ansible分发。

六、六种场景的批量SSL方案速查

你的情况推荐方案关键命令/文件
单台Nginx服务器,10-100个域名acme.sh + DNS API + Shell批量脚本acme.sh --issue --dns dns_tencent + for循环install-cert
宝塔面板,多个站点acme.sh + 宝塔计划任务Shell脚本输出到 /www/server/panel/vhost/cert/{域名}/
Kubernetes集群cert-manager + ClusterIssuerkubectl apply -f cert-manager.yaml + Certificate CRD
多台服务器,统一管理管理机acme.sh申请 + Ansible分发synchronize模块 + nginx -s reload
用了CDN(Cloudflare等)acme.sh申请 + CDN API自动上传证书--reloadcmd里调用CDN API上传证书
只有几个域名,偶尔手动操作宝塔面板/1Panel图形界面一键申请点按钮,不需要命令行

批量部署SSL证书这件事,核心不在"能不能做"——acme.sh、cert-manager、各种脚本都能做——而在"能不能保证不出遗漏"。100个域名里漏掉1个没续签,90天后那个站的用户就会看到红色警告页。自动化方案的真正价值不是省时间,是消除遗忘和遗漏这种人为错误。证书管理这件事,靠人记住三个月后续签是不现实的,靠脚本自动检查才是正道。

相关推荐
在线客服
👇找客服拿折扣
QQ咨询&售后
在线时间
11:00 ~ 5:30
QQ:3155555535
👇联系QQ
👇联系WX
首页 程序 帮助 登录