Python實(shí)現(xiàn)檢測SSL證書是否過期
之前寫了個 shell 版本的 SSL 證書過期巡檢腳本 (文章:《SSL 證書過期巡檢腳本》),后臺反響還是很不錯的
那么今天咸魚給大家介紹一下 python 版本的 SSL 證書過期巡檢腳本 (完整代碼在文末)
思路
導(dǎo)入相關(guān)模塊
import ssl import socket import time from datetime import datetime
首先我們創(chuàng)建一個 domain.txt 用來存放要檢查的域名和對應(yīng)的 IP 地址
www.baidu.com:180.101.50.242,180.101.50.188 www.bing.com:202.89.233.101,202.89.233.100
我們讀取該文件,把里面的域名和對應(yīng)的每個 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(',')取出來之后我們循環(huán)遍歷字典,去獲取每個域名對應(yīng)的證書信息(ssl_connect 函數(shù))
def ssl_connect(domain, ip):
# 設(shè)置socket的超時時間為5秒
socket.setdefaulttimeout(5)
# 創(chuàng)建默認(rèn)的SSL上下文
context = ssl.create_default_context()
# 創(chuàng)建一個SSL套接字
skt = context.wrap_socket(socket.socket(), server_hostname=domain)
try:
# 建立SSL連接
skt.connect((ip, 443))
# 獲取證書過期時間
end_date = skt.getpeercert()['notAfter'].strip(' GMT')
# 創(chuàng)建一個字典,存儲本次連接中的域名、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:
# 關(guān)閉SSL套接字
skt.close()
return skt_infossl_connect 函數(shù)返回一個字典 skt_info,包含當(dāng)前連接的域名、ip 地址和證書過期時間
# skt_info 內(nèi)容
{'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'}然后我們調(diào)用 check_cert_time 函數(shù)進(jìn)行證書有效期檢查和提示
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 函數(shù)內(nèi)容如下:
def check_cert_time(info):
# 獲取當(dāng)前時間戳
current_timestamp = int(time.time())
# 將證書過期時間轉(zhuǎn)換成時間戳
date_object = datetime.strptime(info['end_date'], "%b %d %H:%M:%S %Y")
end_timestamp = int(date_object.timestamp())
# 計(jì)算剩余天數(shù)
remain_day = (end_timestamp - current_timestamp) / 86400
# 打印域名、IP 地址和證書過期時間信息
print(f"域名:{info['domain']},ip 地址:{info['ip']},證書過期時間:{info['end_date']}")
# 根據(jù)剩余天數(shù)進(jìn)行不同的提示
# 如果證書過期時間減去當(dāng)前時間的天數(shù)小于七天的話,則提示需要準(zhǔn)備更換證書了
if 0 < remain_day < 7:
print('剩余時間小于七天!請及時更換證書!')
elif remain_day < 0:
print('證書已過期!請及時更換證書!')
else:
print(f"剩余天數(shù)為:{remain_day:.2f}天\n")最后我們執(zhí)行一下代碼,看看結(jié)果如何

完整代碼
import ssl
import socket
import time
from datetime import datetime
def ssl_connect(domain, ip):
# 設(shè)置socket的超時時間為5秒
socket.setdefaulttimeout(5)
# 創(chuàng)建默認(rèn)的SSL上下文
context = ssl.create_default_context()
# 創(chuàng)建一個SSL套接字
skt = context.wrap_socket(socket.socket(), server_hostname=domain)
try:
# 建立SSL連接
skt.connect((ip, 443))
# 獲取證書過期時間
end_date = skt.getpeercert()['notAfter'].strip(' GMT')
# 創(chuàng)建一個字典,存儲本次連接中的域名、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:
# 關(guān)閉SSL套接字
skt.close()
return skt_info
def check_cert_time(info):
# 獲取當(dāng)前時間戳
current_timestamp = int(time.time())
# 將證書過期時間轉(zhuǎn)換成時間戳
date_object = datetime.strptime(info['end_date'], "%b %d %H:%M:%S %Y")
end_timestamp = int(date_object.timestamp())
# 計(jì)算剩余天數(shù)
remain_day = (end_timestamp - current_timestamp) / 86400
# 打印域名、IP 地址和證書過期時間信息
print(f"域名:{info['domain']},ip 地址:{info['ip']},證書過期時間:{info['end_date']}")
# 根據(jù)剩余天數(shù)進(jìn)行不同的提示
# 如果證書過期時間減去當(dāng)前時間的天數(shù)小于七天的話,則提示需要準(zhǔn)備更換證書了
if 0 < remain_day < 7:
print('剩余時間小于七天!請及時更換證書!')
elif remain_day < 0:
print('證書已過期!請及時更換證書!')
else:
print(f"剩余天數(shù)為:{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]到此這篇關(guān)于Python實(shí)現(xiàn)檢測SSL證書是否過期的文章就介紹到這了,更多相關(guān)Python檢測SSL是否過期內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Tkinter組件實(shí)現(xiàn)Radiobutton的示例
Radiobutton組件用于實(shí)現(xiàn)多選一的問題,本文主要介紹了Tkinter組件實(shí)現(xiàn)Radiobutton的示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-01-01
Python排序方法中sort和sorted的區(qū)別詳解
在python中常用的排序函數(shù)就是sort()和sorted()這兩個函數(shù),使用 sort() 或內(nèi)建函數(shù) sorted() 對列表進(jìn)行排序,本文將詳細(xì)介紹sorted和sort兩者之間的區(qū)別,感興趣的可以了解一下2023-08-08
Jupyter 無法下載文件夾如何實(shí)現(xiàn)曲線救國
這篇文章主要介紹了Jupyter 無法下載文件夾如何實(shí)現(xiàn)曲線救國?今天小編就為大家?guī)砹私鉀Q方法,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
Python根據(jù)文件名批量轉(zhuǎn)移圖片的方法
今天小編就為大家分享一篇Python根據(jù)文件名批量轉(zhuǎn)移圖片的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10

