Nginx证书监控需外部脚本实现多渠道分级告警:统一计算剩余天数,按≥15天(仅日志)、8–14天(企微/钉钉普通提醒)、1–7天(企微+邮件+@责任人)、≤0天(钉钉加签+短信+CRITICAL日志)分层触发,各渠道独立封装调用,并通过状态文件防重复、logrotate轮转日志。

Nginx 本身不提供证书监控能力,所谓“多渠道升级告警”,必须靠外部脚本驱动,核心是一次检查、分层触发:先统一计算剩余天数,再按不同阈值(如15天、7天、当天)分别投递到不同渠道,避免重复、兼顾及时性与重要性。
统一检查逻辑:提取有效期并分级判断
脚本需从本地 PEM 文件或远程域名实时获取证书 Not After 时间,转为 Unix 时间戳后计算剩余天数。关键不是“只告警一次”,而是根据剩余天数动态选择通道:
- ≥15 天:不告警,仅记录日志
- 8–14 天:发企业微信/钉钉普通提醒(低优先级)
- 1–7 天:同时发企业微信 + 邮件,并 @ 责任人(中优先级)
- ≤0 天(已过期):立即触发钉钉加签机器人 + 短信网关(高优先级),并写入 CRITICAL 日志
多渠道发送的关键实现要点
不同渠道的调用不能堆砌在同一个 if 分支里,而应封装为独立函数,由主逻辑按需调用:
- 企业微信:先用 CorpID + Secret 获取 access_token(缓存 2 小时),再 POST 到应用 Webhook;推荐 markdown 格式,含域名、剩余天数、过期时间、运维操作链接
- 钉钉机器人:启用加签时,需拼接 timestamp + 密钥生成 hmac-sha256 签名,并追加到 URL 后;消息体带 at_mobiles 字段才能真正 @ 到人
- 邮件通知:使用 mail 命令需提前配置 msmtp 或 ssmtp;更稳的方式是调用 Python 的 smtplib,支持 HTML 格式和附件(如证书详情截图)
- 短信网关:对接阿里云/腾讯云 API,用 curl 发送 JSON 请求;注意频率限制,过期告警只触发一次,需用状态文件锁住
防重复与状态管理必须做
多渠道不等于多刷屏。同一域名在相同告警级别下,24 小时内不应重复推送:
- 用 /tmp/cert_alert_state_域名_级别 文件记录最近一次触发时间(如 EXPIRED_20260821)
- 每次检查前先读该文件,若存在且距今
- 级别变化时(如从“7天”降为“已过期”),自动清除旧状态文件,允许新告警
集成到系统:定时执行 + 权限 + 日志闭环
脚本不是孤立运行的,要嵌入运维基础设施:
- 放入 /opt/nginx-cert-monitor/check.sh,chmod +x,属主 root:root
- crontab 设为每天凌晨 2 点执行:0 2 * * * /opt/nginx-cert-monitor/check.sh >> /var/log/cert_monitor.log 2>&1
- 日志文件需轮转:用 logrotate 配置每周归档,保留 8 周,防止撑爆磁盘
- 证书路径建议用配置文件管理(如 /etc/nginx-cert-monitor/domains.conf),每行格式:example.com /etc/nginx/ssl/example.com/fullchain.pem


















