本文目录导读:

我来介绍几种Shell脚本监控SSL证书有效期的方法:
使用openssl命令(基础版)
#!/bin/bash
DOMAIN="example.com"
PORT="443"
WARNING_DAYS=30
# 获取证书过期时间
expiry_date=$(echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:$PORT 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
# 转换为时间戳
expiry_timestamp=$(date -d "$expiry_date" +%s)
current_timestamp=$(date +%s)
# 计算剩余天数
remaining_days=$(( ($expiry_timestamp - $current_timestamp) / 86400 ))
echo "域名: $DOMAIN"
echo "过期时间: $expiry_date"
echo "剩余天数: $remaining_days"
if [ $remaining_days -le $WARNING_DAYS ]; then
echo "⚠️ 警告: SSL证书将在 ${remaining_days} 天后过期!"
# 可以在这里添加发送告警的代码
exit 1
else
echo "✅ SSL证书状态正常"
exit 0
fi
多域名批量监控
#!/bin/bash
# 配置域名列表
DOMAINS=(
"example.com:443"
"www.example.com:443"
"api.example.com:443"
)
# 告警阈值(天)
WARNING_DAYS=30
# 日志文件
LOG_FILE="/var/log/ssl_monitor.log"
# 发送告警通知(示例:钉钉/邮件等)
send_alert() {
local domain=$1
local days=$2
local expiry=$3
# 示例:输出到日志
echo "$(date '+%Y-%m-%d %H:%M:%S') - ALERT: $domain 证书将在 ${days} 天后过期(到期日: $expiry)" >> $LOG_FILE
# 在这里可以添加发送邮件、钉钉、Slack等通知
}
# 监控函数
check_certificate() {
local domain_port=$1
local domain=$(echo $domain_port | cut -d: -f1)
local port=$(echo $domain_port | cut -d: -f2)
# 获取证书信息
local cert_info=$(echo | openssl s_client -servername $domain -connect $domain:$port 2>/dev/null)
if [ $? -ne 0 ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - ERROR: 无法连接到 $domain:$port" >> $LOG_FILE
return 1
fi
# 获取过期时间
local expiry_date=$(echo "$cert_info" | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
local subject=$(echo "$cert_info" | openssl x509 -noout -subject 2>/dev/null | sed 's/.*CN = //' | sed 's/,.*//')
if [ -z "$expiry_date" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') - WARNING: 无法获取 $domain 的证书信息" >> $LOG_FILE
return 1
fi
# 计算剩余天数
local expiry_timestamp=$(date -d "$expiry_date" +%s 2>/dev/null)
local current_timestamp=$(date +%s)
local remaining_days=$(( ($expiry_timestamp - $current_timestamp) / 86400 ))
echo "$(date '+%Y-%m-%d %H:%M:%S') - $domain - 证书持有者: $subject - 过期时间: $expiry_date - 剩余: ${remaining_days}天" >> $LOG_FILE
# 检查是否需要告警
if [ $remaining_days -le $WARNING_DAYS ]; then
send_alert "$domain" "$remaining_days" "$expiry_date"
return 1
fi
return 0
}
# 主流程
echo "===== SSL证书监控检查开始 ====="
echo "检查时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "告警阈值: ${WARNING_DAYS}天"
echo "================================"
# 循环检查所有域名
for domain_port in "${DOMAINS[@]}"; do
check_certificate "$domain_port"
done
echo "===== SSL证书监控检查完成 ====="
带颜色输出的增强版
#!/bin/bash
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
check_ssl_cert() {
local domain=$1
local port=${2:-443}
# 使用openssl获取证书信息
local result=$(echo | openssl s_client -servername $domain -connect $domain:$port 2>/dev/null)
if [ $? -ne 0 ]; then
echo -e "${RED}✗ 无法连接到 $domain:$port${NC}"
return 1
fi
# 获取过期时间
local expiry_date=$(echo "$result" | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
if [ -z "$expiry_date" ]; then
echo -e "${RED}✗ 无法获取 $domain 的证书信息${NC}"
return 1
fi
# 计算剩余时间
local expiry_epoch=$(date -d "$expiry_date" +%s 2>/dev/null)
local now_epoch=$(date +%s)
local days_left=$(( ($expiry_epoch - $now_epoch) / 86400 ))
# 获取证书主题
local subject=$(echo "$result" | openssl x509 -noout -subject 2>/dev/null | sed 's/.*CN = //' | sed 's/,.*//')
# 输出结果
echo -e "域名: ${YELLOW}$domain${NC}"
echo -e "端口: ${YELLOW}$port${NC}"
echo -e "证书持有者: ${YELLOW}$subject${NC}"
echo -e "过期时间: ${YELLOW}$expiry_date${NC}"
if [ $days_left -ge 30 ]; then
echo -e "剩余天数: ${GREEN}${days_left}天 ✓${NC}"
elif [ $days_left -ge 7 ]; then
echo -e "剩余天数: ${YELLOW}${days_left}天 ⚠${NC}"
else
echo -e "剩余天数: ${RED}${days_left}天 ✗${NC}"
fi
echo "------------------------"
}
# 检查多个域名
DOMAINS=(
"google.com"
"baidu.com"
"github.com"
)
echo "SSL证书有效期检查"
echo "=================="
for domain in "${DOMAINS[@]}"; do
check_ssl_cert "$domain"
done
Crontab定时检查并发送告警
#!/bin/bash
# 配置
DOMAINS=("example.com" "www.example.com" "api.example.com")
WARNING_DAYS=14
EMAIL="admin@example.com"
LOG_FILE="/var/log/ssl_check.log"
# 日志函数
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> $LOG_FILE
}
# 发送邮件告警
send_email_alert() {
local domain=$1
local days=$2
local expiry=$3
local subject="[警告] SSL证书即将过期 - $domain"
local body="域名: $domain\n证书过期时间: $expiry\n剩余天数: $days"
echo -e "$body" | mail -s "$subject" $EMAIL
log "已发送邮件告警: $domain"
}
# 主检查函数
check_certificates() {
for domain in "${DOMAINS[@]}"; do
# 获取证书过期时间
expiry_date=$(echo | openssl s_client -servername $domain -connect $domain:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
if [ -z "$expiry_date" ]; then
log "警告: 无法获取 $domain 的证书信息"
continue
fi
# 计算剩余天数
expiry_timestamp=$(date -d "$expiry_date" +%s)
current_timestamp=$(date +%s)
remaining_days=$(( ($expiry_timestamp - $current_timestamp) / 86400 ))
log "$domain - 剩余天数: $remaining_days"
# 如果剩余天数小于阈值,发送告警
if [ $remaining_days -le $WARNING_DAYS ]; then
send_email_alert "$domain" "$remaining_days" "$expiry_date"
fi
done
}
# 执行检查
check_certificates
使用方法
保存脚本
# 保存为 ssl_monitor.sh nano ssl_monitor.sh
添加执行权限
chmod +x ssl_monitor.sh
手动运行
./ssl_monitor.sh
配置Crontab定时检查
# 编辑crontab crontab -e # 添加以下内容(每天凌晨2点检查) 0 2 * * * /path/to/ssl_monitor.sh # 或每12小时检查一次 0 */12 * * * /path/to/ssl_monitor.sh
安装必要的工具
# Ubuntu/Debian sudo apt-get install openssl mailutils # CentOS/RHEL sudo yum install openssl mailx
注意事项
- 依赖检查: 确保系统安装了openssl
- 端口变化: 某些服务可能使用非443端口
- SNI支持: 对于多域名服务器需要SNI支持
- 时区设置: 注意系统时区可能影响时间计算
- 错误处理: 添加适当的错误处理机制
- 日志记录: 保存详细的检查日志用于排查
这些脚本可以根据具体需求进行定制和扩展。