首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Python 自动检测服务HTTPS证书过期时间并发送预警

Python 自动检测服务HTTPS证书过期时间并发送预警

作者头像
用户11081884
发布2026-07-20 19:22:41
发布2026-07-20 19:22:41
240
举报

互联网服务中HTTPS 证书是保障数据传输安全的关键组件。一旦证书过期,将导致服务中断、浏览器安全警告等问题,严重影响用户体验和业务连续性。手动跟踪多个服务的证书有效期不仅繁琐,而且容易遗漏。本文介绍如何使用 Python 自动检测 HTTPS 证书的过期时间,并在证书即将过期时发送预警通知,实现运维流程的自动化与智能化。

应用场景

  • 企业运维管理:运维团队需要集中监控公司官网、API 服务、内部系统等多个服务的证书状态,确保持续可用。
  • 云服务与 SaaS 提供商:服务商需确保自身平台及为客户提供的服务证书有效,避免因证书问题导致的服务不可用,维护品牌信誉。
  • 个人开发者与小型团队:管理个人项目、博客或小型企业网站的证书,在证书到期前及时收到提醒,避免因疏忽导致服务中断。
  • 合规与审计要求:满足金融、医疗等行业对系统安全性和业务连续性的定期检查与合规要求。

通过自动化检测,运维人员可以从重复性的检查工作中解放出来,将精力集中于处理预警和解决实际问题,提升整体运维效率。

核心思路与使用说明

本方案的核心是编写一个 Python 脚本,其工作流程如下:

1、获取证书信息:向目标 URL 发起 HTTPS 请求,从 SSL/TLS 握手信息中提取证书的过期时间。

2、计算剩余天数:将证书过期时间与当前时间比较,计算出剩余有效天数。

3、判断与预警:将剩余天数与预设的预警阈值(例如 30 天)进行比较。若剩余天数小于等于阈值,则触发预警流程。

4、发送通知:通过配置好的通知渠道(如邮件、企业微信、钉钉、Slack 等)发送包含详细预警信息的消息。

使用说明

1、环境准备:确保运行脚本的设备安装有 Python 3.6 及以上版本,并能够访问互联网以连接目标服务。

2、安装依赖:本示例脚本仅使用 Python 标准库,无需额外安装依赖。若需扩展其他通知渠道,可根据需要安装相应第三方库。

3、配置脚本:修改脚本中的配置部分,包括目标 URL 列表、预警阈值、通知渠道的认证信息等。

4、部署与运行:

  • 手动运行:在本地或服务器上直接执行脚本进行一次性检查。
  • 定时任务:利用系统的 cron(Linux)或计划任务(Windows)功能,将脚本设置为定时任务(例如每天运行一次),实现持续监控。
  • 集成到 CI/CD:在持续集成/持续部署流水线中增加证书检查环节,确保上线服务的证书状态健康。

代码示例

以下是一个基础版本的 Python 脚本示例,实现了证书过期检测并通过电子邮件发送预警的功能。

代码语言:javascript
复制
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
HTTPS 证书过期时间自动检测与邮件预警脚本
"""

import ssl
import socket
from datetime import datetime
import smtplib
from email.mime.text import MIMEText
from email.header import Header
from typing import List, Tuple

# ============ 用户配置区域 ============
# 需要监控的域名列表
DOMAINS_TO_CHECK = [
    " www.example.com ",
    "api.example.com",
    "blog.example.org",
]
# 预警阈值(天):证书剩余有效期少于等于此值时触发预警
WARNING_THRESHOLD_DAYS = 30
# 邮件服务器配置
SMTP_SERVER = "smtp.office365.com"  # 例如:smtp.gmail.com, smtp.qq.com
SMTP_PORT = 587
SENDER_EMAIL = "your_monitor@example.com"
SENDER_PASSWORD = "your_app_password"  # 注意:建议使用应用专用密码,而非邮箱登录密码
RECIPIENT_EMAILS = ["admin@example.com", "ops@example.com"]
# ============ 配置结束 ============

def get_cert_expiry_date(hostname: str, port: int = 443) -> datetime:
    """
    获取指定主机和端口的 SSL 证书过期日期。

    Args:
        hostname: 目标主机名
        port: 端口号,默认为 443

    Returns:
        datetime: 证书过期时间(UTC)
    """
    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()
            # 证书中的日期格式为:'Aug 28 12:00:00 2025 GMT'
            expire_str = cert['notAfter']
            # 解析字符串为 datetime 对象
            expire_date = datetime.strptime(expire_str, '%b %d %H:%M:%S %Y %Z')
            return expire_date

def check_domains(domains: List[str]) -> List[Tuple[str, datetime, int]]:
    """
    检查域名列表,返回需要预警的域名及其信息。

    Args:
        domains: 待检查的域名列表

    Returns:
        List[Tuple]: 每个元素为 (域名, 过期时间, 剩余天数) 的元组,仅包含需要预警的域名。
    """
    warning_list = []
    current_time = datetime.utcnow()

    for domain in domains:
        try:
            expiry_date = get_cert_expiry_date(domain)
            days_left = (expiry_date - current_time).days
            print(f"[INFO] 域名: {domain:20s} 过期时间: {expiry_date.date()} 剩余天数: {days_left:3d}")

            if days_left <= WARNING_THRESHOLD_DAYS:
                warning_list.append((domain, expiry_date, days_left))
        except socket.gaierror:
            print(f"[ERROR] 无法解析域名: {domain}")
        except (socket.timeout, ConnectionRefusedError, ssl.SSLError) as e:
            print(f"[ERROR] 连接 {domain} 失败: {e}")
        except Exception as e:
            print(f"[ERROR] 检查 {domain} 时发生未知错误: {e}")

    return warning_list

def send_warning_email(warning_list: List[Tuple[str, datetime, int]]) -> None:
    """
    发送证书过期预警邮件。

    Args:
        warning_list: 由 check_domains 函数生成的预警列表。
    """
    if not warning_list:
        print("[INFO] 没有证书需要预警,邮件未发送。")
        return

    # 构建邮件正文
    email_body_lines = ["【重要】HTTPS 证书过期预警通知\n"]
    email_body_lines.append(f"以下服务的 SSL/TLS 证书将在 {WARNING_THRESHOLD_DAYS} 天内过期,请及时处理!\n")
    email_body_lines.append("-" * 50)
    for domain, expiry_date, days_left in warning_list:
        email_body_lines.append(f"域名: {domain}")
        email_body_lines.append(f"过期时间: {expiry_date.strftime('%Y-%m-%d %H:%M:%S UTC')}")
        email_body_lines.append(f"剩余天数: {days_left} 天\n")

    email_body_lines.append("-" * 50)
    email_body_lines.append(f"生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
    email_body = "\n".join(email_body_lines)

    # 构建邮件
    subject = f"HTTPS 证书过期预警 ({len(warning_list)} 个服务)"
    msg = MIMEText(email_body, 'plain', 'utf-8')
    msg['From'] = Header(f"证书监控系统 <{SENDER_EMAIL}>", 'utf-8')
    msg['To'] = Header(",".join(RECIPIENT_EMAILS), 'utf-8')
    msg['Subject'] = Header(subject, 'utf-8')

    # 发送邮件
    try:
        with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
            server.starttls()  # 启用 TLS 加密
            server.login(SENDER_EMAIL, SENDER_PASSWORD)
            server.sendmail(SENDER_EMAIL, RECIPIENT_EMAILS, msg.as_string())
        print(f"[SUCCESS] 预警邮件已发送至 {RECIPIENT_EMAILS}")
    except Exception as e:
        print(f"[FAILED] 邮件发送失败: {e}")

def main():
    """主函数"""
    print("=" * 60)
    print("开始执行 HTTPS 证书过期检查...")
    print("=" * 60)

    # 1. 检查所有配置的域名
    need_warning_domains = check_domains(DOMAINS_TO_CHECK)

    # 2. 如果有需要预警的域名,则发送邮件
    if need_warning_domains:
        send_warning_email(need_warning_domains)
    else:
        print("[INFO] 所有证书状态正常,无需预警。")

    print("=" * 60)
    print("检查完成。")
    print("=" * 60)

if __name__ == "__main__":
    main()

代码要点说明

  • 核心函数 get_cert_expiry_date:使用 Python 标准库 sslsocket 建立安全的 TLS 连接,并直接从连接中获取对等方的证书信息,解析出过期时间。这种方法无需安装额外依赖(如 requests),更加轻量且高效。
  • 监控与判断逻辑 check_domains:遍历所有配置的域名,获取其证书过期时间,计算剩余天数,并与阈值比较。该函数还包含了基本的错误处理(如网络错误、域名解析失败),增强了脚本的健壮性。
  • 通知模块 send_warning_email:使用 smtplibemail 库构建并发送预警邮件。邮件内容清晰列出了每个预警域名的详细信息,便于接收者快速定位问题。
  • 配置灵活:所有需要用户自定义的参数(域名列表、预警阈值、邮件服务器信息等)都集中在脚本开头的配置区域,结构清晰,修改方便。
  • 错误处理与日志:脚本在执行过程中会输出不同级别的日志信息(INFO、ERROR、SUCCESS等),便于运行状态监控、问题调试与结果追溯。

此脚本是一个基础框架,你可以根据实际需求进行功能扩展,通过将此脚本部署为定时任务,可以构建一个低成本、高效率、可扩展的 HTTPS 证书自动监控系统,为服务的稳定运行与安全合规增添一道重要的自动化保障。

“无他,惟手熟尔”!有需要的用起来!

如果你觉得这篇文章有用,欢迎点赞、转发、收藏、留言、推荐❤!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-01-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Nicholas与Pypi 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 应用场景
  • 核心思路与使用说明
    • 使用说明
  • 代码示例
    • 代码要点说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档