本文目录导读:

我来为您提供几个不同场景下监控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
扩展建议
- 邮件通知:集成sendmail或mailx
- Webhook通知:发送到Slack、钉钉等
- 日志记录:使用syslog或文本文件
- 可视化:将结果输出为HTML或JSON格式
- 多端口支持:支持8443等其他端口
您可以根据实际需求选择适合自己的方案,并结合crontab实现自动化监控。