Skip to content

Commit 55a2279

Browse files
committed
get the certificate's issuer and the valid days count
1 parent 438a5a4 commit 55a2279

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
"""
4+
Created by PyCharm.
5+
File Name: LinuxBashShellScriptForOps:get-domain-ssl-info.py
6+
Version: 0.0.1
7+
Author: dgden
8+
Author Email: dgdenterprise@gmail.com
9+
URL: https://github.com/DingGuodong/LinuxBashShellScriptForOps
10+
Download URL: https://github.com/DingGuodong/LinuxBashShellScriptForOps/tarball/master
11+
Create Date: 2021/4/14
12+
Create Time: 11:27
13+
Description: get the certificate's issuer and the valid days count
14+
Long Description:
15+
References:
16+
Prerequisites: []
17+
Internet access maybe is required
18+
Development Status: 3 - Alpha, 5 - Production/Stable
19+
Environment: Console
20+
Intended Audience: System Administrators, Developers, End Users/Desktop
21+
License: Freeware, Freely Distributable
22+
Natural Language: English, Chinese (Simplified)
23+
Operating System: POSIX :: Linux, Microsoft :: Windows
24+
Programming Language: Python :: 2.6
25+
Programming Language: Python :: 2.7
26+
Topic: Utilities
27+
"""
28+
import datetime
29+
import socket
30+
import ssl
31+
import sys
32+
33+
import certifi
34+
35+
36+
def get_cert_info(hostname):
37+
ssl_context = ssl.create_default_context(cafile=certifi.where())
38+
ssl_conn = ssl_context.wrap_socket(
39+
socket.socket(socket.AF_INET),
40+
server_hostname=hostname,
41+
)
42+
43+
ssl_conn.settimeout(30.0)
44+
45+
max_tries = 3
46+
tried_time = 0
47+
while True:
48+
try:
49+
ssl_conn.connect((hostname, 443))
50+
break
51+
except socket.error as e:
52+
tried_time += 1
53+
# such as 'socket.error: [Errno 10060]'
54+
print(e, "try again, ({}/{})".format(max_tries, tried_time))
55+
if tried_time == max_tries:
56+
print("Exceed max number of try times, {}".format(max_tries))
57+
sys.exit(1)
58+
59+
cert_info = ssl_conn.getpeercert()
60+
61+
return cert_info
62+
63+
64+
def get_cert_issuer(hostname):
65+
cert_info = get_cert_info(hostname)
66+
issuer = dict([tuple(x[0]) for x in cert_info.get('issuer')])
67+
common_name = issuer.get('commonName')
68+
return common_name
69+
70+
71+
def get_cert_expiry_datetime(hostname):
72+
ssl_date_fmt = r'%b %d %H:%M:%S %Y %Z'
73+
cert_info = get_cert_info(hostname)
74+
# parse the string from the certificate into a Python datetime object
75+
return datetime.datetime.strptime(cert_info['notAfter'], ssl_date_fmt)
76+
77+
78+
def get_cert_valid_days_remaining(hostname):
79+
"""Get the number of days left in a cert's lifetime."""
80+
expires = get_cert_expiry_datetime(hostname)
81+
return (expires - datetime.datetime.utcnow()).days
82+
83+
84+
def is_cert_expired_after_days(hostname, after_days=14):
85+
"""Check if `hostname` SSL cert expires is within `after_days`.
86+
87+
Raises `AlreadyExpired` if the cert is past due
88+
"""
89+
days_remaining = get_cert_valid_days_remaining(hostname)
90+
91+
# if the cert expires in less than two weeks, we should reissue it
92+
if days_remaining < datetime.timedelta(days=0).days:
93+
# cert has already expired - uhoh!
94+
raise Exception("Cert expired %s days ago" % days_remaining)
95+
elif days_remaining < datetime.timedelta(days=after_days).days:
96+
# expires sooner than the buffer
97+
return True
98+
else:
99+
# everything is fine
100+
return False
101+
102+
103+
def show_domain_info(hostname):
104+
domain = hostname
105+
# is_ssl_enable = True
106+
remain_days = get_cert_valid_days_remaining(hostname)
107+
issuer = get_cert_issuer(hostname)
108+
print("Domain: {}, DaysLeft: {}, Issuer: {}".format(
109+
domain,
110+
remain_days,
111+
issuer
112+
))
113+
114+
115+
if __name__ == '__main__':
116+
show_domain_info("github.com")

0 commit comments

Comments
 (0)