最快的方法是 echo | openssl s_client -servername host -connect host:443 2>/dev/null | openssl x509 -noout -enddate,直接打印出准确的 notAfter 日期,完全不用打开浏览器。接下来可以把这个日期换算成剩余天数,写一个适合 cron 的通过/失败检查,或者一次性扫描一整份域名列表。这是完整的工作流程,不只是大家都知道的那一条命令。
1. 某个网站的证书何时到期
$ 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 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 检查证书是否会在接下来 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 从一个文件里读取域名列表并检查证书到期时间→ 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 显示这个证书文件的有效期→ openssl x509 -in /etc/ssl/certs/example.pem -noout -dates
对于磁盘上已有的文件,根本不需要 s_client。-dates 会同时显示 notBefore 和 notAfter——前者很关键,因为有的证书是为将来签发的,此刻还没生效。
6. 查看完整的证书链
$ 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 帮你写命令。一行命令安装。