经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Python » 查看文章
SSL 证书过期巡检脚本 (Python 版)
来源:cnblogs  作者:咸鱼Linux运维  时间:2023/8/4 9:02:02  对本文有异议

哈喽大家好,我是咸鱼

之前写了个 shell 版本的 SSL 证书过期巡检脚本 (文章:《SSL 证书过期巡检脚本》),后台反响还是很不错的

那么今天咸鱼给大家介绍一下 python 版本的 SSL 证书过期巡检脚本 (完整代码在文末)

思路

导入相关模块

  1. import ssl
  2. import socket
  3. import time
  4. from datetime import datetime

首先我们创建一个 domain.txt 用来存放要检查的域名和对应的 IP 地址

  1. www.baidu.com:180.101.50.242,180.101.50.188
  2. www.bing.com:202.89.233.101,202.89.233.100

我们读取该文件,把里面的域名和对应的每个 ip 取出来,并存放到字典 domains 里面

  1. domains = {}
  2. with open('domain.txt', 'r', encoding='utf-8') as file:
  3. for line in file:
  4. domain, ip_pool = line.strip().split(':')
  5. domains[domain] = ip_pool.split(',')

取出来之后我们循环遍历字典,去获取每个域名对应的证书信息(ssl_connect 函数)

  1. def ssl_connect(domain, ip):
  2. # 设置socket的超时时间为5秒
  3. socket.setdefaulttimeout(5)
  4. # 创建默认的SSL上下文
  5. context = ssl.create_default_context()
  6. # 创建一个SSL套接字
  7. skt = context.wrap_socket(socket.socket(), server_hostname=domain)
  8. try:
  9. # 建立SSL连接
  10. skt.connect((ip, 443))
  11. # 获取证书过期时间
  12. end_date = skt.getpeercert()['notAfter'].strip(' GMT')
  13. # 创建一个字典,存储本次连接中的域名、IP 地址和证书过期时间信息
  14. skt_info = {'domain': domain, 'ip': ip, 'end_date': end_date}
  15. except ssl.CertificateError as e:
  16. cert = e
  17. except socket.timeout:
  18. cert = 'Connect refused'
  19. except ConnectionResetError as e:
  20. cert = 'Connect reset' + str(e)
  21. except socket.gaierror as e:
  22. cert = 'Connnect gaierror'
  23. finally:
  24. # 关闭SSL套接字
  25. skt.close()
  26. return skt_info

ssl_connect 函数返回一个字典 skt_info,包含当前连接的域名、ip 地址和证书过期时间

  1. # skt_info 内容
  2. {'domain': 'www.baidu.com', 'ip': '180.101.50.242', 'end_date': 'Aug 6 01:51:05 2024'}
  3. {'domain': 'www.baidu.com', 'ip': '180.101.50.188', 'end_date': 'Aug 6 01:51:05 2024'}
  4. {'domain': 'www.bing.com', 'ip': '202.89.233.101', 'end_date': 'Aug 16 03:47:45 2023'}
  5. {'domain': 'www.bing.com', 'ip': '202.89.233.100', 'end_date': 'Aug 16 03:47:45 2023'}

然后我们调用 check_cert_time 函数进行证书有效期检查和提示

  1. info = [ssl_connect(domain, ip) for domain, ip_pool in domains.items() for ip in ip_pool]
  2. [check_cert_time(i) for i in info]

check_cert_time 函数内容如下:

  1. def check_cert_time(info):
  2. # 获取当前时间戳
  3. current_timestamp = int(time.time())
  4. # 将证书过期时间转换成时间戳
  5. date_object = datetime.strptime(info['end_date'], "%b %d %H:%M:%S %Y")
  6. end_timestamp = int(date_object.timestamp())
  7. # 计算剩余天数
  8. remain_day = (end_timestamp - current_timestamp) / 86400
  9. # 打印域名、IP 地址和证书过期时间信息
  10. print(f"域名:{info['domain']},ip 地址:{info['ip']},证书过期时间:{info['end_date']}")
  11. # 根据剩余天数进行不同的提示
  12. # 如果证书过期时间减去当前时间的天数小于七天的话,则提示需要准备更换证书了
  13. if 0 < remain_day < 7:
  14. print('剩余时间小于七天!请及时更换证书!')
  15. elif remain_day < 0:
  16. print('证书已过期!请及时更换证书!')
  17. else:
  18. print(f"剩余天数为:{remain_day:.2f}天\n")

最后我们执行一下代码,看看结果如何
image

完整代码

  1. import ssl
  2. import socket
  3. import time
  4. from datetime import datetime
  5. def ssl_connect(domain, ip):
  6. # 设置socket的超时时间为5秒
  7. socket.setdefaulttimeout(5)
  8. # 创建默认的SSL上下文
  9. context = ssl.create_default_context()
  10. # 创建一个SSL套接字
  11. skt = context.wrap_socket(socket.socket(), server_hostname=domain)
  12. try:
  13. # 建立SSL连接
  14. skt.connect((ip, 443))
  15. # 获取证书过期时间
  16. end_date = skt.getpeercert()['notAfter'].strip(' GMT')
  17. # 创建一个字典,存储本次连接中的域名、IP 地址和证书过期时间信息
  18. skt_info = {'domain': domain, 'ip': ip, 'end_date': end_date}
  19. except ssl.CertificateError as e:
  20. cert = e
  21. except socket.timeout:
  22. cert = 'Connect refused'
  23. except ConnectionResetError as e:
  24. cert = 'Connect reset' + str(e)
  25. except socket.gaierror as e:
  26. cert = 'Connnect gaierror'
  27. finally:
  28. # 关闭SSL套接字
  29. skt.close()
  30. return skt_info
  31. def check_cert_time(info):
  32. # 获取当前时间戳
  33. current_timestamp = int(time.time())
  34. # 将证书过期时间转换成时间戳
  35. date_object = datetime.strptime(info['end_date'], "%b %d %H:%M:%S %Y")
  36. end_timestamp = int(date_object.timestamp())
  37. # 计算剩余天数
  38. remain_day = (end_timestamp - current_timestamp) / 86400
  39. # 打印域名、IP 地址和证书过期时间信息
  40. print(f"域名:{info['domain']},ip 地址:{info['ip']},证书过期时间:{info['end_date']}")
  41. # 根据剩余天数进行不同的提示
  42. # 如果证书过期时间减去当前时间的天数小于七天的话,则提示需要准备更换证书了
  43. if 0 < remain_day < 7:
  44. print('剩余时间小于七天!请及时更换证书!')
  45. elif remain_day < 0:
  46. print('证书已过期!请及时更换证书!')
  47. else:
  48. print(f"剩余天数为:{remain_day:.2f}天\n")
  49. if __name__ == "__main__":
  50. domains = {}
  51. with open('domain.txt', 'r', encoding='utf-8') as file:
  52. for line in file:
  53. domain, ip_pool = line.strip().split(':')
  54. domains[domain] = ip_pool.split(',')
  55. info = [ssl_connect(domain, ip) for domain, ip_pool in domains.items() for ip in ip_pool]
  56. [check_cert_time(i) for i in info]

原文链接:https://www.cnblogs.com/edisonfish/p/17604403.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号