So we have alot of certificates, and its now a daily task to watch for ones that are about to expire. We use nagios to alert for that so it’s not a big problem. Anyhow. We do have access to a CSV file of all our certificates. So I can run through that CSV file and generate a report of expiry dates.
So the input CSV might be:
helpdesk.example.com,443
exttest.example.com,8443
mac-update.example.com,443
api.example.com,443
logos.example.com,443
support.example.com,443
And the output would be (last column is days to go before expirey:
helpdesk.example.com:443 Feb 26 17:25:00 2021 GMT 3
exttest.example.com:8443 Feb 26 17:41:00 2021 GMT 3
mac-update.example.com:443 Feb 27 16:48:00 2021 GMT 4
api.example.com:443 Feb 28 12:03:00 2021 GMT 5
logos.example.com:443 Mar 6 16:20:00 2021 GMT 11
Or display using a pandas dataframe:
#!/usr/bin//env python3
import socket
import sys
import subprocess
import shutil
import os
import getopt
import re
import csv
from datetime import datetime, date,timedelta
from operator import itemgetter
import pandas as pd
websites = []
sorted_websites = []
def check_it_runs(cmd):
try:
if subprocess.run(cmd.split(), timeout=3, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, stdin=subprocess.DEVNULL):
return True
except:
return False
with open('l.txt') as csvDataFile:
csvReader = csv.reader(csvDataFile)
for row in csvReader:
websites.append( { "url": row[0], \
"port": str(row[1]), \
"expiry_date": "NaN", \
"daystogo": -1, } )
for website in websites:
cmd="openssl s_client -connect " + website["url"] + ":" + website["port"] + " -servername " + website["url"]
if check_it_runs(cmd):
cmd1 = "openssl s_client -connect " + website["url"] + ":" + website["port"] + " -servername " + website["url"]
cmd2 = "openssl x509 -noout -dates"
p1 = subprocess.Popen(cmd1.split(), stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
results = str(subprocess.check_output(cmd2.split(), stderr=subprocess.STDOUT, stdin=p1.stdout))
matchObj=re.search( r'(.*notAfter=)(.*)(\\n)',results)
website["expiry_date"] = matchObj.group(2)
daystogo = datetime.strptime( website["expiry_date"],"%b %d %H:%M:%S %Y %Z" )
daystogo = daystogo - datetime.now()
daystogo = re.sub(', \d{1,}:\d{2}:\d{2}\.\d{6,}$', '', str(daystogo))
daystogo = re.sub(' days','', daystogo)
website['daystogo']=int(daystogo)
else:
pass
for website in sorted(websites, key=itemgetter('daystogo')):
#print("%40s:%-4s \'%-30s\' %3s " % ( website['url'], website['port'], website['expiry_date'], website['daystogo']))
sorted_websites.append( { "url":website['url'], "port":website['port'], "expiry_date":website['expiry_date'], "daystogo":website['daystogo'] } )
# Creates DataFrame.
df = pd.DataFrame(sorted_websites)
print(df)
sys.exit()