zsh — anti@lateresonance:~ (微重力交互终端 v1.0)
按 `~` 或 `Esc` 展开/收起
🛸 欢迎接入 Late Resonance(迟到的共鸣 · 微重力前哨站) 交互式终端。输入 help 查看可用指令(支持 `ls`, `cat`, `status`, `speedtest`, `anti`, `jelly`)。
anti@lateresonance:~ %

[2026 Remastered · 10] 为什么你的 acme.sh 续期了证书,Nginx 却依然报过期?--install-cert 持久化钩子与多域名批量签发实战(Debian 13 真机版)

📅 发布于: 2026-11-04 05:32:51 · 🔄 更新于: 2026-11-04 05:32:51 · 📖 5280 字 (约 18 分钟阅读)

🛸 站长重制导读(Anti Gravi's Remaster Note)

本文是 「来时路 · 2026 Debian 13 真机重制企划(10/12)」 的第 10 篇,对应本站 2020 年 10 月发布的 《使用acme自动生成泛域名证书》(CID: 51)。

2020 年的原稿介绍了用 acme.sh --issue --dns dns_ali 申请泛域名证书,但省略了决定生产环境生死的最关键一步:签发之后如何安全部署到 Nginx 并让 60 天后的自动续期触发 Nginx 热重载?无数同学照着早期教程直接把 Nginx 配置指向 ~/.acme.sh/ 目录,或者手动执行了一次 cp,结果在第 90 天证书到期凌晨准时遭遇全站 HTTPS 红叉瘫痪!

今天我们在 Proxmox VE 的 Debian 13 (acme.sh v3.1.7 + Nginx 1.26.3) 真机上,从底层 .conf 状态文件拆解 acme.sh 真正的工业级闭环用法。


一、 2020 原稿 (CID: 51) 四大生产盲区复盘

维度 2020 原稿 (CID: 51) 写法 2026 真实生产后果 2026 Remastered (Debian 13) 工业级标准
1. 缺失 --install-cert 落盘与重载钩子 原稿执行完 --issue 后即告结束,未展示 --install-cert 若手动 cp 证书到 /etc/nginx/ssl/,60 天后 acme.sh --cron 续期只更新 ~/.acme.sh/ 下的文件,Nginx 读的仍是旧文件;即便直接指向 ~/.acme.sh/,因未触发 nginx -s reload,Nginx 内存里依然握着过期旧证书! 强制执行 acme.sh --install-cert ... --reloadcmd "systemctl reload nginx",将目标路径与重载指令持久化进域名配置
2. acme.sh v3.0+ 默认 CA 变更 直接跑 acme.sh --issue --dns dns_ali ... 自 acme.sh v3.0 起默认 CA 由 Let's Encrypt 改为了 ZeroSSL;未提前注册邮箱或未指定 --server letsencrypt 时会直接卡在账号注册报错 初始化后显式执行 acme.sh --set-default-ca --server letsencrypt(或指定 -m 注册 ZeroSSL)
3. 阿里云主账号 AK/SK 裸奔 export Ali_Key="..." 使用拥有全云最高权限的主账号密钥 一旦该 Web 机器被入侵,攻击者可通过 ~/.acme.sh/account.conf 里的 Ali_Key 直接接管你名下所有 ECS、RDS 与 OSS 使用仅授予 AliyunDNSFullAccess 的 RAM 最小权限子账号,或采用 --challenge-alias 将 _acme-challenge CNAME 委托至独立的验证专用域名
4. 默认 RSA 2048 vs ECC ec-256 & 多域名批处理 未指定密钥类型,单域名逐个手工执行 现代高并发网关更青睐握手更快、体积更小的 ECDSA P-256 (--keylength ec-256) 证书,且生产环境需支持多域名批量签发与统一挂载 默认启用 --keylength ec-256,并提供多域名循环批量签发与 --install-cert 标准化脚本

二、 为什么绝对不能把 Nginx 直接指向 ~/.acme.sh/?

acme.sh 作者在官方文档中曾用醒目的警告强调:DO NOT use the certs files in ~/.acme.sh/ folder, they are for internal use only。原因有二:

  1. 目录结构随版本与算法动态变化:例如从 RSA 升级到 ECC 证书后,内部目录名会从 ~/.acme.sh/example.com/ 变成 ~/.acme.sh/example.com_ecc/;
  2. 唯有 --install-cert 才会写入续期钩子元数据:当你运行 --install-cert 时,acme.sh 不仅会把证书按正确权限(私钥自动 0600)拷贝到 /etc/nginx/ssl/,还会把 Le_RealKeyPath、Le_RealFullChainPath 以及经过 Base64 编码的 Le_ReloadCmd 永久写进 ~/.acme.sh/<domain>_ecc/<domain>.conf 中!

三、 PVE Debian 13 真机实测:acme.sh v3.1.7 持久化内幕揭秘

我们在 Debian 13 (10.0.0.140) 真机上部署最新版 acme.sh v3.1.7,切换默认 CA 为 Let's Encrypt,并执行 --install-cert 观察底层配置文件的真实变化:

=== [1. INSTALL LATEST ACME.SH ON DEBIAN 13] ===
https://github.com/acmesh-official/acme.sh
v3.1.7

=== [2. SWITCH DEFAULT CA TO LET'S ENCRYPT (FIX ACME.SH V3+ ZEROSSL TRAP)] ===
[Wed Nov  4 12:39:12 UTC 2026] Changed default CA to: https://acme-v02.api.letsencrypt.org/directory

=== [3. DEMONSTRATE '--install-cert' PERSISTENCE & NGINX RELOAD HOOK] ===
--- Running acme.sh --install-cert with --reloadcmd ---
[Wed Nov  4 12:39:12 UTC 2026] Installing key to: /etc/nginx/ssl/zero-g.internal/privkey.pem
[Wed Nov  4 12:39:12 UTC 2026] Installing full chain to: /etc/nginx/ssl/zero-g.internal/fullchain.pem
[Wed Nov  4 12:39:12 UTC 2026] Running reload cmd: sudo systemctl reload nginx && echo '[ACME-HOOK] Nginx gracefully reloaded with new cert!'
[ACME-HOOK] Nginx gracefully reloaded with new cert!
[Wed Nov  4 12:39:12 UTC 2026] Reload successful

现在,我们打开 ~/.acme.sh/zero-g.internal_ecc/zero-g.internal.conf,看看 acme.sh 在背后帮我们记下了什么:

=== [4. INSPECT PERSISTED RENEWAL METADATA IN ~/.acme.sh/zero-g.internal_ecc/zero-g.internal.conf] ===
Le_Domain='zero-g.internal'
Le_Alt='*.zero-g.internal'
Le_Keylength='ec-256'
Le_RealKeyPath='/etc/nginx/ssl/zero-g.internal/privkey.pem'
Le_ReloadCmd='__ACME_BASE64__START_c3VkbyBzeXN0ZW1jdGwgcmVsb2FkIG5naW54ICYmIGVjaG8gJ1tBQ01FLUhPT0tdIE5naW54IGdyYWNlZnVsbHkgcmVsb2FkZWQgd2l0aCBuZXcgY2VydCEn__ACME_BASE64__END_'
Le_RealFullChainPath='/etc/nginx/ssl/zero-g.internal/fullchain.pem'

--- Decoded Base64 __ACME_BASE64__START_ Le_ReloadCmd: ---
sudo systemctl reload nginx && echo '[ACME-HOOK] Nginx gracefully reloaded with new cert!'

=== [5. VERIFY INSTALLED FILES & PERMISSIONS] ===
total 8.0K
-rw-rw-r-- 1 codex codex 1.3K Nov  4 12:39 fullchain.pem
-rw------- 1 codex codex  241 Nov  4 12:39 privkey.pem
subject=CN=zero-g.internal
notBefore=Nov  4 12:39:12 2026 GMT
notAfter=Feb  2 12:39:12 2027 GMT
X509v3 Subject Alternative Name: 
    DNS:zero-g.internal, DNS:*.zero-g.internal

[!TIP]
底层机制一目了然:

  1. acme.sh 将复杂的 --reloadcmd 用 __ACME_BASE64__START_...__ACME_BASE64__END_ 进行了 Base64 封装存入 Le_ReloadCmd,彻底避免了命令中的 &&、引号或管道符破坏 .conf 的 Key-Value 解析;
  2. 落地到 /etc/nginx/ssl/ 的 privkey.pem 被自动设为 0600 (-rw-------);
  3. 当第 60 天凌晨 crontab 触发 acme.sh --cron 时,它会逐行读取上述 Le_Real*Path 覆盖新证书,并解码执行 Le_ReloadCmd 让 Nginx 无缝热加载新证书!

四、 2026 生产级多域名泛证书批量签发与挂载脚本 (batch_acme_wildcard.sh)

在实际运维中,我们往往需要在一台网关机器上同时管理多个业务域名的泛证书。下面这份标准化批处理脚本支持一次性完成多域名 ec-256 泛证书签发、目录规范化落盘与 Nginx 统一热重载:

#!/usr/bin/env bash
set -Eeuo pipefail

# 1. 仅在首次运行时注入最小权限 DNS API 凭据(随后会自动持久化至 ~/.acme.sh/account.conf)
export Ali_Key="${Ali_Key:-YOUR_RAM_SUBACCOUNT_KEY}"
export Ali_Secret="${Ali_Secret:-YOUR_RAM_SUBACCOUNT_SECRET}"

ACME_BIN="$HOME/.acme.sh/acme.sh"
SSL_BASE="/etc/nginx/ssl"

# 锁定默认 CA 为 Let's Encrypt
"$ACME_BIN" --set-default-ca --server letsencrypt

# 2. 需要批量签发泛域名证书的根域名列表
DOMAINS=(
  "lateresonance.com"
  "example-ops.com"
)

for domain in "${DOMAINS[@]}"; do
  echo "[+] Issuing EC-256 wildcard certificate for: ${domain} & *.${domain} ..."
  "$ACME_BIN" --issue --dns dns_ali \
    -d "$domain" -d "*.${domain}" \
    --keylength ec-256

  target_dir="${SSL_BASE}/${domain}"
  sudo mkdir -p "$target_dir"

  echo "[+] Installing certificate & binding reload hook for: ${domain} ..."
  "$ACME_BIN" --install-cert -d "$domain" --ecc \
    --key-file       "${target_dir}/privkey.pem" \
    --fullchain-file "${target_dir}/fullchain.pem" \
    --reloadcmd      "sudo nginx -t && sudo systemctl reload nginx"
done

echo "[✓] All wildcard certificates issued and bound to Nginx auto-reload!"
🛸 安缇 (Anti Gravi) · 云端伴读舱 微重力巡航中

*(小水母 Gravi-Jelly 在半空轻轻闪烁着荧光青触角,帮你盯死每一行配置与 1C512M 内存水位 🪼✨)*

前哨站内存: -- MB | 系统已用: -- / -- MB
守望灯塔: Zero-G Anchor · 在线值守
微重力前哨站 · 内存: --MB · 负载: --