首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Nginx 上的通配符证书 90 天到期,续签这事我是这么搞的

Nginx 上的通配符证书 90 天到期,续签这事我是这么搞的

原创
作者头像
外滩首席运维
发布2026-08-10 18:37:44
发布2026-08-10 18:37:44
1280
举报

用免费通配符证书有个绕不开的问题:90 天就过期。

我管着三个子域名,api.xxx.comadmin.xxx.comcdn.xxx.com,一开始每个域名各申请一张单域名证书,后来换了通配符证书,*.xxx.com 一张搞定。省事是省事了,但每隔三个月就得续签一次,忘了就全挂。

上个月就翻了一次车。周一早上收到用户反馈说网站打不开,我一看浏览器,NET::ERR_CERT_DATE_INVALID——证书两天前就过期了。三个子域名全红。

从那之后我把续签流程从头理了一遍,记录在这里。

先看当前证书什么时候到期

续签之前先确认一下现状。终端跑这条:

代码语言:bash
复制
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null \
  | openssl x509 -noout -dates

输出类似:

代码语言:plaintext
复制
notBefore=May  1 00:00:00 2026 GMT
notAfter=Jul 30 23:59:59 2026 GMT

notAfter 就是到期时间。管好几个域名的话,写个循环一次查完:

代码语言:bash
复制
for domain in api.xxx.com admin.xxx.com cdn.xxx.com; do
  end=$(echo | openssl s_client -servername "$domain" -connect "$domain":443 2>/dev/null \
    | openssl x509 -noout -enddate | cut -d= -f2)
  echo "$domain → $end"
done

续签:拿到新证书

免费通配符证书签发需要 DNS 验证——CA 要求你在域名 DNS 里加一条 TXT 记录,证明域名是你的。

如果你的证书管理平台支持对接 DNS 服务商(阿里云 DNS、Cloudflare 这类),这一步可以自动完成:提前配好 DNS 服务商的密钥,续签时平台自动加 TXT 记录、等验证通过、签发新证书。几分钟搞定。

手动的话,得自己去 DNS 控制台加记录、等生效、再回来点签发,来回十几分钟。域名一多很容易漏。

拿到新证书后,通常是两个文件:

  • fullchain.pem:你的证书 + 中间证书(CA 的信任链)
  • privkey.pem:私钥

有些地方给的是分开的三个文件(证书、中间证书、私钥),需要自己合并:

代码语言:bash
复制
cat your_cert.pem intermediate.pem > fullchain.pem

部署到 Nginx

拿到新的证书文件,替换 Nginx 配置里指向的路径。

我习惯用固定路径,这样每次续签只替换文件,不改 Nginx 配置:

代码语言:nginx
复制
server {
    listen 443 ssl;
    server_name *.xxx.com;

    ssl_certificate     /etc/nginx/ssl/xxx.com/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/xxx.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers on;

    # ...
}

替换完证书文件之后:

代码语言:bash
复制
# 先检查配置语法
nginx -t

# 没问题再 reload(不是 restart)
nginx -s reload

这里有个容易踩的坑:不要用 systemctl restart nginx。reload 就够了,restart 会断开所有现有连接。如果线上有 WebSocket 长连接,用户会直接感知到断连。reload 是平滑切换,旧的 worker 处理完手头请求再退出。

续签后验证

reload 之后,再跑一次 openssl 确认新证书生效:

代码语言:bash
复制
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null \
  | openssl x509 -noout -dates -subject

notAfter 是不是已经刷新到 90 天之后。

浏览器测试的话要注意,浏览器有 TLS session 缓存,可能看到的还是旧证书。换隐私窗口,或者用 curl 更靠谱:

代码语言:bash
复制
curl -vI https://example.com 2>&1 | grep -E "expire date|subject"

踩过的几个坑

只换了证书,没换中间证书

证书的信任链是"根证书 → 中间证书 → 你的证书"。如果你只替换了自己的证书,中间证书没更新,Chrome 可能正常(它会自动补链),但 Firefox、Safari 报错。

所以每次续签,fullchain.pem 要整个替换。别只换里面第一段。

证书文件权限

新证书文件权限别忘了设。Nginx worker 通常以 www-datanginx 用户运行,需要能读到证书:

代码语言:bash
复制
chmod 644 /etc/nginx/ssl/xxx.com/fullchain.pem
chmod 600 /etc/nginx/ssl/xxx.com/privkey.pem
chown root:root /etc/nginx/ssl/xxx.com/*.pem

私钥 600 就够,不要给太大。

改了文件但没 reload

听起来不可能,但我真干过。半夜续签完证书,nginx -t 也跑了,然后直接关了终端去睡觉。第二天用户反馈还是旧证书——因为忘了 nginx -s reload

多台机器只更新了一台

如果有多台 Nginx 做负载均衡,每台都得更新证书。漏了一台,用户会随机碰到新证书或旧证书,排查起来非常迷惑。

90 天一轮,靠脑子记不住

免费通配符证书 90 天到期,一年续签四次。靠自己记日子不现实。

最早我试过 crontab 跑脚本检查剩余天数,不到 14 天就发邮件提醒。原理可行,但出过几次状况:

  • 机器重装,crontab 没了,我也忘了重新加
  • 发邮件依赖本机 postfix,没配好的话邮件发不出去也不报错
  • DNS 偶尔抽风,openssl 连接超时,脚本静默退出

一个监控脚本自己都不可靠,它还能监控什么。

后来换了在线的证书监控。填个域名就行,到期前自动通过微信推提醒。这类服务不用自己运维,不存在"crontab 丢了"的问题。

另外,如果你同时用了阿里云 CDN,有些证书管理平台在续签完成后能把新证书自动同步到 CDN,不用再手动去阿里云控制台换。但 Nginx 服务器上的证书替换没法省,这一步还是得自己来。

整个流程说起来不复杂,真正麻烦的是"定时记得做"。把到期提醒设好,剩下的几条命令跑一遍,十分钟搞定。

我目前用 ssl.spug.cc 管通配符证书和到期提醒,够用。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 先看当前证书什么时候到期
  • 续签:拿到新证书
  • 部署到 Nginx
  • 续签后验证
  • 踩过的几个坑
  • 90 天一轮,靠脑子记不住
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档