Beautifully Track Certificate Expirations with Grafana , Influxdb and Collectd.

In my previous write up I had a sample python script to display the number of days a certificate is valid. I have moved forward and created a complete certificate tracking solution using Collectd, Influxdb and Grafana. I will not go through the complete setup here because there are just too many tutorials about this kind of thing. What follows is the recipe for just tracking certificates’ expirations, and arduous and perilous task for admins of all ages.

First you need a collectd config file that uses the exec plugin, normally it would go inside /etc/collectd/collectd.conf.d/certs_valid.conf

LoadPlugin exec

   Exec nobody "/etc/collectd/collectd.conf.d/collectd_certs_valid.py" "one_domain:443"
   Exec nobody "/etc/collectd/collectd.conf.d/collectd_certs_valid.py" "another_domain:443"

Now copy the following python code in /etc/collectd/collectd.conf.d/collectd_certs_valid.py and make sure you can run by hand. A good test is collectd_certs_valid.py http://www.google.com:443 it should start giving out lines like: PUTVAL “www.google.com/x509-seconds/timeleft” interval=10 N:5948602  every ten seconds.

#!/usr/bin/python3 -u
#
# Calculate the expiration days for a cert angelos@multiwave.fr
#
import OpenSSL
import ssl
import sys
import datetime
import time
import os


if len(sys.argv) <=1:
  print("Usage: expires host:port")
  exit(1)

try:
  [hostname,port]=sys.argv[1].split(":")
except:
  hostname=sys.argv[1]
  port=443

try:
  conn = ssl.create_connection((hostname, port))
except:
  print("ssl connection failed")
  exit(1)

try:
  interval=int(os.environ['COLLECTD_INTERVAL'])
except:
  interval=10

while True:
  conn = ssl.create_connection((hostname, port))
  context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
  sock = context.wrap_socket(conn, server_hostname=hostname)
  certificate = ssl.DER_cert_to_PEM_cert(sock.getpeercert(True))
  x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, certificate)
  expires=time.strptime(x509.get_notAfter().decode('ascii'), '%Y%m%d%H%M%SZ')

  now=datetime.datetime.now().timetuple()
  diff=time.mktime(expires)-time.mktime(now)

  print("PUTVAL \"%s/x509-seconds/timeleft\" interval=%d N:%d"% (hostname,interval,diff))

  time.sleep(interval)

The above effectively allows collectd to insert proper expiration time data into your Influxdb. Note the -u parameter to python to use unbuffered output.

Now all you have to do is use  Grafana and create a new dashboard/panel combination and use the x509 metrics retrieved from the python script.

Remember to adjust your Y axes for time data in seconds and the net result of the Graph will be pretty nice. Adjust it to your heart’s content:

The really truly awesome part is Grafana’s Alerts. You can create an alert if a certificate’s time is less than a week to get and alert.

Never Be surprised by an expired certificate ever again!

P.S. many thanks to all the net folks who know the innards of openSSL and x509 for python

Certificate Expiration Tracking

One thought on “Certificate Expiration Tracking

  1. Yannis says:

    Thanks for sharing!!! Much appreciated!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: