自托管一旦上了"泛域名反代 + 一堆子服务",就会反复面对一个麻烦:给每个子域名单独申请证书,到期还得逐个续。更别扭的是,很多子服务(NAS、内网工具)没有 80 端口对外,用正统的 HTTP 校验根本过不去。ACME 通配符证书正是为此而生:一次签下发 *.example.com 覆盖所有子域名,再用 DNS 验证(而不是开 80 端口的 HTTP 验证)来做签发与续期。这篇讲清证书为什么、ACME 怎么签通配符、DNS 验证与 HTTP 验证的取舍、用 certbot / acme.sh 配云 DNS 自动续期,以及常见坑:权限、过期失联、自动续期没生效。
一、证书与 ACME 解决什么:把"可信加密"从手工变成自动
网站要加密,就得有一张"受信任的证书"(让大家不再看到"不安全"的惊心提示)。传统做法是向 CA 提交、人工验证、手工导入到每台服务器,到期再repeat。ACME(Automatic Certificate Management Environment)协议把这条链路自动化:你的服务器与 CA(比如 Let's Encrypt)通过约定接口对账,只需证明"你掌控这个域名的验证权",就能自动签发并定时续期。它解决的是"证书要一直有效"的运维负担——让加密从一次性手工配置变成持续自动运转。
当你有多个子服务且很多不出现在公网 80 端口时,通配符(wildcard)价值更明显:一张 *.example.com 覆盖 blog、nas、api 等任意子域,一次签发即达全站。而签发通配符只能走 DNS 验证——因为 CA 没法对"任意子域"做 HTTP 校验,只能让你证明"这根域名的 DNS 归你管"。这就是为什么 DNS 验证是通配符证书的必经之路。
二、DNS 验证 vs HTTP 验证:各自在什么场景用
两张验证方式对应两种"证明你是域名主人"的手段。HTTP-01:CA 让你在指定域名下放一个随机 token 文件,通过公网 80 访问到即通过;简单,但要求域名能对外开 80、且对每个域名独立签发。DNS-01:CA 让你在域名根下加一条指定的 TXT 记录,等它解析生效即通过;不依赖公网 80、能签发通配符,还一次覆盖所有子域。取舍很清晰:能开 80 的少量域名用 HTTP-01 最省事;大量子服务、内网服务、或需要泛域名的,果断用 DNS-01 + 通配符。
# DNS-01 的验证本质:CA 会让你添加一条 TXT 记录
# _acme-challenge.example.com TXT "一段随机验证串"
# 自动工具(certbot/acme.sh + 云 DNS API)会替你自动加、自动删,
# 你看到的效果就是"一个命令签出 *.example.com"。
# 以 certbot 为例(需先装对应云的 DNS 插件):
# certbot certonly --manual --preferred-challenges dns \
# -d '*.example.com' -d 'example.com' \
# --manual-auth-hook /usr/local/bin/dns_auth.sh \
# --manual-cleanup-hook /usr/local/bin/dns_cleanup.sh
选型的判断:能开放公网 80、子服务不多 → HTTP-01 + 单域名;有内网/多子服务/要泛域名 → DNS-01 + 通配符。多数把一堆服务塞在一台自托管机 + 一键反代的人,最终都会走向 DNS-01 通配符这条更省心的路。
三、用 acme.sh 配云 DNS 自动签发与续期
在实际自托管里,比 certbot 更"开箱即合"的是 acme.sh——它内置众多云厂商 DNS API 插件,一条命令就能完成"添加验证记录 → 签发 → 清理"全套,并把证书安装到 nginx/caddy 等目标位置。要点是"域名服务商在哪儿,就配置对应 API 密钥":阿里云、腾讯云、Cloudflare、DNSPod 等都支持。够配好后,后续续期完全自动,你甚至不用再管证书。
# 1) 安装 acme.sh
curl https://get.acme.sh | sh -s email=you@example.com
# 2) 以 Cloudflare 为例(DNS 由 Cloudflare 托管),先导出 API Token
export CF_Token="你的GlobalAPIKey或Token"
export CF_Account_ID="你的账户ID"
# 3) 用 DNS-01 签发通配符证书
acme.sh --issue -d '*.example.com' -d 'example.com' \
--dns dns_cf --server letsencrypt
# 4) 安装到 nginx(自动续期后会重新安装)
acme.sh --install-cert -d '*.example.com' \
--key-file /etc/nginx/ssl/example.key \
--fullchain-file /etc/nginx/ssl/example.crt \
--reloadcmd "systemctl reload nginx"
# 5) 通配符生效后,反代里就能统一引用这一张证书
# server { server_name blog.example.com; listen 443 ssl;
# ssl_certificate /etc/nginx/ssl/example.crt;
# ssl_certificate_key /etc/nginx/ssl/example.key; }
这里的关键是:"签发"和"安装到最终服务"是两回事。acme.sh 的 --install-cert 会把你签下的证书复制到目标路径并触发 reloadcmd(重载 nginx 让新证书生效)。续期是 acme.sh 的 cron 自动做的,它会重新执行 install-cert,等于"过期前自动换上新证书且服务已重载"——这才是真正的"一直有效、免手工"。
四、常见坑:权限、解析生效延迟、自动续期没生效
通配符 + 自动化虽省心,坑也不少。一是"权限与路径":acme.sh 目录、证书文件、以及 reloadcmd 里重载服务的权限要配好,否则续期后因权限写不进/重载失败,服务还是旧证书。二是"解析生效延迟":DNS-01 依赖新 TXT 记录在全球生效,有的 DNS 会滞后几十秒到几分钟,工具一般会自动等,但零宽限期(低于此时间续不上会过期)要留足余量。三是"自动续期没生效"最危险:cron 没跑、环境变量没导出、或域名托管搬到了别家导致验证记录没加对——定期"看一眼证书过期时间"比盲目相信"自动"更可靠。四是要把证书当资产纳管:续期脚本和服务重载命令纳入版本管理,证书文件只读、不落盘代号环境。
# 查看证书到期时间的可靠命令,自动化里常用来做"续期前检查"
openssl x509 -enddate -noout -in /etc/nginx/ssl/example.crt
# 或 watch 一下通过告警/cron 每日记录到期剩余天数,快到 14 天时告警
把这几条当排障 SOP:续期后先用 openssl 看新证书时间戳与域名是否对,再确认服务已重载新旧证书已生效,最后确认 cron 与 DNS 插件是否在续期时真正联网成功。自动化的前提是"到期时真有人/有第二道检查兜底",别把一个静默的 cron 当成免死金牌。
五、边界:证书自动化替你做"续期",不代表替你管好全站
证书只是 HTTPS 链路的一环。通配符证书好用,但也要认清边界:一张通配符爆了就覆盖所有子域,因此私钥保护级别要更高(权限最小化、不随便拷);特定合规场景(多级域名、不同信任域)可能要分开管;另外自动续期依赖"DNS 托管在受支持的服务商且密钥有效"——这个外部前提变了,自动化就断了。把证书纳入整个安全与运维体系:密钥权限、续期检查、失败告警、以及"个别子服务单独引别的证书"都要计划好。
回到自托管整体看,ACME 通配符 + 云 DNS 自动续期的价值,是把"全站 HTTPS 加密"这件本要反复手工续的杂事,固化成"一次配置、长期自动、失败可查"的闭环。落地要点:能开 80 且子服务少用 HTTP-01,大量子服务/内网/要泛域名用 DNS-01;acme.sh + 对应云 DNS 插件一条命令签发与自动续期并安装到反代;防住权限、解析延迟、续期没生效三坑并配到期检查。把这层自动化做好,你的自托管站点才能真正做到"一直打的开、一直加密、一直受信"。
结语
ACME 通配符证书是自托管"多子域名 + 内网服务"的加密解决法:用 DNS-01 验证一次签下发 *.example.com,再交给 acme.sh 配云 DNS 自动续期并安装到反代,就能让全站 HTTPS 长期自动有效。要点:根据能否开 80 选 HTTP-01 还是 DNS-01;把"签发"与"安装+重载"两步都用工具固化;用 openssl 定期查到期、配好权限与优先级,并接受"自动续期依赖 DNS 托管与密钥"这一外部边界。网格化下来,证书自动化替你挡掉的是重复手工续期的心烦,而把"什么证书放哪台机、私钥如何保护"的判断仍握在你手里——这正是不慌不忙长期养服务器的分水岭。




