编写Python脚本监控域名ssl证书过期时间并在10天内发送邮件

依赖aliyun的邮件推送服务

1、安装依赖包

pip3 install alibabacloud_dm20151123

2、编写配置文件config.json

{"alibaba_cloud": {"access_key_id": "XXXXXXXXXXXXXXXXXXX","access_key_secret": "XXXXXXXXXXXXXXXX","region_id": "ap-southeast-1","endpoint": "dm.ap-southeast-1.aliyuncs.com"},"email": {"from_address": "abc@XXXX.com","to_address": ["acdtf92@gmail.com","segrd@let.vet"]},"ssl": {"domains": ["ase.abc.com","ase.abc.cn:8443"]}
}

3、脚本正文

import json
import ssl
import socket
from datetime import datetime
from alibabacloud_dm20151123.client import Client as Dm20151123Client
from alibabacloud_tea_openapi import models as open_api_models
from alibabacloud_dm20151123 import models as dm_20151123_models
from alibabacloud_tea_util import models as util_models# 读取配置文件
def load_config(file_path: str) -> dict:with open(file_path, 'r') as f:return json.load(f)def get_ssl_cert_expiry_date(host_with_port: str) -> datetime:try:# 处理主机和端口,默认端口是 443if ':' in host_with_port:host, port = host_with_port.split(':')port = int(port)else:host = host_with_portport = 443context = ssl.create_default_context()with socket.create_connection((host, port)) as sock:with context.wrap_socket(sock, server_hostname=host) as ssock:cert = ssock.getpeercert()expiry_date_str = cert['notAfter']expiry_date = datetime.strptime(expiry_date_str, '%b %d %H:%M:%S %Y GMT')return expiry_dateexcept Exception as e:# 记录错误,但不发送邮件print(f"Error retrieving SSL certificate for {host_with_port}: {e}")return Noneclass Sample:@staticmethoddef create_client(config: dict) -> Dm20151123Client:alibaba_cloud_config = config['alibaba_cloud']client_config = open_api_models.Config(access_key_id=alibaba_cloud_config['access_key_id'],access_key_secret=alibaba_cloud_config['access_key_secret'])client_config.endpoint = alibaba_cloud_config['endpoint']return Dm20151123Client(client_config)@staticmethoddef send_email(config: dict, subject: str, body: str) -> None:client = Sample.create_client(config)email_config = config['email']to_addresses = ','.join(email_config['to_address'])  # 将多个地址合并为逗号分隔的字符串single_send_mail_request = dm_20151123_models.SingleSendMailRequest(account_name=email_config['from_address'],to_address=to_addresses,subject=subject,html_body=body,reply_to_address=True,address_type=1  # Added AddressType parameter)runtime = util_models.RuntimeOptions()try:response = client.single_send_mail_with_options(single_send_mail_request, runtime)print(f"Email sent successfully: {response}")except Exception as error:# 记录错误,但不将错误信息发送到邮件中print(f"Error sending email: {error.message}")@staticmethoddef main() -> None:config = load_config('config.json')ssl_config = config['ssl']domains = ssl_config['domains']for domain in domains:expiry_date = get_ssl_cert_expiry_date(domain)if expiry_date:days_remaining = (expiry_date - datetime.now()).daysif days_remaining <= 10:subject = f"SSL Certificate Expiry Warning for {domain}"body = f"SSL certificate for {domain} will expire on {expiry_date.strftime('%Y-%m-%d %H:%M:%S')}. Only {days_remaining} days remaining."Sample.send_email(config, subject, body)elif days_remaining < 0:subject = f"SSL Certificate Expired for {domain}"body = f"SSL certificate for {domain} expired on {expiry_date.strftime('%Y-%m-%d %H:%M:%S')}. It has been expired for {-days_remaining} days."Sample.send_email(config, subject, body)else:# 记录证书检索错误,但不发送邮件print(f"Skipping {domain} due to SSL certificate retrieval error.")if __name__ == '__main__':Sample.main()

4、执行结果

# /usr/bin/python3 ssl_spirtime.py --config-file config.json
Error retrieving SSL certificate for biking999.com: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: certificate has expired (_ssl.c:1131)
Skipping bidd999.com due to SSL certificate retrieval error.
Email sent successfully: {'headers': {'date': 'Wed, 18 Sep 2024 07:36:36 GMT', 'content-type': 'application/json;charset=utf-8', 'content-length': '82', 'connection': 'keep-alive', 'keep-alive': 'timeout=25', 'access-control-allow-origin': '*', 'access-control-expose-headers': '*', 'x-acs-request-id': 'D2D4F3A9-DFA3-3BF4-8CA1-1EAF53925294', 'x-acs-trace-id': 'dfa8887a84c0eec8eb4fdb464b1d8f58', 'etag': '8uOlvXmQYUyBJKzVwsfMCGA2'}, 'statusCode': 200, 'body': {'EnvId': '8000000005879627107', 'RequestId': 'D2D4F3A9-DFA3-3BF4-8CA1-1EAF53925294'}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/54525.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GPU 云与 GenAI :DigitalOcean 在 AI 平台与应用方向的技术规划

在 DigitalOcean&#xff0c;我们不仅在观察人工智能革命&#xff0c;而且还在积极参与这场技术革命。 去年&#xff0c;我们进行了一项关键的收购以扩展平台的人工智能能力&#xff0c;扩大了对曾经仅限于大型企业的 AI/ML 开发工具的访问。在2024年7月由 DigitalOcean 主办的…

C++:多态(协变,override,final,纯虚函数抽象类,原理)

目录 编译时多态 函数重载 模板 运行时多态 多态的实现 实现多态的条件 协变 析构函数的重写 override 关键字 final 关键字 重载、重写、隐藏对比 纯虚函数和抽象类 多态的原理 多态是什么&#xff1f; 多态就是有多种形态 多态有两种&#xff0c;分别是编译时…

使用Go语言的互斥锁(Mutex)解决并发问题

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在并发编程中,由于存在竞争条件和数据竞争,我们需要将某些代码片段设定为临界区,并使用互斥锁(Mutex)等同步原语来保护这些临界区。本文将详细介绍Go语言标准库中Mutex的使用方法,以及如何利用它来解决实际…

Linux驱动开发 ——架构体系

只读存储器&#xff08;ROM&#xff09; 1.作用 这是一种非易失性存储器&#xff0c;用于永久存储数据和程序。与随机存取存储器&#xff08;RAM&#xff09;不同&#xff0c;ROM中的数据在断电后不会丢失&#xff0c;通常用于存储固件和系统启动程序。它的内容在制造时或通过…

Java基础面试题——异常

目录 关系图 1. Throwable和Exception之间的关系 2.异常分为哪两大类 3.常见的 RuntimeException 4. 常见的 Error 5.什么是已检查异常和未检查异常&#xff1f;它们的区别是什么&#xff1f; 6.Java 中如何自定义异常&#xff1f; 7.throw 和 throws 的区别是什么&…

ubuntu18.04升级到20.04

要将 Ubuntu 18.04 升级到 Ubuntu 20.04&#xff0c;你可以按照以下步骤进行操作。升级操作会涉及到系统的核心部分&#xff0c;建议在升级之前备份重要数据。 1. 备份数据 在进行系统升级之前&#xff0c;请确保备份重要的数据。可以使用 rsync、tar、或者系统备份工具来创建…

GlusterFS 分布式文件系统

一、GlusterFS 概述 1.1 什么是GlusterFS GlusterFS 是一个开源的分布式文件系统&#xff0c;它可以将多个存储服务器结合在一起&#xff0c;创建一个大的存储池&#xff0c;供客户端使用。它不需要单独的元数据服务器&#xff0c;这样可以提高系统的性能和可靠性。由于没有…

视频转文字工具:开启视频内容深度挖掘的钥匙

图片里到文字要提取出来&#xff0c;现在有很多的工具&#xff0c;但是视频里的文字要提取出来&#xff0c;是不是就不那么好操作呢&#xff1f;并不是的&#xff0c;现在也有不少支持视频转文字的工具&#xff0c;这次我们就来介绍一些可以提高我们视频文字提取效率的工具吧。…

速盾:凡科建站开cdn了吗?

凡科建站是一家专业的建站平台&#xff0c;提供了多种功能和工具来帮助用户快速搭建自己的网站。随着互联网技术的不断发展&#xff0c;网站的访问速度和稳定性成为了越来越重要的考虑因素。为了优化用户体验&#xff0c;提高网站的加载速度&#xff0c;凡科建站已经开启了CDN&…

经典sql题(八)SQL 查询详细指南总结一

SQL 查询详细指南 SQL&#xff08;Structured Query Language&#xff09;是一种用于管理和操作关系数据库的标准语言。本文将详细介绍 SQL 中的一些常见操作及其用法&#xff0c;包括 DISTINCT 去重、LIMIT 限制、排序、开窗函数、NULL 值替换、JOIN 与 UNION 等。 1. DISTI…

大话Python|基础语法(上)

一、单行注释 以下代码输出一个Hello World&#xff01;字符串 在Python代码中&#xff0c;注释会自动被Python解析器忽略 print(Hello World) 二、多行注释 在Python代码中&#xff0c;注释一共有两种形式&#xff1b; 1、单行注释&#xff1a;注释的内容只有一行 2、多行…

计算机网络笔记001

讲义 1.计算机网络的定义  定义&#xff1a; 一批独立自治的计算机系统的互连集合体  说明&#xff1a; 独立自治的计算机系统&#xff0c; 互连的手段是各种各样的&#xff0c; 依据协议进行 工作  2.计算机网络和通信网络  通信网络&#xff1a; 重点研究通…

element plus 按需导入vue

步骤一&#xff1a; 下载element plus 在打开vue项目的编辑器中打开终端&#xff0c;或者在cmd窗口进入到项目目录下 用你的包管理器安装element plus,例如使用npm包管理器&#xff1a; npm install element-plus --save 查看是否安装成功&#xff1a;查看项目文件package…

PostgreSQL(PG)(二十二)

&#x1f33b;&#x1f33b; 目录 &#x1f33b;&#x1f33b; 一、PostgreSQL 简介1.1、PG 的历史1.2、PG的社区1.2.1 纯社区1.2.2 完善的组织结构1.2.3 开源许可独特性 1.3 、PostgreSQL与MySQL的比较 二、PostgresQL的下载安装2.1、Windows上安装 PostgreSQL2.2、远程 连接 …

RK3568部署DOCKER启动服务器失败解决办法

按照上文的方法部署完DOCKER之后&#xff0c;启动服务异常&#xff0c;查阅网络相关资源&#xff0c;解决方案如下&#xff1a; 修改/源码/kernel/arch/arm64/configs/OK3568-C-linux_defconfig&#xff0c;在最后添加 CONFIG_MEMCGy CONFIG_VETHy CONFIG_BRIDGEy CONFIG_BRID…

php怎么连接使用kafka

PHP 连接并使用 Kafka 需要借助 Kafka 的 PHP 客户端库&#xff0c;比如流行的 php-rdkafka 扩展。它是基于 C 语言的 librdkafka 库的 PHP 绑定&#xff0c;功能稳定且性能高。下面是如何使用 php-rdkafka 来连接和使用 Kafka 的步骤。 1. 安装 php-rdkafka 1.1 安装依赖 首…

GS-SLAM论文阅读笔记--TAMBRIDGE

前言 本文提出了一个自己的分类方法&#xff0c;传统的视觉SLAM通常使用以帧为中心的跟踪方法&#xff0c;但是3DGS作为一种高效的地图表达方法好像更侧重于地图的创建。这两种方法都有各自的优缺点&#xff0c;但是如果能取长补短&#xff0c;互相结合&#xff0c;那么就会是…

6.7泊松噪声

基础概念 在OpenCV联合C中给一张图片添加泊松噪声&#xff08;Poisson Noise&#xff09;可以通过生成随机数并在图像的每个像素上加上这些随机数来实现。泊松噪声是一种统计分布服从泊松分布的噪声&#xff0c;通常用于模拟光子计数等场景。 使用泊松噪声的场景 泊松噪声通…

【解决】chrome 谷歌浏览器,鼠标点击任何区域都是 Input 输入框的状态,能看到输入的光标

chrome 谷歌浏览器&#xff0c;鼠标点击任何区域都是 Input 输入框的状态&#xff0c;能看到输入的光标 今天打开电脑的时候&#xff0c;网页中任何文本的地方&#xff0c;只要鼠标点击&#xff0c;就会出现一个输入的光标&#xff0c;无论在哪个站点哪个页面都是如此。 我知道…

Pandas 数据分析入门详解

今日内容大纲介绍 DataFrame读写文件 DataFrame加载部分数据 DataFrame分组聚合计算 DataFrame常用排序方式 1.DataFrame-保存数据到文件 格式 df对象.to_数据格式(路径) ​ # 例如: df.to_csv(data/abc.csv) 代码演示 如要保存的对象是计算的中间结果&#xff0c;或者以…