CLI AI

用 openssl 检查 SSL 证书何时到期

2026-06-27

最快的方法是 echo | openssl s_client -servername host -connect host:443 2>/dev/null | openssl x509 -noout -enddate,直接打印出准确的 notAfter 日期,完全不用打开浏览器。接下来可以把这个日期换算成剩余天数,写一个适合 cron 的通过/失败检查,或者一次性扫描一整份域名列表。这是完整的工作流程,不只是大家都知道的那一条命令。

1. 某个网站的证书何时到期

clai
$ clai cliai.tech 的证书什么时候到期→ echo | openssl s_client -servername cliai.tech -connect cliai.tech:443 2>/dev/null | openssl x509 -noout -enddate -subjectnotAfter=Nov  2 10:19:50 2026 GMTsubject=CN=cliai.tech

echo | 关闭标准输入,否则 s_client 会一直等待交互输入。-servername 设置 SNI,只要一个 IP 上跑了不止一个网站——而这几乎总是事实——就必须加上它。

2. 还剩多少天

clai
$ clai cliai.tech 的证书还有多少天到期→ exp=$(echo | openssl s_client -servername cliai.tech -connect cliai.tech:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2); echo $(( ($(date -d "$exp" +%s) - $(date +%s)) / 86400 )) days

date -d 解析 OpenSSL 的日期格式,剩下的就是普通的秒数运算。这个数字就是监控里要和阈值比较的那个值。

3. 不用自己算天数的检查方式

clai
$ clai 检查证书是否会在接下来 30 天内到期→ echo | openssl s_client -servername cliai.tech -connect cliai.tech:443 2>/dev/null | openssl x509 -noout -checkend 2592000 && echo "ok" || echo "expires within 30 days"

-checkend 接受秒数,返回的是退出码,不是文本。2592000 就是 30 天。可以直接放进脚本——不需要解析任何输出。

4. 一次检查一整份域名列表

clai
$ clai 从一个文件里读取域名列表并检查证书到期时间→ while read d; do printf '%-28s ' "$d"; echo | openssl s_client -servername "$d" -connect "$d":443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2; done < domains.txt

同样的技巧放进循环里。把 domains.txt 放在脚本旁边——更新列表比改命令本身容易得多。

5. 本地的证书文件

clai
$ clai 显示这个证书文件的有效期→ openssl x509 -in /etc/ssl/certs/example.pem -noout -dates

对于磁盘上已有的文件,根本不需要 s_client。-dates 会同时显示 notBefore 和 notAfter——前者很关键,因为有的证书是为将来签发的,此刻还没生效。

6. 查看完整的证书链

clai
$ clai 显示这个网站的证书链→ echo | openssl s_client -servername cliai.tech -connect cliai.tech:443 -showcerts 2>/dev/null | grep -E 's:|i:'

-showcerts 会返回整条证书链,s: 是 subject,i: 是 issuer。链不完整是常见的原因,网站在浏览器里能正常打开,但在 curl 或手机 App 里就报错。

常见坑

  • 不加 -servername 可能查到别人的证书。 在共享 IP 上,没有 SNI 的服务器会返回默认证书,你测到的其实是另一个网站的到期时间。
  • date -d 只有 GNU 版本才有。 在 macOS 上要用 date -j -f '%b %d %T %Y %Z',输入格式得自己手写。
  • 证书到期和域名到期是两回事。 证书自动续期救不了你,如果域名本身过期,或者 ACME 验证挂了。

相关问题

怎么检查非标准端口上的证书? 把端口换进 -connect,比如 -connect mail.example.com:993,协议需要升级连接的话再加上 -starttls imap。

为什么浏览器显示证书有效,curl 却报错? 通常是证书链不完整:浏览器会自己补上缺失的中间证书,curl 不会。看看 -showcerts 的输出。

怎么把提醒自动化? 把带 -checkend 的版本放进 cron,退出码非零就发通知。30 天的阈值留出了处理的时间。

相关阅读

别再手写 openssl 长命令了——描述你的需求,CliAI 帮你写命令。一行命令安装。