Shell脚本监控SSL证书到期,提前邮件告警提醒

SSL证书一旦过期,网站会直接报错或无法访问,用户流失和业务中断往往就在一瞬间。
本文提供一套Shell脚本方案,自动检查证书剩余有效期,并在到期前通过邮件发出告警提醒。
整个流程零基础也能照做,最终你会得到一个每天定时运行、结果可验证的监控任务。

需要提前准备的环境和工具

开始之前,确认服务器上已经具备以下条件:

  • 一台能访问目标域名的Linux服务器(本地或远程均可)。
  • 已安装openssl和curl,绝大多数发行版默认自带。
  • 一个可用于发送邮件的SMTP邮箱账号,比如QQ邮箱、163邮箱或企业邮箱。
  • 基本的文本编辑能力,会用vi或nano即可。

如果服务器没有openssl,可以用包管理器安装。
例如在CentOS上执行yum install -y openssl,在Ubuntu/Debian上执行apt install -y openssl。

邮件发送工具推荐使用mailx或sendmail,但更简单的方式是直接用curl调用SMTP服务。
下文会给出具体命令。

获取证书到期时间的正确方法

监控的第一步是准确拿到证书的到期时间。
不要依赖浏览器显示,直接用命令行获取:

echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -enddate

把example.com替换成你的实际域名。
执行后会输出类似notAfter=Jun 15 12:00:00 2025 GMT的结果,这就是证书的到期时间。

注意:如果域名使用了CDN或反向代理,证书可能由CDN提供,这时监控源站证书没有意义,应改为监控CDN上的证书。

拿到到期时间后,需要把它转换成剩余天数。
可以用date命令计算:

expire_date=$(echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
expire_ts=$(date -d "$expire_date" +%s)
now_ts=$(date +%s)
days_left=$(( (expire_ts - now_ts) / 86400 ))
echo "剩余天数: $days_left"

这段命令会输出证书距离过期还有多少天。86400是一天的秒数。

编写监控脚本并加入邮件告警

新建一个脚本文件,比如/opt/ssl_monitor.sh,内容如下:

#!/bin/bash

# 要监控的域名列表,每行一个
DOMAINS=(
  "example.com"
  "www.example.com"
)

# 提前多少天开始告警
WARN_DAYS=15

# 收件人邮箱
MAIL_TO="your_email@example.com"

# SMTP配置(以QQ邮箱为例)
SMTP_SERVER="smtp.qq.com"
SMTP_PORT="465"
SMTP_USER="your_email@qq.com"
SMTP_PASS="你的授权码"

for domain in "${DOMAINS[@]}"; do
  expire_date=$(echo | openssl s_client -servername "$domain" -connect "$domain:443" 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
  if [ -z "$expire_date" ]; then
    echo "无法获取 $domain 的证书信息"
    continue
  fi
  expire_ts=$(date -d "$expire_date" +%s)
  now_ts=$(date +%s)
  days_left=$(( (expire_ts - now_ts) / 86400 ))

  if [ "$days_left" -le "$WARN_DAYS" ]; then
    subject="SSL证书告警: $domain 剩余 $days_left 天"
    body="域名 $domain 的SSL证书将于 $expire_date 过期,剩余 $days_left 天,请及时续期。"

    curl -s --url "smtps://$SMTP_SERVER:$SMTP_PORT" --ssl-reqd \
      --mail-from "$SMTP_USER" \
      --mail-rcpt "$MAIL_TO" \
      --user "$SMTP_USER:$SMTP_PASS" \
      -T <(echo -e "From: $SMTP_USER\nTo: $MAIL_TO\nSubject: $subject\n\n$body")
  fi
done

保存后赋予执行权限:

chmod +x /opt/ssl_monitor.sh

关键点:SMTP_PASS通常不是邮箱登录密码,而是邮箱服务商提供的授权码。
以QQ邮箱为例,需要在设置中开启SMTP服务并生成授权码。

设置定时任务让脚本自动运行

手动执行一次脚本,确认能正常获取到期天数且邮件能发出:

/opt/ssl_monitor.sh

如果收到测试邮件,说明配置正确。
接着用crontab设置每天自动运行:

crontab -e

加入一行:

0 9 * * * /bin/bash /opt/ssl_monitor.sh >/dev/null 2>&1

这表示每天上午9点执行一次。>/dev/null 2>&1用于丢弃正常输出,避免产生大量日志。

避坑提示:

  • 脚本中的域名列表要用数组格式,每行一个,不要用逗号分隔。
  • 如果服务器无法解析域名,检查/etc/resolv.conf中的DNS配置。
  • 邮件发送失败时,先用curl命令单独测试SMTP连通性,确认端口和授权码无误。
  • 部分云服务器默认封禁25端口,建议使用465或587端口。

验证监控是否真正生效

脚本部署后,需要确认它确实在工作。
可以临时把WARN_DAYS改成一个很大的值,比如365,这样所有域名都会触发告警,方便测试邮件发送流程。
测试完成后记得改回合理数值。

另外,查看crontab日志确认任务执行情况:

grep CRON /var/log/syslog

或者查看/var/log/cron(CentOS系)。
如果日志中没有报错,且收到了告警邮件,说明整个监控链路已经跑通。

建议每月手动检查一次证书剩余天数,与脚本输出对比,确保结果一致。
证书续期后,脚本会自动更新剩余天数,无需额外调整。

常见疑问

脚本能监控多个域名吗?
可以。在DOMAINS数组中添加域名即可,每个域名会独立检查并发送告警。

邮件收不到怎么办?
先检查垃圾邮件箱,再确认授权码是否正确、SMTP端口是否被防火墙拦截。用telnet smtp.qq.com 465测试连通性。

证书续期后还需要改脚本吗?
不需要。脚本每次运行都会重新获取证书到期时间,续期后剩余天数会自动增加。

可以用企业微信或钉钉告警代替邮件吗?
可以。把curl发送邮件的部分替换为调用企业微信机器人或钉钉Webhook的API即可,原理相同。

分享到:
上一篇
Docker容器资源限制,限制CPU内存防止抢占资源
下一篇
宝塔面板备份异地推送,自动上传备份到对象存储
1
系统公告

泽御云中秋国庆双节活动上线:新购8折,拼团3.99元起

尊敬的用户:
泽御云“月满中秋·礼贺国庆”双节活动现已开启,活动时间为2026年9月23日至10月10日。 活动期间可享以下福利:
1. 常规云服务器新购使用优惠码“泽御中秋国庆同乐”,符合条件的订单享8折优惠。
2. 香港精品云服务器5人拼团低至3.99元,部分4核4G套餐3人拼团年付388元,续费同价。
3. 新用户购买年付云服务器,符合活动规则可赠送2个月使用时长。
4. 老用户续费季度赠15天,续费年度赠2个月;活动期间升级配置免收配置迁移手续费。
5. 推荐好友成功下单,符合条件的推荐人可获赠7天服务器使用时长。
6. 活动期间享宕机补偿标准翻倍、简单网站迁移协助及技术工单优先处理权益。
温馨提示:优惠码不适用于拼团套餐、活动轻量产品、年付订单及续费订单;拼团套餐为独立特价活动,不与赠时类福利叠加。赠送时长不可折现、退款或跨账户转移,具体规则以活动页面说明为准。
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意