From 64ea73a6ab1d9d792167502984f775a95813ce3a Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Fri, 31 Oct 2014 00:38:54 +0100 Subject: [PATCH] Add TLS certificate checker --- tls-check | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tls-check diff --git a/tls-check b/tls-check new file mode 100644 index 0000000..d16e80a --- /dev/null +++ b/tls-check @@ -0,0 +1,68 @@ +#!/usr/bin/python + +from __future__ import print_function +from optparse import OptionParser +from ssl import SSLContext, PROTOCOL_TLSv1_2, CERT_REQUIRED, cert_time_to_seconds, SSLError +from socket import socket, AF_INET6 +from datetime import datetime, timedelta + +VERBOSE=False + +def check_cert(host, port, ca, warn, crit): + context = SSLContext(PROTOCOL_TLSv1_2) + context.verify_mode = CERT_REQUIRED + context.load_verify_locations(ca) + connection = context.wrap_socket(socket(AF_INET6), + server_hostname=host) + try: + connection.connect((host, port)) + except SSLError: + print("CRIT (invalid certificate) %s:%d" % (host, port)) + return 2 + + expiretimestamp = cert_time_to_seconds(connection.getpeercert()['notAfter']) + delta = datetime.utcfromtimestamp(expiretimestamp) - datetime.utcnow() + + if delta < crit: + print("CRIT (expires in %s) %s:%d" % (delta, host, port)) + return 2 + elif delta < warn: + print("WARN (expires in %s) %s:%d" % (delta, host, port)) + return 1 + + +def main(): + global VERBOSE + parser = OptionParser() + parser.add_option("-n", "--name", + action="append", type="string", dest="hosts", + help="hostname:port to check for expired certificates") + parser.add_option("-w", "--warning-days", + action="store", type=int, dest="warn", default=15, + help="minimum remaining validity in days before a warning is issued") + parser.add_option("-c", "--critical-days", + action="store", type=int, dest="crit", default=5, + help="minimum remaining validity in days before a warning is issued") + parser.add_option("-v", action="store_true", dest="verbose", default=False) + parser.add_option("-q", action="store_false", dest="verbose") + parser.add_option("--ca", action="store", type="string", dest="ca", + default="/etc/ssl/certs/ca-certificates.crt", + help="ca certificate bundle") + + + opts, _args = parser.parse_args() + + VERBOSE = opts.verbose + if not opts.hosts: + parser.error("needs at least one host") + + try: + hosts = [ (i[0], int(i[1])) for i in [ j.split(':', 1) for j in opts.hosts ] ] + except (ValueError, IndexError): + parser.error("names need to be in DNSNAME:PORT format") + + for host, port in hosts: + check_cert(host, port, opts.ca, timedelta(opts.warn), timedelta(opts.crit)) + +if __name__ == "__main__": + main() -- 2.39.2