脚本如何检测SSL证书过期

wen 实用脚本 1

本文目录导读:

脚本如何检测SSL证书过期

  1. 使用 OpenSSL 命令行(通用、适合监控脚本)
  2. Python 脚本(更灵活,适合集成到系统)
  3. Node.js 脚本(适合 Web 开发环境)
  4. 本地 PEM 文件检测
  5. 生产级监控建议

检测SSL证书过期主要有两种场景:服务端主动检查(如监测自己网站的证书)和客户端被动检查(如浏览器访问时),下面提供几种常见语言和工具的脚本实现。

使用 OpenSSL 命令行(通用、适合监控脚本)

这是最直接的方法,通过 openssl s_client 获取证书信息并解析过期时间。

#!/bin/bash
# 检查域名证书过期时间
DOMAIN="example.com"
PORT=443
# 获取证书过期时间,并转换为时间戳
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 "证书过期时间: $expiry_date"
echo "剩余天数: $remaining_days"
# 如果剩余天数小于30天,发出警报
if [ $remaining_days -lt 30 ]; then
    echo "警告:证书将在 $remaining_days 天后过期!"
fi

增强版(支持多域名、发送通知):

#!/bin/bash
check_cert() {
    local domain=$1 port=${2:-443}
    local expiry_date expiry_timestamp current_timestamp remaining_days
    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: 剩余 $remaining_days 天"
    [ $remaining_days -lt 30 ] && echo "⚠️ 警告:$domain 证书即将过期!"
}
# 批量检查
for site in "google.com" "github.com" "your-domain.com"; do
    check_cert "$site"
done

Python 脚本(更灵活,适合集成到系统)

Python 的 sslsocketdatetime 模块可以轻松完成。

import ssl
import socket
import datetime
def check_cert_expiry(hostname, port=443):
    """检查指定域名的SSL证书过期时间"""
    context = ssl.create_default_context()
    try:
        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_str = cert['notAfter']
                expiry_date = datetime.datetime.strptime(expiry_date_str, '%b %d %H:%M:%S %Y %Z')
                # 计算剩余天数
                now = datetime.datetime.now()
                remaining_days = (expiry_date - now).days
                print(f"[{hostname}]")
                print(f"  证书颁发给: {cert['subject'][0][0][1] if cert['subject'] else 'N/A'}")
                print(f"  过期时间: {expiry_date}")
                print(f"  剩余天数: {remaining_days}")
                return remaining_days
    except Exception as e:
        print(f"检查 {hostname} 时出错: {e}")
        return None
# 使用示例
if __name__ == "__main__":
    domains = ["example.com", "google.com", "github.com"]
    for domain in domains:
        days_left = check_cert_expiry(domain)
        if days_left is not None and days_left < 30:
            print(f"  ⚠️ 警告:{domain} 的证书将在 {days_left} 天后过期!")
        print("-" * 50)

Node.js 脚本(适合 Web 开发环境)

利用 tls 模块直接获取证书。

const tls = require('tls');
function checkSSLCert(hostname, port = 443) {
    return new Promise((resolve, reject) => {
        const socket = tls.connect(port, hostname, { servername: hostname }, () => {
            const cert = socket.getPeerCertificate();
            const expiryDate = new Date(cert.valid_to);
            const now = new Date();
            const remainingDays = Math.floor((expiryDate - now) / (1000 * 60 * 60 * 24));
            console.log(`主机: ${hostname}`);
            console.log(`颁发给: ${cert.subject.CN}`);
            console.log(`过期时间: ${expiryDate}`);
            console.log(`剩余天数: ${remainingDays}`);
            if (remainingDays < 30) {
                console.warn(`⚠️ 证书将在 ${remainingDays} 天后过期!`);
            }
            socket.end();
            resolve(remainingDays);
        });
        socket.on('error', (err) => {
            console.error(`连接失败: ${err.message}`);
            reject(err);
        });
    });
}
// 使用
checkSSLCert('example.com');

本地 PEM 文件检测

如果你有证书文件(如 .pem.crt),可以直接离线解析。

OpenSSL 方式:

openssl x509 -in /path/to/certificate.pem -noout -enddate

Python 方式:

import ssl
import datetime
with open('/path/to/certificate.pem', 'rb') as f:
    cert_data = f.read()
cert = ssl.PEM_cert_to_DER_cert(cert_data.decode('utf-8'))
# 注意:Python标准库没有直接解析DER证书的轻量方法,推荐使用cryptography库

生产级监控建议

  • 定时任务:将检测脚本加入 cron(Linux)或 Task Scheduler(Windows),每日执行一次。
  • 告警集成:结合邮件、Slack、钉钉等发送通知。
  • 证书透明日志:使用 certbot 等工具自动续期。
  • 专业工具:考虑使用 Let's EncryptCertbot(自动续期)、Nagios/Zabbix(企业监控)。

脚本可帮助你快速检测 SSL 证书是否即将过期,根据你的技术栈和环境选择最适合的实现方式即可。

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