ssl证书巡检核心是准确提取剩余天数、判断≤7天、触发多渠道告警;用openssl加-servername和timeout提取not after时间,转时间戳计算天数;批量检查配置文件中域名,跳过注释与空行,按返回码容错处理。

每天凌晨自动巡检 SSL 证书到期时间并提前一周预警,核心是三件事:准确提取证书剩余天数、判断是否 ≤7 天、触发告警(邮件/钉钉/企业微信等)。Shell 脚本完全能胜任,关键在稳定性和容错。
一、用 openssl 提取目标域名证书剩余天数
不依赖外部工具,只靠系统自带 openssl 和 date。重点是解析证书的 Not After 时间,并转成秒数与当前时间比对:
- 命令示例:
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2- - 必须加
-servername参数,否则 SNI 不匹配可能拿到错误证书(尤其 CDN 或多域名共用 IP 场景) - 建议加超时控制:
timeout 10s openssl s_client ...,避免卡死影响定时任务 - 提取后用
date -d "xxx" +%s转为时间戳,再减去$(date +%s),除以 86400 取整得剩余天数
二、批量检查多个域名并统一预警逻辑
把要监控的域名写进配置文件(如 /etc/ssl-check/domains.txt),每行一个,支持注释和端口自定义:
- 格式示例:
example.com:443或api.internal.org:8443,空行和#开头行自动跳过 - 脚本循环读取,对每个域名执行证书检查,捕获 openssl 返回码(0 成功,非 0 失败)
- 失败时记录日志(如连接超时、证书不可达),不误报“即将过期”,避免干扰告警
- 剩余天数 ≤7 且 >0,视为“需预警”;=0 是已过期;
三、告警方式选轻量可靠的(推荐邮件+日志双通道)
生产环境不建议只依赖一种通知方式。Shell 原生发邮件最稳妥:
- 用
mail -s "SSL 过期预警" admin@example.com 发文本告警,内容含域名、剩余天数、过期时间、检查时间 - 同时追加到统一日志文件(如
/var/log/ssl-check.log),带时间戳,方便排查和审计 - 若需钉钉/企微,用 curl 调 Webhook:构造 JSON payload,注意 URL 要 escape,响应状态码 200 才算发送成功
- 加锁机制(如
flock -n /tmp/ssl-check.lock)防止凌晨多个实例并发冲突
四、加入 crontab 并验证执行效果
定时任务设为每天 3:00 执行(避开业务高峰),务必指定 SHELL 和 PATH:
- crontab 条目:
0 3 * * * SHELL=/bin/bash PATH=/usr/local/bin:/usr/bin:/bin /opt/scripts/ssl-check.sh >/dev/null 2>&1 - 首次运行前手动执行一次:
sudo -u root /opt/scripts/ssl-check.sh,检查日志和邮件是否正常 - 模拟过期场景测试:改本地时间或用测试域名(如
expired.badssl.com),确认告警触发逻辑正确 - 日志保留 30 天,可用 logrotate 管理,避免磁盘占满
整个流程不复杂但容易忽略细节:SNI 支持、超时控制、错误隔离、日志留存。脚本写好后,加个简单的 usage 提示和参数开关(如 -d 调试模式),维护起来就轻松多了。











