上个月有个站点的证书过期了,浏览器直接红屏,一天掉了三百多个独立 IP。

宝塔面板上明明写着"自动续签已开启",绿色的。

我去翻日志才发现,续签任务已经连续失败四十多天,中间没有任何提醒。

这篇把排查过程完整写一遍,遇到同样问题的可以直接照着走。

先确认是不是真过期

浏览器报证书错误不一定可信,有时候是本地系统时间不对。直接连服务器看实际证书:

echo | openssl s_client -servername www.example.com -connect www.example.com:443 2>/dev/null | openssl x509 -noout -dates

会输出两行,notBefore 和 notAfter。notAfter 是过期时间,如果已经过去了,那就是真过期,不是浏览器抽风。

再看续签日志

宝塔的证书续签日志在 /www/server/panel/logs/ 目录下,文件名里带 letsencrypt 或者 ssl。

ls -lt /www/server/panel/logs/ | head

找到最新的那个,直接看末尾:

tail -n 100 /www/server/panel/logs/letsencrypt.log

我那次日志里反复出现这么一段:

Type: unauthorized
Detail: Invalid response from
http://www.example.com/.well-known/acme-challenge/Xk3m...

意思是 Let's Encrypt 的验证服务器过来取验证文件,没取到。

四个常见原因

第一,80 端口不通。

这是最常见的。宝塔默认用文件验证,验证服务器必须能从公网访问 http://域名/.well-known/acme-challenge/ 这个路径。

如果之前为了强制 HTTPS,在 Nginx 里把 80 端口全量 301 到 443,验证请求会被跳走,验证就失败。

正确的做法是放行这个路径:

location ^~ /.well-known/acme-challenge/ {
    root /www/wwwroot/你的站点目录;
    try_files $uri =404;
}

location / {
    return 301 https://$host$request_uri;
}

第二,CDN 或者云防火墙挡住了。

我那次就是。站点前面套了一层 CDN,CDN 的回源只放行 443,80 端口被拦在外面。Let's Encrypt 从公网访问 80 打不到源站,自然失败。

解决办法是在 CDN 后台把 80 端口也回源,或者改用 DNS 验证。

第三,面板升级后计划任务丢了。

宝塔升级大版本的时候,偶尔会把 ssl 相关的计划任务清掉。去面板的"计划任务"里看一眼,有没有一条叫"续签 Let's Encrypt 证书"的,没有就手动加一条。

第四,泛域名证书需要 DNS 接口。

*.example.com 这种证书没法用文件验证,必须用 DNS 验证,而且要在面板里配置 DNS 服务商的 API 密钥。没配就是必然失败。

我最后怎么解决的

文件验证这条路太依赖 80 端口,我干脆全改成 DNS 验证。

面板里:网站 → 设置 → SSL → Let's Encrypt → 验证方式选 DNS,然后填 DNS 服务商的 API 密钥。腾讯云、阿里云、Cloudflare 宝塔都内置了。

改完手动点一次续签,成功后就不用管了。DNS 验证不依赖任何端口,CDN 开不开都行。

从去年改到现在,一年多,没再出过问题。

两件要提前做的事

一、加证书到期监控。

面板不会主动通知你。可以用在线监控服务,或者最土的——在日历里设个提醒,每 60 天看一次。

我现在用的是一个 uptime 监控,把 HTTPS 证书剩余天数当指标,少于 15 天发邮件。

二、别把 80 端口全封。

很多人为了"安全"直接把 80 关了,只留 443。这会让所有文件验证类的证书申请全部失效,包括以后换新域名的时候。

证书过期这种事,出一次就够难受了。花二十分钟改成 DNS 验证,比每次出事再抢救划算。

俗人源码网免责声明:

1、本站所有资源均收集于互联网,分享目的仅限学习与参考。如有侵权,请联系 1685698671@qq.com 及时删除!

2、本站资源不保证完整性和安全性,下载后请自行检测。使用过程中出现的任何问题均与本站无关,敬请自行处理。

3、本站资源仅限个人学习研究使用,严禁用于任何违法违纪用途。因使用者违规使用产生的一切后果,由使用者自行承担,本站不承担任何责任。