哈嘍大家好,我是鹹魚 之前寫了個 shell 版本的 SSL 證書過期巡檢腳本 (文章:《[SSL 證書過期巡檢腳本](https://mp.weixin.qq.com/s?__biz=MzkzNzI1MzE2Mw==&mid=2247486153&idx=1&sn=52911a79b77c11d7 ...
哈嘍大家好,我是鹹魚
之前寫了個 shell 版本的 SSL 證書過期巡檢腳本 (文章:《SSL 證書過期巡檢腳本》),後臺反響還是很不錯的
那麼今天鹹魚給大家介紹一下 python 版本的 SSL 證書過期巡檢腳本 (完整代碼在文末)
思路
導入相關模塊
import ssl
import socket
import time
from datetime import datetime
首先我們創建一個 domain.txt
用來存放要檢查的功能變數名稱和對應的 IP 地址
www.baidu.com:180.101.50.242,180.101.50.188
www.bing.com:202.89.233.101,202.89.233.100
我們讀取該文件,把裡面的功能變數名稱和對應的每個 ip 取出來,並存放到字典 domains
裡面
domains = {}
with open('domain.txt', 'r', encoding='utf-8') as file:
for line in file:
domain, ip_pool = line.strip().split(':')
domains[domain] = ip_pool.split(',')
取出來之後我們迴圈遍歷字典,去獲取每個功能變數名稱對應的證書信息(ssl_connect
函數)
def ssl_connect(domain, ip):
# 設置socket的超時時間為5秒
socket.setdefaulttimeout(5)
# 創建預設的SSL上下文
context = ssl.create_default_context()
# 創建一個SSL套接字
skt = context.wrap_socket(socket.socket(), server_hostname=domain)
try:
# 建立SSL連接
skt.connect((ip, 443))
# 獲取證書過期時間
end_date = skt.getpeercert()['notAfter'].strip(' GMT')
# 創建一個字典,存儲本次連接中的功能變數名稱、IP 地址和證書過期時間信息
skt_info = {'domain': domain, 'ip': ip, 'end_date': end_date}
except ssl.CertificateError as e:
cert = e
except socket.timeout:
cert = 'Connect refused'
except ConnectionResetError as e:
cert = 'Connect reset' + str(e)
except socket.gaierror as e:
cert = 'Connnect gaierror'
finally:
# 關閉SSL套接字
skt.close()
return skt_info
ssl_connect
函數返回一個字典 skt_info
,包含當前連接的功能變數名稱、ip 地址和證書過期時間
# skt_info 內容
{'domain': 'www.baidu.com', 'ip': '180.101.50.242', 'end_date': 'Aug 6 01:51:05 2024'}
{'domain': 'www.baidu.com', 'ip': '180.101.50.188', 'end_date': 'Aug 6 01:51:05 2024'}
{'domain': 'www.bing.com', 'ip': '202.89.233.101', 'end_date': 'Aug 16 03:47:45 2023'}
{'domain': 'www.bing.com', 'ip': '202.89.233.100', 'end_date': 'Aug 16 03:47:45 2023'}
然後我們調用 check_cert_time
函數進行證書有效期檢查和提示
info = [ssl_connect(domain, ip) for domain, ip_pool in domains.items() for ip in ip_pool]
[check_cert_time(i) for i in info]
check_cert_time
函數內容如下:
def check_cert_time(info):
# 獲取當前時間戳
current_timestamp = int(time.time())
# 將證書過期時間轉換成時間戳
date_object = datetime.strptime(info['end_date'], "%b %d %H:%M:%S %Y")
end_timestamp = int(date_object.timestamp())
# 計算剩餘天數
remain_day = (end_timestamp - current_timestamp) / 86400
# 列印功能變數名稱、IP 地址和證書過期時間信息
print(f"功能變數名稱:{info['domain']},ip 地址:{info['ip']},證書過期時間:{info['end_date']}")
# 根據剩餘天數進行不同的提示
# 如果證書過期時間減去當前時間的天數小於七天的話,則提示需要準備更換證書了
if 0 < remain_day < 7:
print('剩餘時間小於七天!請及時更換證書!')
elif remain_day < 0:
print('證書已過期!請及時更換證書!')
else:
print(f"剩餘天數為:{remain_day:.2f}天\n")
最後我們執行一下代碼,看看結果如何
完整代碼
import ssl
import socket
import time
from datetime import datetime
def ssl_connect(domain, ip):
# 設置socket的超時時間為5秒
socket.setdefaulttimeout(5)
# 創建預設的SSL上下文
context = ssl.create_default_context()
# 創建一個SSL套接字
skt = context.wrap_socket(socket.socket(), server_hostname=domain)
try:
# 建立SSL連接
skt.connect((ip, 443))
# 獲取證書過期時間
end_date = skt.getpeercert()['notAfter'].strip(' GMT')
# 創建一個字典,存儲本次連接中的功能變數名稱、IP 地址和證書過期時間信息
skt_info = {'domain': domain, 'ip': ip, 'end_date': end_date}
except ssl.CertificateError as e:
cert = e
except socket.timeout:
cert = 'Connect refused'
except ConnectionResetError as e:
cert = 'Connect reset' + str(e)
except socket.gaierror as e:
cert = 'Connnect gaierror'
finally:
# 關閉SSL套接字
skt.close()
return skt_info
def check_cert_time(info):
# 獲取當前時間戳
current_timestamp = int(time.time())
# 將證書過期時間轉換成時間戳
date_object = datetime.strptime(info['end_date'], "%b %d %H:%M:%S %Y")
end_timestamp = int(date_object.timestamp())
# 計算剩餘天數
remain_day = (end_timestamp - current_timestamp) / 86400
# 列印功能變數名稱、IP 地址和證書過期時間信息
print(f"功能變數名稱:{info['domain']},ip 地址:{info['ip']},證書過期時間:{info['end_date']}")
# 根據剩餘天數進行不同的提示
# 如果證書過期時間減去當前時間的天數小於七天的話,則提示需要準備更換證書了
if 0 < remain_day < 7:
print('剩餘時間小於七天!請及時更換證書!')
elif remain_day < 0:
print('證書已過期!請及時更換證書!')
else:
print(f"剩餘天數為:{remain_day:.2f}天\n")
if __name__ == "__main__":
domains = {}
with open('domain.txt', 'r', encoding='utf-8') as file:
for line in file:
domain, ip_pool = line.strip().split(':')
domains[domain] = ip_pool.split(',')
info = [ssl_connect(domain, ip) for domain, ip_pool in domains.items() for ip in ip_pool]
[check_cert_time(i) for i in info]