
网站SSL证书过期后,浏览器通常会显示“连接不是私密连接”“证书已过期”或类似安全警告。用户可能无法正常访问网站,API客户端、支付回调、小程序接口和站点监控也可能因为TLS验证失败而中断。
遇到证书过期时,不要只在浏览器中临时忽略警告,也不要直接删除服务器上的证书目录。正确处理方式是先确认网站实际对外提供的是哪张证书,再检查域名解析、证书文件、续期工具和Web服务器配置,完成重新签发后安全加载新证书,并验证自动续期是否真正可用。
本文以Linux服务器、Nginx和Let’s Encrypt Certbot为主要示例,同时说明常见面板、CDN和负载均衡场景中的排查思路。
一、SSL证书过期会造成什么影响
SSL/TLS证书用于证明网站身份,并帮助客户端与服务器建立加密连接。证书包含有效期,超过截止时间后,浏览器和大多数客户端会拒绝信任它。
常见影响包括:
- 浏览器出现证书过期警告。
- 搜索引擎或监控工具无法正常抓取网站。
- HTTPS接口调用失败。
- App、小程序和桌面客户端无法连接API。
- Webhook、支付通知和第三方回调失败。
- 邮件、面板、对象存储或其他使用该证书的服务异常。
- CDN回源使用HTTPS时发生握手失败。
证书过期不会自动删除服务器中的网站文件和数据库,但会阻断或干扰依赖HTTPS的访问链路。因此,应优先恢复证书,而不是重装网站环境。
二、先确认真的是证书过期
浏览器显示HTTPS错误,不一定都是证书过期。域名不匹配、证书链不完整、服务器时间错误、SNI配置错误和CDN证书异常,也可能产生类似提示。
1. 使用OpenSSL检查线上证书
将 example.com 替换为实际域名:
`bash echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -subject -issuer -dates `
输出中重点查看:
subject:证书对应的主体。issuer:签发机构。notBefore:证书开始生效时间。notAfter:证书到期时间。
检查证书是否覆盖当前域名:
`bash echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -ext subjectAltName `
-servername参数很重要。多个HTTPS网站共用一个IP时,服务器通常根据SNI选择证书;不指定域名可能看到默认站点的证书,而不是目标网站的证书。
2. 检查本地证书文件
如果已经知道证书路径,可以直接查看:
`bash openssl x509 -in /path/to/fullchain.pem -noout -subject -issuer -dates `
还可以检查证书是否会在30天内到期:
`bash openssl x509 -in /path/to/fullchain.pem -noout -checkend 2592000 `
2592000代表30天的秒数。命令的退出状态可以用于监控脚本,但正式监控还应记录域名、证书路径和检查结果。
3. 对比线上证书与本地证书
有时Certbot已经生成新证书,但网站仍然对外提供旧证书。可以分别查看线上和本地证书的序列号:
`bash echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -serial `
`bash openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -serial `
如果序列号不同,通常表示Web服务器没有加载预期证书、配置指向了其他文件,或者HTTPS由CDN、负载均衡和反向代理中的另一层终止。
三、确认HTTPS证书实际部署在哪里
处理证书前,先画清楚访问链路。常见结构包括:
1. 浏览器直接连接Nginx或Apache
证书安装在网站服务器上。更新后需要让Web服务器重新加载配置。
2. 浏览器先连接CDN
用户看到的是CDN边缘节点提供的证书。即使源站证书正常,CDN上的证书过期仍会导致前端访问异常。
同时还要检查CDN回源方式:
- CDN使用HTTP回源:源站证书不参与回源连接。
- CDN使用HTTPS回源:源站证书或回源证书过期也可能导致CDN访问源站失败。
3. 浏览器连接负载均衡
证书可能安装在云负载均衡、应用网关或反向代理上,而不是后端云服务器。此时只更新服务器证书不会改变用户看到的证书。
4. 宝塔、1Panel或其他管理面板
面板可能负责申请、部署和续期证书,也可能只是把证书文件写入Nginx配置。需要确认续期任务由面板、Certbot还是其他ACME客户端负责,避免多个工具同时管理同一证书。
四、使用Certbot检查现有证书
如果证书由Certbot管理,可以先查看证书列表:
`bash sudo certbot certificates `
该命令通常会显示:
- 证书名称。
- 包含的域名。
- 到期时间。
- 证书文件路径。
- 私钥文件路径。
Certbot常用证书文件位于:
`text /etc/letsencrypt/live/证书名称/ `
目录中常见文件包括:
cert.pem:站点证书。chain.pem:中间证书链。fullchain.pem:站点证书与中间证书链。privkey.pem:私钥。
不要手动删除 /etc/letsencrypt/ 中的文件或修改其中的符号链接。错误操作可能破坏续期配置和历史证书关系。
五、先测试续期而不是直接反复申请
Certbot提供模拟续期测试:
`bash sudo certbot renew –dry-run `
--dry-run会使用测试环境检查续期流程,适合发现域名验证、端口、防火墙、插件和部署钩子问题。
如果测试成功,说明当前续期配置基本可用;如果失败,应根据错误信息定位原因,不要连续使用强制续期反复申请正式证书,以免触发证书机构的请求限制。
查看Certbot日志:
`bash sudo less /var/log/letsencrypt/letsencrypt.log `
查看最近的错误信息:
`bash sudo tail -n 100 /var/log/letsencrypt/letsencrypt.log `
六、重新签发或续期证书
具体命令取决于原来的验证方式和Web服务器。
1. Nginx插件
如果Certbot使用Nginx插件管理证书:
`bash sudo certbot –nginx -d example.com -d www.example.com `
Certbot可以完成域名验证,并在支持的配置中安装证书。执行前建议备份Nginx配置。
2. Webroot方式
网站正在运行,并且可以通过指定目录提供验证文件时,可以使用:
`bash sudo certbot certonly –webroot \ -w /var/www/example \ -d example.com \ -d www.example.com `
Webroot插件会在站点目录下的 .well-known/acme-challenge/ 中创建验证文件。Web服务器必须允许公网通过HTTP访问该路径。
3. Standalone方式
没有可用Web服务器插件时,可以使用Certbot自带的临时服务:
`bash sudo certbot certonly –standalone \ -d example.com \ -d www.example.com `
Standalone方式通常需要占用80端口。如果Nginx或Apache已经监听80端口,可能需要短暂停止服务:
`bash sudo systemctl stop nginx sudo certbot certonly –standalone -d example.com -d www.example.com sudo systemctl start nginx `
生产网站使用这种方式前,应评估停机影响。可以优先考虑Nginx插件、Webroot或DNS验证。
4. DNS验证与通配符证书
申请 *.example.com 形式的通配符证书,需要使用DNS-01验证。
手动方式示例:
`bash sudo certbot certonly –manual \ –preferred-challenges dns \ -d example.com \ -d ‘*.example.com’ `
手动DNS验证通常不能自动续期,除非配置了自动更新DNS记录的认证脚本。正式环境更适合使用DNS服务商插件或其他支持DNS API的ACME客户端。
七、证书续期失败的常见原因
1. 域名没有解析到当前服务器
检查IPv4记录:
`bash dig +short A example.com `
检查IPv6记录:
`bash dig +short AAAA example.com `
如果域名解析到了旧服务器、CDN或错误地址,验证请求可能无法到达运行Certbot的服务器。
特别要注意AAAA记录。即使IPv4正确,错误的IPv6解析也可能导致部分验证或访问失败。
2. 80端口没有开放
HTTP-01验证需要证书机构通过80端口访问验证文件。
检查本机监听:
`bash sudo ss -lntp | grep ‘:80’ `
同时检查:
- 云平台安全组。
- 服务器防火墙。
- 路由器或NAT端口转发。
- CDN代理状态。
- Web服务器监听配置。
Let’s Encrypt建议为普通Web站点保留80端口,并将正常访问重定向到HTTPS,而不是完全关闭80端口。
3. 验证目录被重写或拦截
确认验证路径可以访问:
`bash sudo mkdir -p /var/www/example/.well-known/acme-challenge echo test | sudo tee /var/www/example/.well-known/acme-challenge/check.txt curl http://example.com/.well-known/acme-challenge/check.txt `
如果无法返回 test,应检查Nginx location规则、网站根目录、重写配置、身份验证和反向代理。
测试完成后删除临时文件:
`bash sudo rm /var/www/example/.well-known/acme-challenge/check.txt `
4. CDN或代理影响验证
域名经过CDN代理时,验证请求可能被重定向、缓存或拦截。
处理方式包括:
- 确保CDN允许访问
/.well-known/acme-challenge/。 - 暂时关闭代理后进行HTTP验证。
- 改用DNS-01验证。
- 直接在CDN平台管理面向用户的证书。
不要在不了解访问链路的情况下同时修改CDN、DNS和源站配置,否则会增加恢复难度。
5. 证书包含已停用的域名
旧证书可能同时包含多个域名,其中某个域名已经不再解析到服务器,导致整张证书续期失败。
先查看:
`bash sudo certbot certificates `
确认每个域名是否仍然需要。如果需要修改证书包含的域名,应使用 --cert-name 和完整域名列表重新签发,而不是直接删除证书目录。
6. 使用手动验证申请却没有自动化脚本
通过 --manual 完成的证书,如果没有配置认证钩子,通常无法无人值守地自动更新DNS或HTTP验证内容。
这种情况下即使系统定时执行了 certbot renew,证书也可能无法续期。应改用支持自动续期的Nginx、Apache、Webroot或DNS API插件。
7. Certbot定时任务没有运行
不同安装方式可能使用systemd timer、cron或面板计划任务。
检查systemd计时器:
`bash systemctl list-timers –all | grep -i certbot `
检查服务状态:
`bash systemctl status certbot.timer `
查看近期日志:
`bash journalctl -u certbot.service –since “7 days ago” `
如果系统没有 certbot.timer,还要检查cron、snap安装方式和面板任务,不要直接创建重复的续期任务。
八、新证书已经生成但网站仍显示旧证书
这是非常常见的情况。
1. 检查Nginx证书路径
查找实际配置:
`bash sudo nginx -T | grep -E ‘ssl_certificate|ssl_certificate_key’ `
推荐配置指向Certbot的 live 目录,例如:
`nginx ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; `
如果Nginx指向手工复制的旧证书文件,Certbot更新 live 目录后,网站仍然不会使用新证书。
2. 测试配置并重新加载
先测试:
`bash sudo nginx -t `
测试通过后重新加载:
`bash sudo systemctl reload nginx `
重新加载通常比完整重启影响更小。不要跳过 nginx -t,错误配置可能导致加载失败。
3. 再次检查线上证书
`bash echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -serial -dates `
如果仍然是旧证书,继续检查:
- DNS是否指向其他服务器。
- 是否存在多个Nginx实例或容器。
- 443端口是否由负载均衡接管。
- CDN边缘证书是否尚未更新。
- 浏览器是否访问了其他子域名。
九、Apache如何加载新证书
Apache服务器可以先检查配置:
`bash sudo apachectl configtest `
重新加载:
`bash sudo systemctl reload apache2 `
在RHEL、Rocky Linux或兼容环境中,服务名称可能是:
`bash sudo systemctl reload httpd `
证书路径需要以实际虚拟主机配置为准。使用Certbot Apache插件时,可以通过以下命令重新签发和安装:
`bash sudo certbot –apache -d example.com -d www.example.com `
十、为续期配置部署钩子
证书文件更新后,Web服务器通常需要重新加载才能使用新证书。Certbot支持部署钩子:
`bash sudo certbot renew –deploy-hook “systemctl reload nginx” `
部署钩子应只在证书成功更新后执行。
也可以将钩子脚本放到:
`text /etc/letsencrypt/renewal-hooks/deploy/ `
示例脚本:
`bash #!/bin/sh nginx -t && systemctl reload nginx `
创建脚本后要设置可执行权限:
`bash sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh `
部署钩子中不要直接无条件重启多个服务。应先验证配置,并尽量只重新加载实际使用该证书的服务。
十一、如何确认自动续期真的有效
自动续期配置完成后,至少检查以下项目。
1. 模拟续期成功
`bash sudo certbot renew –dry-run `
2. 定时任务存在
`bash systemctl list-timers –all | grep -i certbot `
3. 部署钩子能够正确执行
可以在维护时段单独测试脚本,并检查Nginx或Apache日志。
4. 线上证书与本地证书一致
定期对比到期时间或序列号。
5. 提前设置外部监控
不要只依赖服务器本地任务。服务器磁盘损坏、定时器停用、DNS变更和CDN配置错误,都可能让本地续期状态失去意义。
建议从外部网络监控:
- 证书剩余有效期。
- HTTPS握手是否成功。
- 域名是否匹配。
- 证书链是否完整。
- 站点是否返回正常状态码。
可以设置30天、14天、7天和3天多级告警,避免只在证书过期当天收到通知。
十二、2026年需要注意证书有效期缩短趋势
截至2026年8月,Let’s Encrypt的默认签发证书仍以90天有效期为主,但官方已经公布逐步缩短默认证书有效期的计划,并将继续推动更频繁的自动续期。
这意味着网站管理员不应依赖“每两三个月手工更新一次”的方式。无论使用Certbot、面板、CDN还是云平台证书服务,都应建立可测试、可监控的自动续期流程。
短周期证书并不会明显增加已正确配置自动化系统的日常工作,但会更快暴露那些依赖人工操作、失效DNS凭据或无人维护的续期流程。
十三、私钥泄露不能只重新签发
如果证书过期只是正常时间问题,重新续期即可。但如果怀疑私钥泄露、服务器被入侵或证书被未授权人员复制,处理方式不同。
应当:
- 立即限制受影响服务器的访问。
- 使用新的私钥签发证书。
- 撤销与泄露私钥相关的证书。
- 修改服务器密码、API密钥和DNS凭据。
- 检查异常登录、启动项和配置变更。
- 在确认系统可信后重新部署服务。
只更新证书到期时间不能解决私钥泄露问题。
十四、完整处理流程
网站证书过期时,可以按照下面的顺序处理:
- 使用OpenSSL检查线上证书的域名、签发者和到期时间。
- 判断证书部署在源站、CDN、负载均衡还是管理面板。
- 使用
certbot certificates查看本地证书和路径。 - 使用
certbot renew --dry-run测试续期流程。 - 根据错误检查DNS、80端口、防火墙和验证目录。
- 使用原来的验证方式续期或重新签发证书。
- 检查Nginx或Apache配置是否指向新证书。
- 测试配置后重新加载Web服务器。
- 再次从公网检查证书序列号和到期时间。
- 确认systemd timer、cron或面板续期任务正常。
- 配置部署钩子和外部到期监控。
- 如果私钥可能泄露,立即更换私钥并撤销旧证书。
总结
网站SSL证书过期并不只是重新执行一次申请命令。真正需要解决的是证书为什么没有按时续期,以及新证书能否被正确部署到用户实际连接的HTTPS入口。
排查时应先确认线上证书,再检查域名解析、验证方式、Certbot配置、80端口、Web服务器证书路径、CDN和负载均衡。新证书生成后,还要测试配置并重新加载Nginx或Apache,最后从公网验证网站提供的确实是新证书。
最可靠的方案不是记住证书到期日期,而是建立自动续期、部署钩子和外部监控。只有续期测试成功、定时任务正常、证书能够自动加载并且到期前可以收到告警,整个HTTPS证书管理流程才算完整。




