SSL证书到期检查与告警脚本
批量检查域名SSL证书到期时间,提前告警,支持多域名、邮件/企业微信告警
详细内容
#!/bin/bash
# ==========================================
# SSL证书到期检查与告警脚本
# 用途:批量检查域名SSL证书到期时间,提前告警
# 使用方法:bash ssl_cert_check.sh
# ==========================================
# 配置
DOMAINS="${DOMAINS:-www.example.com api.example.com}"
WARN_DAYS="${WARN_DAYS:-30}"
ALERT_EMAIL="${ALERT_EMAIL:-}"
ALERT_WEBHOOK="${ALERT_WEBHOOK:-}"
TIMEOUT="${TIMEOUT:-10}"
echo "========== SSL证书检查报告 =========="
echo "检查时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "告警阈值: 剩余${WARN_DAYS}天"
echo ""
# 检查openssl
if ! command -v openssl &> /dev/null; then
echo "❌ 错误: openssl未安装"
exit 1
fi
ALERTS=()
TOTAL=0
VALID=0
EXPIRING=0
EXPIRED=0
check_cert() {
local domain=$1
local port=${2:-443}
TOTAL=$((TOTAL + 1))
echo "【检查: $domain:$port】"
# 获取证书信息
CERT_INFO=$(echo | openssl s_client -connect "${domain}:${port}" -servername "$domain" -timeout "$TIMEOUT" 2>/dev/null | openssl x509 -noout -dates -subject -issuer 2>/dev/null)
if [ -z "$CERT_INFO" ]; then
echo " ❌ 无法获取证书信息"
ALERTS+=("❌ $domain: 无法获取证书信息")
return
fi
# 解析证书信息
NOT_BEFORE=$(echo "$CERT_INFO" | grep "notBefore" | cut -d= -f2)
NOT_AFTER=$(echo "$CERT_INFO" | grep "notAfter" | cut -d= -f2)
SUBJECT=$(echo "$CERT_INFO" | grep "subject" | cut -d= -f2-)
ISSUER=$(echo "$CERT_INFO" | grep "issuer" | cut -d= -f2-)
# 计算剩余天数
EXPIRY_TIMESTAMP=$(date -d "$NOT_AFTER" +%s 2>/dev/null)
CURRENT_TIMESTAMP=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_TIMESTAMP - CURRENT_TIMESTAMP) / 86400 ))
echo " 主题: $SUBJECT"
echo " 颁发者: $ISSUER"
echo " 生效时间: $NOT_BEFORE"
echo " 到期时间: $NOT_AFTER"
echo " 剩余天数: $DAYS_LEFT 天"
if [ "$DAYS_LEFT" -le 0 ]; then
echo " 🔴 证书已过期!"
EXPIRED=$((EXPIRED + 1))
ALERTS+=("🔴 $domain: 证书已过期 $((-DAYS_LEFT)) 天")
elif [ "$DAYS_LEFT" -le "$WARN_DAYS" ]; then
echo " 🟡 证书即将到期!"
EXPIRING=$((EXPIRING + 1))
ALERTS+=("🟡 $domain: 证书剩余 $DAYS_LEFT 天到期")
else
echo " ✅ 证书正常"
VALID=$((VALID + 1))
fi
echo ""
}
# 逐个检查域名
for domain in $DOMAINS; do
if echo "$domain" | grep -q ":"; then
host=$(echo "$domain" | cut -d: -f1)
port=$(echo "$domain" | cut -d: -f2)
check_cert "$host" "$port"
else
check_cert "$domain"
fi
done
# 检查汇总
echo "========== 检查汇总 =========="
echo " 总检查数: $TOTAL"
echo " ✅ 正常: $VALID"
echo " 🟡 即将到期: $EXPIRING"
echo " 🔴 已过期: $EXPIRED"
echo ""
# 告警
if [ ${#ALERTS[@]} -gt 0 ]; then
echo "【告警详情】"
for alert in "${ALERTS[@]}"; do
echo " $alert"
done
echo ""
# 发送邮件告警
if [ -n "$ALERT_EMAIL" ]; then
SUBJECT="SSL证书到期告警 - $(date '+%Y-%m-%d')"
BODY="SSL证书检查发现以下问题:
"
for alert in "${ALERTS[@]}"; do
BODY="$BODY$alert
"
done
echo -e "$BODY" | mail -s "$SUBJECT" "$ALERT_EMAIL" 2>/dev/null
echo "📧 已发送邮件告警到: $ALERT_EMAIL"
fi
# 发送Webhook告警(企业微信/钉钉)
if [ -n "$ALERT_WEBHOOK" ]; then
CONTENT="SSL证书到期告警:
"
for alert in "${ALERTS[@]}"; do
CONTENT="$CONTENT$alert
"
done
curl -s -X POST "$ALERT_WEBHOOK" -H "Content-Type: application/json" -d "{"content": "$CONTENT"}" >/dev/null 2>&1
echo "🔔 已发送Webhook告警"
fi
else
echo "✅ 所有证书正常,无需告警"
fi
echo ""
echo "========== 检查完成 =========="
echo "提示: 可将此脚本加入crontab定时执行,例如每天检查一次"
echo " 0 9 * * * /path/to/ssl_cert_check.sh"
适配环境
适配系统:CentOS 7+,Ubuntu 18.04+,Debian 10+
依赖环境:bash 4.0+
参数说明
[{"name": "DOMAINS", "label": "\u57df\u540d\u5217\u8868(\u7a7a\u683c\u5206\u9694)", "default": "www.example.com"}, {"name": "WARN_DAYS", "label": "\u544a\u8b66\u9608\u503c(\u5929)", "default": "30"}, {"name": "ALERT_EMAIL", "label": "\u544a\u8b66\u90ae\u7bb1", "default": ""}, {"name": "ALERT_WEBHOOK", "label": "Webhook\u5730\u5740", "default": ""}]