Few events are more frustrating than a sudden production outage caused by an expired SSL/TLS certificate. Secure browser locks turn into giant red warnings, users flee, APIs reject connections, and engineering teams scramble. Even in the age of automated renewal tools like Let's Encrypt, cron failures, DNS validation issues, or network glitches can silently break renewal flows.

In this guide, we'll implement a multi-layered SSL monitoring strategy: a lightweight Bash script using openssl for isolated endpoints, and a Prometheus blackbox_exporter setup for robust, enterprise-grade multi-target probing.

DevOps Principle: Never trust that auto-renewal works silently. Always configure an external, independent checking mechanism to verify the actual certificates served to clients.

Method 1: The Lightweight OpenSSL Bash Script

This script connects to a remote endpoint, extracts the expiration date, calculates the remaining lifetime, and triggers alerts if the certificate is within its warning threshold (e.g., less than 14 days).

check_ssl.sh
#!/usr/bin/env bash
# -------------------------------------------------------------
# SSL Certificate expiration checker via OpenSSL.
# -------------------------------------------------------------
set -euo pipefail

TARGET_DOMAIN="example.com"
PORT=443
WARNING_DAYS=14

# Fetch expiration date string from OpenSSL client
expiration_date=$(timeout 5 openssl s_client -connect "${TARGET_DOMAIN}:${PORT}" \
  -servername "${TARGET_DOMAIN}" -showcerts < /dev/null 2>/dev/null \
  | openssl x509 -noout -enddate \
  | cut -d'=' -f2)

if [ -z "${expiration_date}" ]; then
    echo "Error: Could not retrieve certificate for ${TARGET_DOMAIN}"
    exit 1
fi

# Convert dates to epoch seconds
expiry_epoch=$(date -d "${expiration_date}" +%s)
current_epoch=$(date +%s)
seconds_left=$((expiry_epoch - current_epoch))
days_left=$((seconds_left / 86400))

if [ "${days_left}" -le "${WARNING_DAYS}" ]; then
    echo "๐Ÿšจ WARNING: SSL Certificate for ${TARGET_DOMAIN} expires in ${days_left} days! (${expiration_date})"
    # Hook in Slack, PagerDuty, or mail notification commands here
else
    echo "โœ” SSL certificate is healthy. Days remaining: ${days_left}"
fi

Method 2: Enterprise Monitoring with Prometheus Blackbox Exporter

For containerized services, a centralized prober is much cleaner. Prometheus's blackbox_exporter queries endpoints over HTTP/S, TCP, DNS, and ICMP. It exposes the target's certificate expiration timestamps as scrapeable metrics.

1. Configure the Blackbox Exporter

Define an HTTP module inside your blackbox.yml configuration file to check SSL status during calls.

blackbox.yml
modules:
  http_2xx_ssl:
    prober: http
    timeout: 5s
    http:
      method: GET
      preferred_ip_protocol: ip4
      fail_if_not_ssl: true

2. Configure Prometheus Jobs

Add the job configuration to your prometheus.yml file to pass URLs through the blackbox exporter instance.

prometheus.yml
scrape_configs:
  - job_name: 'blackbox_ssl'
    metrics_path: /probe
    params:
      module: [http_2xx_ssl]
    static_configs:
      - targets:
        - https://example.com
        - https://my-api.com
    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target__
      - source_labels: [__param_target__]
        target_label: instance
      - target_label: __address__
        replacement: 127.0.0.1:9115 # Blackbox exporter IP

3. Define Prometheus Alerting Rules

We write an Alertmanager rule alerting if the computed remaining certificate duration is less than 14 days.

alert_rules.yml
groups:
  - name: ssl_rules
    rules:
    - alert: SSLCertificateExpiringSoon
      expr: probe_ssl_earliest_cert_expiry - time() < 86400 * 14
      for: 10m
      labels:
        severity: warning
      annotations:
        summary: "SSL Certificate for instance {{ $labels.instance }} is expiring soon"
        description: "The SSL certificate served by {{ $labels.instance }} will expire in less than 14 days."

Conclusion

Combining local cron checks for standalone servers with Prometheus's centralized monitoring offers solid coverage for your environment. By monitoring SSL states externally, you ensure that network setups, load balancers, and local renewals are validated correctly. This protects users from certificate errors and keeps service availability high.

Pick the method that best matches your setup size, and ensure your team has visibility into certificate lifecycles!