4. 证书有效期监控:设置预警阈值(30天、15天、7天)
证书过期,是生产环境中最常见、也最不该发生的故障。我见过太多团队因为一张证书过期,导致整个支付链路中断两小时。说白了,这不是技术问题,是管理问题。
有效期监控的核心就一句话:在证书死掉之前,给你留足反应时间。那留多少天合适?我个人习惯设三层:30天、15天、7天。为什么是这三个数字?往下看。
4.1 三层预警模型:为什么是30/15/7?
你想想看,证书续签这件事,涉及的人不止你一个。你得找CA申请、等审批、拿新证、部署、重启服务。每一步都可能卡住。所以预警不能只设一个点,得分层。
| 预警层级 | 阈值 | 预警级别 | 响应要求 |
|---|---|---|---|
| 第一层 | 30天 | 提醒(Info) | 确认证书归属,启动续签流程 |
| 第二层 | 15天 | 警告(Warning) | 必须提交续签申请,进入审批 |
| 第三层 | 7天 | 紧急(Critical) | 立即执行,跳过非必要审批 |
30天那层,说白了是给你「看一眼」的机会。我建议这时候发邮件或钉钉消息,别太吵。15天是真正的行动线。7天是红线——我曾经遇到过某家银行,7天预警发出去没人理,结果第6天CA系统宕机,差点没续上。从那以后,7天预警我直接打电话。
核心原则:预警不是通知,是驱动行动。每一层预警都必须对应一个明确的动作,否则就是噪音。
4.2 预警阈值配置实战
不管你是用Prometheus、Zabbix还是自研平台,阈值配置的逻辑都一样。我拿Prometheus举个例,因为它的表达式最直观。
4.2.1 Prometheus 告警规则示例
groups:
- name: certificate_expiry
rules:
- alert: CertExpiryIn30Days
expr: |
(x509_cert_not_after - time()) / 86400 <= 30
and
(x509_cert_not_after - time()) / 86400 > 15
for: 1h
labels:
severity: info
annotations:
summary: "证书 {{ $labels.common_name }} 将在30天内过期"
description: "剩余 {{ $value | humanizeDuration }}"
- alert: CertExpiryIn15Days
expr: |
(x509_cert_not_after - time()) / 86400 <= 15
and
(x509_cert_not_after - time()) / 86400 > 7
for: 30m
labels:
severity: warning
annotations:
summary: "证书 {{ $labels.common_name }} 将在15天内过期"
description: "剩余 {{ $value | humanizeDuration }},请尽快续签"
- alert: CertExpiryIn7Days
expr: |
(x509_cert_not_after - time()) / 86400 <= 7
for: 10m
labels:
severity: critical
annotations:
summary: "证书 {{ $labels.common_name }} 将在7天内过期"
description: "剩余 {{ $value | humanizeDuration }},立即处理!"
小技巧:注意每个规则的 for 字段。30天预警我设1小时,避免短时波动误报。7天预警只等10分钟,因为这时候每一分钟都宝贵。
4.2.2 用脚本做兜底检查
有些环境跑不了Prometheus,比如离线内网。我习惯写一个简单的Shell脚本,配合crontab做兜底。嗯,这里要注意:脚本里一定要处理时区问题,我踩过坑。
#!/bin/bash
# 证书有效期检查脚本
# 用法: ./check_cert_expiry.sh /path/to/cert.pem
CERT_PATH=$1
WARN_DAYS=30
CRIT_DAYS=7
# 获取证书过期时间(秒)
EXPIRY_EPOCH=$(openssl x509 -in "$CERT_PATH" -noout -enddate | cut -d= -f2 | date -f - +%s)
NOW_EPOCH=$(date +%s)
REMAIN_DAYS=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))
if [ $REMAIN_DAYS -le $CRIT_DAYS ]; then
echo "CRITICAL: 证书 $CERT_PATH 剩余 $REMAIN_DAYS 天"
exit 2
elif [ $REMAIN_DAYS -le $WARN_DAYS ]; then
echo "WARNING: 证书 $CERT_PATH 剩余 $REMAIN_DAYS 天"
exit 1
else
echo "OK: 证书 $CERT_PATH 剩余 $REMAIN_DAYS 天"
exit 0
fi
避坑指南:我曾经在macOS上写这个脚本,date -f 参数不兼容。后来统一用 date -d 加GNU date才解决。跨平台时一定要测试date命令的行为。
4.3 预警阈值动态调整策略
30/15/7是通用模板,但实际场景需要微调。我总结了几种常见情况:
- 根CA证书:有效期通常10年以上,预警可以放宽到90天。但千万别不管,根证丢了比叶子证过期更麻烦。
- 内部CA签发证书:流程快,15天预警就够了。我建议把7天预警改成3天,给自己留点缓冲。
- 外部CA证书(如Let's Encrypt):90天有效期,30天预警其实已经有点晚了。我习惯设成45天、20天、10天。
- 设备证书(IoT场景):设备可能离线,预警要提前到60天。因为你要留出设备回连、OTA升级的时间。
| 证书类型 | 典型有效期 | 建议预警阈值 | 备注 |
|---|---|---|---|
| 根CA证书 | 10-20年 | 90/60/30天 | 手动续签,流程长 |
| 内部CA签发证书 | 1-3年 | 30/15/3天 | 自动化程度高 |
| Let's Encrypt | 90天 | 45/20/10天 | 自动续签为主 |
| IoT设备证书 | 1-5年 | 60/30/15天 | 考虑设备离线窗口 |
4.4 预警阈值背后的知识体系
说了这么多,其实就一张图能讲清楚。我画了个流程图,帮你理解三层预警怎么联动。
这张图的核心逻辑是:每一层预警触发时,都要检查上一层的动作是否已完成。如果30天预警发了没人动,15天预警就不能只发通知,得升级处理。我见过最惨的案例,就是每层预警都发邮件,结果没人看,最后证书过期了才发现。
4.5 预警阈值的最佳实践总结
最后,我把自己踩过的坑和总结的经验列一下:
- 不要只设一个阈值。单点预警等于没有预警。万一那天你休假呢?
- 预警渠道要分层。30天发邮件,15天发邮件+钉钉,7天直接打电话。我建议7天预警的接收人里加上你的领导。
- 节假日要自动顺延。如果证书在春节前7天过期,预警要提前到15天。我写过一个脚本,对接节假日API自动调整阈值。
- 测试预警流程。每季度做一次模拟演练,真的让证书走到7天预警,看团队能不能在24小时内续上。我第一次演练就发现,有人不知道私钥在哪。
- 记录预警响应时间。每次预警从触发到关闭,记录耗时。如果连续三次都在7天预警才处理,说明30天和15天的流程有问题。
我的习惯:在监控系统里加一个「证书健康度」仪表盘,显示所有证书的剩余天数,按颜色排序。绿色>30天,黄色15-30天,红色<15天。每天早上看一眼,心里有数。
阈值设好了,监控就跑起来了。但别忘了,监控只是手段,续签才是目的。下一层我们要聊的,就是证书发现和资产盘点——你得先知道你有多少张证书,才能管好它们。