The Importance of Certificate Expiration Monitoring
When an SSL/TLS certificate expires, HTTPS connections fail. Browsers display security warnings, users can't access the site, and services relying on HTTPS are disrupted. Despite this serious consequence, certificate expiration remains one of the most common causes of unexpected downtime in production systems. Many organizations have experienced the embarrassment of a high-profile service going down because someone forgot to renew a certificate.
Preventing certificate expiration problems requires both automated monitoring and renewal processes. You need to know well in advance when certificates will expire so you have time to renew them, and you need systems in place to automatically check expiration dates and alert you before it's too late.
Manual Certificate Expiration Checking
Using OpenSSL:
# Check expiration of a certificate file
openssl x509 -in certificate.crt -noout -dates
# Output:
# notBefore=Jan 15 12:34:56 2024 GMT
# notAfter=Apr 14 12:34:56 2024 GMT
# Extract just the expiration date
openssl x509 -in certificate.crt -noout -enddate
# Output:
# notAfter=Apr 14 12:34:56 2024 GMT
Checking a live HTTPS server's certificate:
# Connect to server and retrieve certificate
openssl s_client -connect example.com:443 -servername example.com < /dev/null | openssl x509 -noout -dates
# For just the expiration date:
openssl s_client -connect example.com:443 -servername example.com < /dev/null | openssl x509 -noout -enddate
Using curl:
# Check certificate expiration from a URL
curl -vI https://example.com 2>&1 | grep "expire date"
# Output:
# * expire date: Apr 14 12:34:56 2024 GMT
Using Python:
from datetime import datetime
import ssl
def check_certificate_expiration(hostname, port=443):
context = ssl.create_default_context()
try:
with context.create_connection((hostname, port), timeout=10) as sock:
with context.wrap_socket(sock, server_hostname=hostname) as ssock:
cert = ssock.getpeercert()
expiration = datetime.strptime(
cert['notAfter'],
'%b %d %H:%M:%S %Y %Z'
)
days_until_expiration = (expiration - datetime.now()).days
print(f"Certificate expires: {expiration}")
print(f"Days until expiration: {days_until_expiration}")
if days_until_expiration < 0:
print("CRITICAL: Certificate is EXPIRED")
elif days_until_expiration < 30:
print(f"WARNING: Certificate expires in {days_until_expiration} days")
else:
print(f"OK: Certificate is valid for {days_until_expiration} more days")
return expiration, days_until_expiration
except Exception as e:
print(f"Error checking certificate: {e}")
return None, None
# Usage
check_certificate_expiration('example.com')
Using JavaScript (Node.js):
const https = require('https');
const tls = require('tls');
function checkCertificateExpiration(hostname) {
const options = {
hostname: hostname,
port: 443,
method: 'HEAD'
};
const req = https.request(options, (res) => {
const cert = res.socket.getPeerCertificate();
const expirationDate = new Date(cert.valid_to);
const now = new Date();
const daysUntilExpiration = Math.floor((expirationDate - now) / (1000 * 60 * 60 * 24));
console.log(`Certificate expires: ${expirationDate}`);
console.log(`Days until expiration: ${daysUntilExpiration}`);
if (daysUntilExpiration < 0) {
console.log('CRITICAL: Certificate is EXPIRED');
} else if (daysUntilExpiration < 30) {
console.log(`WARNING: Certificate expires in ${daysUntilExpiration} days`);
} else {
console.log(`OK: Certificate is valid for ${daysUntilExpiration} more days`);
}
res.resume();
});
req.on('error', (err) => {
console.error(`Error checking certificate: ${err.message}`);
});
req.end();
}
// Usage
checkCertificateExpiration('example.com');
Automated Certificate Expiration Monitoring
For production systems, manual checking isn't sufficient. You need automated monitoring that regularly checks expiration dates and alerts you before expiration.
Monitoring Tools:
- Uptime/Monitoring Services:
- Uptimerobot
- Pingdom
- New Relic
- Datadog
These services monitor HTTPS endpoints and can alert when certificate expiration is approaching (typically configurable for 30, 14, 7, and 1-day warnings).
- Certificate Management Tools:
- Sectigo (formerly Comodo)
- DigiCert
- GlobalSign
Most commercial CA platforms offer monitoring and automated renewal.
-
Open Source Tools:
- Certbot (from Let's Encrypt)
- Acme.sh
- cert-manager (Kubernetes)
-
Custom Scripts: Create monitoring scripts that check certificates on a schedule.
Example Monitoring Script (Bash):
#!/bin/bash
HOSTNAME="example.com"
ALERT_THRESHOLD_DAYS=30
EMAIL_ALERT="[email protected]"
# Get certificate expiration date
EXPIRATION=$(echo | openssl s_client -servername $HOSTNAME -connect $HOSTNAME:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
# Convert to seconds since epoch
EXPIRATION_EPOCH=$(date -d "$EXPIRATION" +%s)
NOW_EPOCH=$(date +%s)
# Calculate days until expiration
DAYS_UNTIL=$((($EXPIRATION_EPOCH - $NOW_EPOCH) / 86400))
# Check and alert
if [ $DAYS_UNTIL -lt 0 ]; then
echo "CRITICAL: Certificate for $HOSTNAME is EXPIRED" | mail -s "CRITICAL: Certificate Expired" $EMAIL_ALERT
elif [ $DAYS_UNTIL -lt $ALERT_THRESHOLD_DAYS ]; then
echo "WARNING: Certificate for $HOSTNAME expires in $DAYS_UNTIL days" | mail -s "WARNING: Certificate Expiring" $EMAIL_ALERT
else
echo "OK: Certificate for $HOSTNAME is valid for $DAYS_UNTIL more days"
fi
Add this to cron to run regularly:
# Check certificate expiration daily
0 9 * * * /path/to/check_cert_expiration.sh
Example Monitoring with Prometheus (Node Exporter):
The Node Exporter has a textfile_collector that can run scripts reporting metrics.
Create a script that outputs Prometheus metrics:
#!/bin/bash
HOSTNAME="example.com"
# Get certificate expiration in Unix timestamp
EXPIRATION=$(echo | openssl s_client -servername $HOSTNAME -connect $HOSTNAME:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRATION_EPOCH=$(date -d "$EXPIRATION" +%s)
# Output Prometheus metric
echo "# HELP certificate_expires_seconds_unix Certificate expiration time in Unix epoch"
echo "# TYPE certificate_expires_seconds_unix gauge"
echo "certificate_expires_seconds_unix{hostname=\"$HOSTNAME\"} $EXPIRATION_EPOCH"
Then Prometheus can alert when the expiration time is approaching:
groups:
- name: certificates
rules:
- alert: CertificateExpiresSoon
expr: (certificate_expires_seconds_unix - time()) / 86400 < 30
for: 1h
annotations:
summary: "Certificate expires in less than 30 days"
Kubernetes Certificate Monitoring
For Kubernetes clusters, certificate expiration is a common operational challenge:
Using cert-manager:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-cert
spec:
secretName: example-tls
issuerRef:
name: letsencrypt-prod
dnsNames:
- example.com
- www.example.com
# Auto-renew 30 days before expiration
renewBefore: 720h # 30 days
Monitoring with Prometheus:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: certificate-alerts
spec:
groups:
- name: certificates
interval: 30s
rules:
- alert: KubernetesCertificateExpiresSoon
expr: certmanager_certificate_renewal_errors_total > 0
for: 1h
annotations:
summary: "Certificate renewal error detected"
- alert: KubernetesCertificateExpires
expr: certmanager_certificate_expiration_timestamp_seconds - time() < 604800
# Triggers 7 days before expiration
for: 1h
annotations:
summary: "Certificate expires in less than 7 days"
Automated Certificate Renewal
Prevention is better than cure. Use automated renewal instead of manual renewal:
Let's Encrypt with Certbot:
# Install certbot
apt-get install certbot python3-certbot-nginx
# Get certificate
certbot certonly --nginx -d example.com -d www.example.com
# Set up auto-renewal (installed by default)
systemctl enable certbot.timer
systemctl start certbot.timer
# Check renewal status
certbot renew --dry-run
Certbot automatically renews certificates 30 days before expiration.
Docker-based Renewal:
FROM certbot/certbot
WORKDIR /etc/letsencrypt
VOLUME /etc/letsencrypt
ENTRYPOINT ["certbot", "renew", "--webroot", "-w", "/var/www/html"]
Run as a cron job:
docker run --rm \
-v /etc/letsencrypt:/etc/letsencrypt \
-v /var/www/html:/var/www/html \
certbot/certbot \
renew
Monitoring Across an Organization
For enterprises with many certificates:
Certificate Inventory: Maintain a database of all certificates:
- Hostname
- Certificate authority
- Expiration date
- Renewal date
- Owner contact
Centralized Monitoring: Use CMDB (Configuration Management Database) tools:
- Splunk
- ServiceNow
- Custom dashboard
Alerting Strategy: Set up alerts at multiple thresholds:
- 90 days before expiration: Info
- 30 days before expiration: Warning
- 7 days before expiration: Critical alert to responsible team
- Expired: Critical incident
Reporting: Generate monthly reports of certificate status across the organization.
Troubleshooting Certificate Expiration Issues
Problem: Certificate Shows as Expired but Browser Accepts It:
Likely cause: Your system time is incorrect. Certificates are time-based.
Solution: Sync system time: ntpdate -s time.nist.gov
Problem: Certificate Renewal Failed: Causes:
- DNS not pointing to verification server
- Firewall blocking challenge port
- Disk space exhausted
Solution: Check renewal logs and DNS configuration.
Problem: Intermediate Certificate Missing: If the certificate chain is incomplete, browsers may reject it. Solution: Include intermediate certificate in certificate bundle.
Best Practices
- Automate everything: Use Let's Encrypt and certbot or equivalent for automatic renewal
- Multiple alert levels: Alert progressively as expiration approaches
- Test renewal: Regularly test that renewal processes work
- Monitor across your entire organization: Know every certificate you operate
- Use DNS-based validation: More reliable than HTTP validation
- Shorter certificate lifetime: Modern certificates are often 3-12 months instead of 1-3 years, encouraging automation
Conclusion
Certificate expiration doesn't have to cause downtime. With proper monitoring (automated checking at multiple thresholds), automated renewal (using Let's Encrypt or similar), and good organizational practices (maintaining certificate inventory, understanding the renewal process), you can ensure your certificates never unexpectedly expire. The best approach is to fully automate both monitoring and renewal, treating certificate management as a solved technical problem rather than a manual operational burden.


