监控SSL证书有效期的脚本如何写

wen 实用脚本 10

本文目录导读:

监控SSL证书有效期的脚本如何写

  1. 方案一:基础Bash脚本(Linux/Unix)
  2. 方案二:批量监控脚本
  3. 方案三:Python脚本(更灵活)
  4. 方案四:Crontab定时监控
  5. 使用示例
  6. 扩展建议

我来为您提供几个不同场景下监控SSL证书有效期的脚本方案:

基础Bash脚本(Linux/Unix)

#!/bin/bash
# SSL证书监控脚本
# 使用方法:./ssl_monitor.sh example.com
DOMAIN=$1
WARNING_DAYS=30
CRITICAL_DAYS=7
EMAIL="admin@example.com"
# 检查域名参数
if [ -z "$DOMAIN" ]; then
    echo "用法: $0 <域名>"
    echo "示例: $0 example.com"
    exit 1
fi
# 获取证书过期日期
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
    echo "错误:无法获取 $DOMAIN 的SSL证书信息"
    exit 2
fi
# 计算剩余天数
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
CURRENT_EPOCH=$(date +%s)
REMAINING_DAYS=$(( ($EXPIRY_EPOCH - CURRENT_EPOCH) / 86400 ))
echo "域名: $DOMAIN"
echo "证书过期日期: $EXPIRY_DATE"
echo "剩余天数: $REMAINING_DAYS 天"
# 发送警告
if [ $REMAINING_DAYS -le $CRITICAL_DAYS ]; then
    echo "⚠️  严重警告:证书将在 $REMAINING_DAYS 天内过期!"
    # 发送邮件通知(需要配置mail命令)
    # echo "SSL证书将在 $REMAINING_DAYS 天内过期" | mail -s "严重: $DOMAIN SSL证书即将过期" $EMAIL
elif [ $REMAINING_DAYS -le $WARNING_DAYS ]; then
    echo "⚠️  警告:证书将在 $REMAINING_DAYS 天内过期"
    # echo "SSL证书将在 $REMAINING_DAYS 天内过期" | mail -s "警告: $DOMAIN SSL证书即将过期" $EMAIL
fi
exit 0

批量监控脚本

#!/bin/bash
# 批量SSL证书监控脚本
DOMAINS_FILE="domains.txt"
WARNING_DAYS=30
CRITICAL_DAYS=7
# 检查域名文件
if [ ! -f "$DOMAINS_FILE" ]; then
    echo "错误:找不到域名列表文件 $DOMAINS_FILE"
    echo "请创建文件,每行一个域名"
    exit 1
fi
# 创建报告文件
REPORT_FILE="ssl_report_$(date +%Y%m%d).txt"
echo "SSL证书监控报告 - $(date)" > $REPORT_FILE
echo "=========================================" >> $REPORT_FILE
# 逐行读取域名
while IFS= read -r domain; do
    # 跳过空行和注释
    [[ -z "$domain" || "$domain" == \#* ]] && continue
    echo "检查: $domain"
    # 获取证书信息
    EXPIRY_DATE=$(echo | openssl s_client -servername $domain -connect $domain:443 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
    if [ -z "$EXPIRY_DATE" ]; then
        echo "错误: 无法获取 $domain 的证书信息" >> $REPORT_FILE
        continue
    fi
    # 计算剩余天数
    EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s 2>/dev/null)
    CURRENT_EPOCH=$(date +%s)
    if [ -z "$EXPIRY_EPOCH" ]; then
        echo "错误: 日期格式转换失败 - $domain" >> $REPORT_FILE
        continue
    fi
    REMAINING_DAYS=$(( ($EXPIRY_EPOCH - CURRENT_EPOCH) / 86400 ))
    # 输出结果
    echo "$domain | 过期: $EXPIRY_DATE | 剩余: $REMAINING_DAYS 天" >> $REPORT_FILE
    # 状态判断
    if [ $REMAINING_DAYS -le 0 ]; then
        echo "⚠️  已过期: $domain"
    elif [ $REMAINING_DAYS -le $CRITICAL_DAYS ]; then
        echo "🔴 严重: $domain"
    elif [ $REMAINING_DAYS -le $WARNING_DAYS ]; then
        echo "🟡 警告: $domain"
    else
        echo "🟢 正常: $domain"
    fi
done < "$DOMAINS_FILE"
echo "=========================================" >> $REPORT_FILE
echo "报告已保存到: $REPORT_FILE"

Python脚本(更灵活)

#!/usr/bin/env python3
import ssl
import socket
import datetime
import sys
import argparse
def check_ssl_expiry(hostname, port=443):
    """检查SSL证书过期日期"""
    try:
        context = ssl.create_default_context()
        with socket.create_connection((hostname, port), timeout=10) as sock:
            with context.wrap_socket(sock, server_hostname=hostname) as ssock:
                cert = ssock.getpeercert()
                # 获取过期日期
                expiry_date = datetime.datetime.strptime(
                    cert['notAfter'], '%b %d %H:%M:%S %Y %Z'
                )
                remaining_days = (expiry_date - datetime.datetime.now()).days
                return {
                    'domain': hostname,
                    'expiry_date': expiry_date,
                    'remaining_days': remaining_days,
                    'issuer': dict(cert['issuer'][0]),
                    'subject': dict(cert['subject'][0])
                }
    except Exception as e:
        return {'domain': hostname, 'error': str(e)}
def main():
    parser = argparse.ArgumentParser(description='SSL证书有效期监控工具')
    parser.add_argument('domains', nargs='+', help='要检查的域名')
    parser.add_argument('-w', '--warning', type=int, default=30, help='警告天数')
    parser.add_argument('-c', '--critical', type=int, default=7, help='严重警告天数')
    args = parser.parse_args()
    print(f"{'域名':<30} {'状态':<10} {'过期日期':<25} {'剩余天数':<10} {'签发者':<30}")
    print("="*105)
    for domain in args.domains:
        result = check_ssl_expiry(domain)
        if 'error' in result:
            print(f"{result['domain']:<30} {'错误':<10} {result['error']:<55}")
            continue
        remaining = result['remaining_days']
        if remaining <= 0:
            status = "已过期"
            status_color = "\033[91m"  # 红色
        elif remaining <= args.critical:
            status = "严重"
            status_color = "\033[91m"
        elif remaining <= args.warning:
            status = "警告"
            status_color = "\033[93m"  # 黄色
        else:
            status = "正常"
            status_color = "\033[92m"  # 绿色
        issuer = result['issuer'].get('commonName', 'Unknown')
        expiry_str = result['expiry_date'].strftime('%Y-%m-%d %H:%M:%S')
        print(f"{result['domain']:<30} {status_color}{status:<10}\033[0m {expiry_str:<25} {remaining:<10} {issuer:<30}")
if __name__ == "__main__":
    main()

Crontab定时监控

创建定时任务配置:

# 编辑crontab
crontab -e
# 添加以下行(每天检查一次)
0 9 * * * /path/to/ssl_monitor.sh example.com >> /var/log/ssl_monitor.log 2>&1
# 或每6小时检查一次
0 */6 * * * /path/to/ssl_monitor_batch.sh

使用示例

# Bash脚本使用
chmod +x ssl_monitor.sh
./ssl_monitor.sh google.com
# Python脚本使用
chmod +x ssl_monitor.py
python3 ssl_monitor.py google.com github.com -w 30 -c 7
# 批量检查
echo "google.com
github.com
stackoverflow.com" > domains.txt
./ssl_monitor_batch.sh

扩展建议

  1. 邮件通知:集成sendmail或mailx
  2. Webhook通知:发送到Slack、钉钉等
  3. 日志记录:使用syslog或文本文件
  4. 可视化:将结果输出为HTML或JSON格式
  5. 多端口支持:支持8443等其他端口

您可以根据实际需求选择适合自己的方案,并结合crontab实现自动化监控。

抱歉,评论功能暂时关闭!