]> git.siccegge.de Git - dane-monitoring-plugins.git/commitdiff
Add checks for certificate expiry
authorChristoph Egger <christoph@christoph-egger.org>
Mon, 29 Aug 2016 20:32:21 +0000 (22:32 +0200)
committerChristoph Egger <christoph@christoph-egger.org>
Mon, 29 Aug 2016 20:32:21 +0000 (22:32 +0200)
check_dane/cert.py
check_dane_smtp

index 289f514c3d1c8337b9a97ca5bf14d96a10d40d98..a66a1344685d54a9f7e38363e1e5167f33d500e1 100644 (file)
@@ -1,10 +1,43 @@
 #!/usr/bin/python3
 
+from datetime import datetime
+import logging
+from ssl import cert_time_to_seconds
+
 from pyasn1_modules import rfc2459
 from pyasn1.codec.der import decoder, encoder
 
+def verify_certificate(cert, args):
+    expiretimestamp = cert_time_to_seconds(cert['notAfter'])
+    starttimestamp = cert_time_to_seconds(cert['notBefore'])
+
+    if datetime.utcfromtimestamp(starttimestamp) > datetime.utcnow():
+        logging.error("Certificate will only be valid starting %s", cert['notBefore'])
+        return 2
+
+    if datetime.utcfromtimestamp(expiretimestamp) < datetime.utcnow():
+        logging.error("Certificate will only be valid until %s", cert['notAfter'])
+        return 2
+
+    delta = datetime.utcfromtimestamp(expiretimestamp) - datetime.utcnow()
+    deltastr = str(delta).split(",")
+
+    if delta.days < args.critdays:
+        logging.error("expires in %8s,%16s", deltastr[0], deltastr[1])
+        return 2
+    elif delta.days < args.warndays:
+        logging.warn("expires in %8s,%16s", deltastr[0], deltastr[1])
+        return 1
+
+    return 0
 
 def get_spki(certificate):
     cert = decoder.decode(certificate, asn1Spec=rfc2459.Certificate())[0]
     spki = cert['tbsCertificate']["subjectPublicKeyInfo"]
     return encoder.encode(spki)
+
+def add_certificate_options(argparser):
+    argparser.add_argument("--warndays", type=int, default=-1,
+                           help="Days before certificate expiration to warn")
+    argparser.add_argument("--critdays", type=int, default=-1,
+                           help="Days before certificate expiration to raise error")
index 8a40445a1b098f5d7e14a208b1cc4214580f1b74..05ff3481decfe2302ab735e883fd70c8c2a4fcdd 100755 (executable)
@@ -13,6 +13,7 @@ from ssl import SSLContext, PROTOCOL_TLSv1_2, CERT_REQUIRED, cert_time_to_second
 from unbound import ub_ctx, idn2dname, ub_strerror
 
 from check_dane.tlsa import verify_tlsa_record
+from check_dane.cert import verify_certificate, add_certificate_options
 
 def init_connection(sslcontext, args):
     host = args.Host
@@ -96,6 +97,8 @@ def main():
     group.add_argument("-4", "--4", action="store_true", help="check via IPv4 only")
     group.add_argument("--64", action="store_false", help="check via IPv4 and IPv6 (default)")
 
+    add_certificate_options(parser)
+
     args = parser.parse_args()
 
     if args.verbose:
@@ -117,7 +120,9 @@ def main():
         logging.error("Connection refused")
         return 2
 
-    retval = verify_tlsa_record(resolver, "_%d._tcp.%s" % (port, host), connection.getpeercert(binary_form=True))
+    retval = verify_certificate(connection.getpeercert(), args)
+    nretval = verify_tlsa_record(resolver, "_%d._tcp.%s" % (port, host), connection.getpeercert(binary_form=True))
+    retval = max(retval, nretval)
 
     close_connection(connection)
     return retval