From 05510f25a5f7c6e96b16d3df645e073f8ef6ca7b Mon Sep 17 00:00:00 2001 From: Joshua Tauberer Date: Sun, 21 Sep 2014 12:51:27 +0000 Subject: [PATCH] warn if a SSL cert is expiring in 30 days --- management/status_checks.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/management/status_checks.py b/management/status_checks.py index 97048f1b..1bf05a68 100755 --- a/management/status_checks.py +++ b/management/status_checks.py @@ -9,6 +9,7 @@ __ALL__ = ['check_certificate'] import os, os.path, re, subprocess, datetime import dns.reversename, dns.resolver +import dateutil.parser, dateutil.tz from dns_update import get_dns_zones, build_tlsa_record from web_update import get_web_domains, get_domain_ssl_files @@ -374,6 +375,7 @@ def check_certificate(domain, ssl_certificate, ssl_private_key): ]) cert_dump = cert_dump.split("\n") certificate_names = set() + cert_expiration_date = None while len(cert_dump) > 0: line = cert_dump.pop(0) @@ -395,6 +397,10 @@ def check_certificate(domain, ssl_certificate, ssl_private_key): if m: certificate_names.add(m.group(1)) + m = re.match(" Not After : (.*)", line) + if m: + cert_expiration_date = dateutil.parser.parse(m.group(1)) + wildcard_domain = re.sub("^[^\.]+", "*", domain) if domain is not None and domain not in certificate_names and wildcard_domain not in certificate_names: return "This certificate is for the wrong domain names. It is for %s." % \ @@ -445,11 +451,21 @@ def check_certificate(domain, ssl_certificate, ssl_private_key): if "self signed" in verifyoutput: # Certificate is self-signed. return "SELF-SIGNED" - elif retcode == 0: - # Certificate is OK. - return "OK" - else: + elif retcode != 0: + # There is some unknown problem. Return the `openssl verify` raw output. return verifyoutput.strip() + else: + # `openssl verify` returned a zero exit status so the cert is currently + # good. + + # But is it expiring soon? + now = datetime.datetime.now(dateutil.tz.tzlocal()) + ndays = (cert_expiration_date-now).days + if ndays <= 31: + return "This certificate expires in %d days on %s." % (ndays, cert_expiration_date.strftime("%x")) + + # Return the special OK code. + return "OK" _apt_updates = None def list_apt_updates(apt_update=True):