直接查看证书过期时间需区分本地文件与线上服务:本地用openssl x509 -in cert.pem -noout -enddate,要求文件仅含一段pem证书;线上用echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate,确保sni和协议匹配。

能直接看,但必须分清是查本地文件还是线上服务——搞混了就报错或看到过期信息。
查本地 PEM/CRT 证书文件的到期时间
你手头有 cert.pem、fullchain.pem 或 server.crt 这类文件,想确认它本身是否快过期?用 openssl x509 直接读就行,前提是文件干净。
- 只含一段证书:开头是
-----BEGIN CERTIFICATE-----,结尾是-----END CERTIFICATE-----,中间不能夹私钥或其它证书 - 命令:
openssl x509 -in cert.pem -noout -enddate,输出类似notAfter=Mar 15 12:34:56 2025 GMT - 如果报
unable to load certificate,八成是文件混了内容;可用awk '/^-----BEGIN CERTIFICATE-----$/,/^-----END CERTIFICATE-----$/' cert.pem抽出第一段再试 - 想同时看生效和过期:
openssl x509 -in cert.pem -noout -dates
查正在运行的 HTTPS 服务真实证书
本地文件可能已更新,但 Nginx/Apache 没 reload,或者配置指向了旧路径。此时必须从网络层真实握手一次,拿到服务端此刻实际返回的证书链。
- 基础命令:
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -enddate - 必须加
-servername example.com(启用 SNI),否则多域名服务器可能返回默认证书 - 若连接失败报
ssl handshake failure,不是证书问题,而是协议不匹配:加-tls1_3或-tls1_2强制版本 - 若服务用了私有 CA 或自签名证书,
s_client会报验证失败,但只要加了-noout就不影响提取-enddate
计算剩余天数并预警(运维常用)
光看日期不够直观,生产环境需要知道“还剩几天”,且要规避系统 locale 差异导致的 date -d 解析失败。
- 推荐用 OpenSSL 自带的
-checkend:比如检查 30 天内是否过期,openssl x509 -checkend 2592000 -noout -in cert.pem(2592000 = 30 × 24 × 3600) - 返回值为 0 表示有效,非 0 表示即将过期;脚本里可直接用
if ! openssl x509 -checkend ...判断 - 避免依赖
date -d "Mar 15 12:34:56 2025 GMT":不同发行版对月份缩写解析不一致(如 CentOS vs Ubuntu),容易在自动化中静默失败 - 批量检查目录下所有证书:
find /etc/letsencrypt/live -name "fullchain.pem" -exec openssl x509 -noout -enddate -in {} \; 2>/dev/null
常见错误和绕过点
很多报错不是命令写错,而是环境或证书结构没理清。
-
Connection refused:端口不通,先telnet example.com 443确认连得上 -
verify error:num=20:unable to get local issuer certificate:证书链不全,但不影响-noout -enddate提取 - 用
fullchain.pem直接查会失败:它包含站点证书 + 中间证书,openssl x509只认单段;应拆出第一段或改用server.crt - Let’s Encrypt 的
live/domain/cert.pem是软链,指向archive/下某次签发的证书,记得确认软链目标是否最新
真正麻烦的不是命令记不住,而是证书文件里藏了私钥、中间证书混在一块、或者线上服务用的是另一份没同步的证书——这些细节不手动验证一遍,光跑命令只会给你一个“看起来正常”的假象。











