#!/usr/bin/env python3 import glob import subprocess import datetime import os WARN_DAYS = 30 CRIT_DAYS = 10 now = datetime.datetime.now() sockets = sorted(glob.glob("/var/run/mysqld/mysqld*.sock")) for sock in sockets: if not os.path.exists(sock): continue try: ssl_cert = subprocess.check_output( ["mysql", "-NS", f"{sock}"], input="SELECT @@ssl_cert;", text=True, stderr=subprocess.DEVNULL ).strip() ssl_ca = subprocess.check_output( ["mysql", "-NS", f"{sock}"], input="SELECT @@ssl_ca;", text=True, stderr=subprocess.DEVNULL ).strip() if not ssl_cert.startswith("/"): datadir = subprocess.check_output( ["mysql", "-NS", f"{sock}"], input="SELECT @@datadir;", text=True, stderr=subprocess.DEVNULL ).strip() cert_path = datadir + ssl_cert else: cert_path = ssl_cert except Exception: print(f"3 mysql_ssl_cert_{os.path.basename(sock)} UNKNOWN - mysql error") continue try: out = subprocess.check_output( ["openssl", "x509", "-in", cert_path, "-noout", "-enddate", "-subject", "-issuer"], text=True, stderr=subprocess.DEVNULL ) except Exception: print(f"3 mysql_ssl_cert_{os.path.basename(sock)} UNKNOWN - cannot read cert {cert_path}") continue expiry = None subject = "" issuer = "" for line in out.splitlines(): if line.startswith("notAfter="): raw = line.split("=", 1)[1].strip() expiry = datetime.datetime.strptime(raw, "%b %d %H:%M:%S %Y %Z") elif line.startswith("subject="): subject = line.replace("subject=", "").strip() elif line.startswith("issuer="): issuer = line.replace("issuer=", "").strip() if not expiry: print(f"3 mysql_ssl_cert_{os.path.basename(sock)} UNKNOWN - cannot parse expiry") continue # ----------- days_left -------------- days_left = (expiry - now).days if days_left < CRIT_DAYS: status = 2 elif days_left < WARN_DAYS: status = 1 else: status = 0 expiry_str = expiry.strftime("%Y-%m-%d %H:%M:%S") svc = f"mysql_ssl_cert_{os.path.basename(sock)}" summary = f"{cert_path}; {days_left} Tage; {expiry_str};" if subject: summary += f" {subject};" if issuer: summary += f" {issuer};" print(f"{status} {svc} days_left={days_left};{WARN_DAYS};{CRIT_DAYS};0; {summary}")