Skip to content

Instantly share code, notes, and snippets.

@quantum5
Last active July 8, 2017 19:27
Show Gist options
  • Save quantum5/f780bc39de84fb3f27fa058c2666e0ec to your computer and use it in GitHub Desktop.
Save quantum5/f780bc39de84fb3f27fa058c2666e0ec to your computer and use it in GitHub Desktop.
Certificate Expiration Warning Cron Program
import subprocess
import requests
import argparse
import time
import sys
import os
import re
from datetime import datetime, timedelta
from textwrap import dedent
def find_cn(value):
result = re.search('/CN=([^/]+)', value)
if result:
return result.group(1)
def openssl_datetime(value):
return datetime.strptime(value, '%b %d %H:%M:%S %Y %Z')
def main():
parser = argparse.ArgumentParser()
parser.add_argument('host', help='hostname and port to check')
parser.add_argument('-s', '--sni', help='SNI name to use')
parser.add_argument('-t', '--threshold', help='days before expiry to warn',
default=14, type=int)
parser.add_argument('-q', '--quiet', help='quiet mode', action='store_true')
parser.add_argument('mailgun_domain', nargs='?', help='mailgun domain name to send warning')
parser.add_argument('mailgun_api', nargs='?', help='mailgun API key to send warning')
parser.add_argument('sender', nargs='?', help='address to send warning from')
parser.add_argument('recipients', nargs='*', help='address(es) to send warning to')
parser.add_argument('-m', '--subject', help='email subject to use')
args = parser.parse_args()
with open(os.devnull, 'w+') as null:
cmdline = ['openssl', 's_client', '-connect', args.host]
if args.sni:
cmdline += ['-servername', args.sni]
s_client = subprocess.Popen(
cmdline, stdin=null, stdout=subprocess.PIPE, stderr=null,
)
result = subprocess.check_output(
['openssl', 'x509', '-noout', '-dates', '-subject', '-issuer'],
stdin=s_client.stdout, stderr=null,
)
expires = None
issued = None
issuer = None
cn = None
for line in result.split('\n'):
key, _, value = line.partition('=')
if key == 'notBefore':
issued = openssl_datetime(value)
elif key == 'notAfter':
expires = openssl_datetime(value)
elif key == 'subject':
cn = find_cn(value)
elif key == 'issuer':
issuer = find_cn(value)
delta = expires - datetime.utcnow()
if not args.quiet:
print 'Checked certificate for:', args.host
print 'Certificate x509 name:', cn
print 'Certificate issued on:', issued
print 'Certificate issued by:', issuer
print 'Certificate expires on:', expires
print 'Certificate expires in:', delta
if (args.mailgun_domain and args.mailgun_api and args.sender and args.recipients
and delta <= timedelta(days=args.threshold)):
subject = args.subject or 'Certificate expiration warning for %s' % args.host
text = dedent('''\
Your certificate for {host} expires in {delta}.
Certificate information:
* Host name: {host}
* Common name: {cn}
* Issued on: {issued}
* Expires on: {expires}
* Issuer: {issuer}
Remember to renew the certificate and reload it into the application!
''').format(host=args.host, delta=delta, cn=cn, expires=expires,
issued=issued, issuer=issuer).rstrip()
requests.post(
'https://api.mailgun.net/v3/%s/messages' % args.mailgun_domain,
auth=('api', args.mailgun_api),
data={'from': args.sender,
'to': args.recipients,
'subject': subject,
'text': text})
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment