How to Monitor SSL Certificates
Knowing that you need to monitor SSL certificates is the first step. The second is setting up monitoring that actually catches problems before your users do. This guide walks through the practical steps: checking your current certificate status, deciding what to monitor, choosing a renewal strategy, and automating the process so you never get paged at 2 AM because a certificate expired silently.
If you are not yet clear on why this matters, start with our introduction to SSL monitoring.
TL;DR
- Start by auditing your current certificates with openssl CLI commands -- check expiry, SANs, chain, and TLS versions.
- Monitor six dimensions: expiry, chain completeness, TLS protocols, cipher suites, HSTS, and CAA records.
- Choose a renewal strategy (Let's Encrypt ACME for public, cert-manager/Vault for internal) and monitor that it actually works.
- The top five pitfalls: missing intermediates, silent renewal failures, wildcard gaps, inconsistent backends, and forgotten non-web endpoints.
- Integrate SSL alerts into Slack, PagerDuty, or your CI/CD pipeline so the right people are notified immediately.
Step 1: Check Your Current Certificate Status
Before setting up automated monitoring, assess where you stand. The openssl CLI is available on every Linux and macOS system and gives you the raw details of any public certificate.
Check expiry dates
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -dates
This outputs the notBefore and notAfter dates. The -servername flag is essential for servers hosting multiple domains behind SNI (Server Name Indication) -- without it, you may get the wrong certificate.
View full certificate details
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -text
This shows everything: issuer, subject, SANs (Subject Alternative Names), key algorithm, key size, signature algorithm, and validity dates. Look for:
- Subject Alternative Names (SANs) -- confirm all your domains and subdomains are listed
- Signature Algorithm -- should be
sha256WithRSAEncryptionor better, neversha1 - Public Key size -- RSA should be 2048 bits minimum, ECDSA 256 bits minimum
Check the certificate chain
echo | openssl s_client -connect example.com:443 -servername example.com -showcerts 2>/dev/null
This displays each certificate in the chain. You should see your leaf certificate (depth 0), one or more intermediates, and optionally the root CA. A common misconfiguration is serving the leaf certificate without the intermediate, which causes validation failures on some clients.
Quick TLS version check
# Test specific TLS versions
openssl s_client -connect example.com:443 -tls1_2 /dev/null && echo "TLS 1.2: supported"
openssl s_client -connect example.com:443 -tls1_3 /dev/null && echo "TLS 1.3: supported"
Step 2: Decide What to Monitor
A good SSL certificate monitoring setup checks more than just the expiry date. Here is what to track and why each dimension matters.
Certificate expiry
The obvious one. Set up alerts at multiple thresholds. A useful pattern is:
- 60 days -- for commercial certificates that need procurement
- 30 days -- start the renewal process
- 14 days -- escalation if not yet renewed
- 7 days -- emergency alert
For Let's Encrypt certificates that auto-renew, a 14-day alert catching a failed renewal is typically sufficient.
Certificate chain completeness
The most common TLS misconfiguration in production is a missing intermediate certificate. The server works fine when tested from Chrome on a developer's laptop (because Chrome caches intermediates aggressively) but fails on mobile devices, older browsers, and API clients that do not perform AIA fetching.
Monitor the chain from a clean client perspective to catch what your browser might miss.
TLS protocol versions
TLS 1.0 and 1.1 are deprecated by RFC 8996 (March 2021). All major browsers have removed support. If your server still offers these protocols, you are providing no additional compatibility while maintaining unnecessary attack surface. Monitor for any protocol below TLS 1.2.
Cipher suite strength
Prefer AEAD cipher suites: AES-GCM and ChaCha20-Poly1305 with forward secrecy (ECDHE key exchange). Flag any server offering:
- CBC-mode ciphers -- vulnerable to BEAST and Lucky13
- RC4 -- broken, should never be used
- 3DES -- vulnerable to Sweet32
- RSA key transport -- no forward secrecy
HSTS configuration
HTTP Strict Transport Security tells browsers to only connect over HTTPS. Check for the Strict-Transport-Security header with a max-age of at least 31536000 (one year). The includeSubDomains directive should be present if you serve all subdomains over HTTPS. If eligible, consider HSTS preloading.
CAA records
DNS Certification Authority Authorization (CAA) records specify which CAs are allowed to issue certificates for your domain. Without CAA records, any CA can issue a certificate for your domain. Monitor that your CAA records remain correctly configured.
Step 3: Choose a Certificate Renewal Strategy
Monitoring without a renewal strategy just gives you advance notice of an impending outage. You need a plan for how certificates get renewed.
Let's Encrypt with ACME clients
For public-facing web services, Let's Encrypt is the standard choice. Certificates are free, valid for 90 days, and renewed automatically via the ACME protocol. The most common ACME client is certbot:
# Install certbot (Ubuntu/Debian)
sudo apt install certbot python3-certbot-nginx
# Obtain and install certificate with auto-renewal
sudo certbot --nginx -d example.com -d www.example.com
# Verify auto-renewal is configured
sudo certbot renew --dry-run
Certbot configures a systemd timer that attempts renewal twice daily. Certificates are renewed when they are within 30 days of expiry. The key word is "attempts" -- if renewal fails (DNS propagation issue, webroot inaccessible, port 80 blocked), it fails silently until the next attempt.
This is precisely where monitoring adds value: it catches the case where automated renewal has been failing for weeks.
Common Mistake
Assuming certbot auto-renewal "just works" without monitoring. Renewal failures are silent by default -- port 80 blocks, webroot changes, or disabled timers can cause weeks of failed attempts that you only discover when the certificate expires.
Commercial certificates
For organizations requiring Organization Validated (OV) or Extended Validated (EV) certificates, renewal is a manual process involving a CA (DigiCert, Sectigo, GlobalSign). These typically have a one-year validity period.
Start the renewal process 45 days before expiry to account for validation delays. Build renewal into your ops calendar.
Internal certificates
Internal PKI for mTLS between microservices often uses tools like cert-manager (Kubernetes), HashiCorp Vault PKI, or step-ca. These systems handle issuance and renewal, but they still need monitoring -- a misconfigured renewal job can fail without any visible symptom until services start rejecting each other's connections.
Step 4: Set Up Automated SSL Certificate Monitoring
With your inventory complete, monitoring dimensions chosen, and renewal strategy in place, it is time to automate.
Option A: Metric Tower (recommended)
Metric Tower's SSL monitoring combines deep certificate analysis with a security-focused dashboard. Add your domains in the monitoring section, and the platform handles the rest:
- Automated checks against every monitored domain on a configurable schedule
- Deep TLS analysis using
testssl.sh(vulnerability checks for BEAST, POODLE, Heartbleed, CRIME, ROBOT, and more) - Fast multi-host certificate parsing via
tlsx(SANs, chain, key details) - Expiry alerts at configurable thresholds via Slack, email, PagerDuty, or webhooks
- Domain registration monitoring via RDAP (detects domain expiry and EPP status changes)
- Team dashboards with historical trend data
- Integration with Metric Tower's broader security scanning for a unified view
Option B: DIY with shell scripts
If you prefer to build your own, here is a starting point. This script checks a list of domains and sends an alert if any certificate expires within 30 days:
#!/bin/bash
THRESHOLD_DAYS=30
DOMAINS="example.com www.example.com api.example.com"
for domain in $DOMAINS; do
expiry=$(echo | openssl s_client -connect "$domain:443" \
-servername "$domain" 2>/dev/null \
| openssl x509 -noout -enddate 2>/dev/null \
| cut -d= -f2)
if [ -z "$expiry" ]; then
echo "WARN: Could not retrieve certificate for $domain"
continue
fi
expiry_epoch=$(date -d "$expiry" +%s 2>/dev/null || date -j -f "%b %d %T %Y %Z" "$expiry" +%s)
now_epoch=$(date +%s)
days_left=$(( (expiry_epoch - now_epoch) / 86400 ))
if [ "$days_left" -lt "$THRESHOLD_DAYS" ]; then
echo "ALERT: $domain expires in $days_left days ($expiry)"
fi
done
This works, but it has limitations: no chain validation, no protocol checks, no cipher analysis, no alerting integration, and no historical tracking. It also requires a server to run on and monitoring of the monitoring script itself.
Step 5: Avoid Common Pitfalls
Even with monitoring in place, these are the issues that catch teams off guard.
Missing intermediate certificates
This is the number one TLS misconfiguration in production. Your certificate works in Chrome (which caches intermediates) but fails in curl, Python requests, mobile apps, and older browsers. Always verify the chain from a clean client:
# Check if chain is complete (should show full chain)
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| grep -E "depth=|verify"
Certificate auto-renewal failing silently
Certbot renewal can fail for multiple silent reasons: port 80 is blocked, the webroot directory changed, DNS validation is misconfigured, or the certbot service/timer was disabled during a system update. Check your certbot timer status periodically:
systemctl status certbot.timer
journalctl -u certbot --since "7 days ago"
Wildcard certificates covering too much (or too little)
A wildcard certificate for *.example.com covers api.example.com and www.example.com but does not cover the bare example.com or nested subdomains like staging.api.example.com. Ensure your SANs explicitly list every hostname you serve.
Different certificates on different servers
Behind a load balancer, each backend server needs the same certificate. If you renewed the certificate on server A but not server B, requests that hit server B will fail intermittently. Monitor from outside the load balancer to catch this.
Forgetting non-web TLS endpoints
SMTP servers (port 25/587/465), IMAP (993), database connections (3306/5432 with TLS), and API gateways all use certificates that need monitoring. Do not limit your monitoring to port 443.
Best Practice
Inventory all TLS endpoints beyond web servers: SMTP (25/587/465), IMAP (993), databases (3306/5432), API gateways, and internal mTLS. Each one has a certificate that can expire independently.
Step 6: Integrate SSL Monitoring Into Your Workflow
Monitoring is only valuable if alerts reach the people who can act on them. Set up integrations with your existing tooling:
Slack or Teams. Route SSL alerts to a dedicated channel like #infrastructure-alerts. Tag the on-call engineer or relevant team.
PagerDuty or OpsGenie. For certificates expiring within 7 days, escalate to your incident management platform. A certificate expiring in 24 hours is an SEV-2 incident.
Email. Good as a secondary channel, but should never be the sole alerting mechanism. Emails get buried.
CI/CD pipeline checks. Add a certificate check to your deployment pipeline. Before deploying to production, verify the target environment's certificates are valid and have at least 14 days remaining. This prevents deploying to an environment with an expiring certificate.
Putting It All Together
Here is a practical monitoring checklist to implement today:
- Run the
opensslcommands above against every public-facing domain you operate - Inventory all certificates: domain, issuer, expiry date, renewal method (auto/manual)
- Set up automated monitoring with configurable expiry alerts
- Enable protocol and cipher analysis to catch TLS misconfigurations
- Verify certificate chain completeness from outside your network
- Configure alerts to route to Slack, PagerDuty, or your incident management system
- Test your renewal process -- actually let a staging certificate expire and verify the renewal path works
- Document the renewal procedure for manual certificates so it is not trapped in one person's head
Best Practice
Test your renewal process in staging. Actually let a staging certificate expire and verify the renewal path works end-to-end. Discovering a broken renewal process in production at 2 AM is the scenario monitoring exists to prevent.
Key Takeaways
- 1 Audit your current certificates first -- check expiry, SANs, chain completeness, TLS versions, and cipher suites with openssl.
- 2 Monitor six dimensions beyond expiry: chain, protocols, ciphers, HSTS, and CAA records each catch different failure modes.
- 3 Automate renewal with ACME clients, but monitor the automation itself -- silent renewal failures are the most common cause of unexpected certificate expiry.
- 4 Route SSL alerts to your incident management system, not just email -- and add certificate checks to your CI/CD pipeline.
Metric Tower's SSL monitoring handles items 3 through 6 out of the box, alongside DNS monitoring, uptime checks, and vulnerability scanning in a single platform. For teams comparing options, our comparison of the top SSL monitoring tools covers the trade-offs between dedicated solutions, bundled monitoring, and enterprise platforms.