本文目录导读:

检测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 的 ssl、socket 和 datetime 模块可以轻松完成。
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 Encrypt、Certbot(自动续期)、Nagios/Zabbix(企业监控)。
脚本可帮助你快速检测 SSL 证书是否即将过期,根据你的技术栈和环境选择最适合的实现方式即可。