Table of Contents
- Why SSL Certificates Expire Unexpectedly
- Let's Encrypt + Certbot Auto-Renewal
- DirectAdmin Auto-SSL for Hosting
- Setting Up a Cron Job for VPS Renewal
- SSL Expiry Monitoring & Alerts
- Renewing Paid Commercial SSL
- Troubleshooting Auto-Renewal Failures
- SSL Expiry Prevention Checklist
- Frequently Asked Questions
Why SSL Certificates Expire Unexpectedly
SSL certificates have a finite lifespan — currently capped at 398 days (~13 months) for commercial certificates and 90 days for Let's Encrypt. Despite this, many website owners still experience unexpected expiry due to:
- Forgetting to note the expiry date or setting the wrong reminder
- Renewal notification emails landing in spam
- Changed admin email not updated at the CA
- Auto-renewal configured but silently failing after a DNS change
The result: your site shows "Your connection is not private" — a red warning screen that drives visitors away instantly.
Industry data: According to Venafi (2022), over 80% of certificate-related outages are caused by unplanned expiration — all preventable with proper auto-renewal setup.
Let's Encrypt + Certbot Auto-Renewal
Let's Encrypt is the world's most popular free CA, issuing 90-day certificates. Certbot is the IETF-recommended client with full auto-renewal support.
Installing Certbot
# Ubuntu/Debian
sudo apt update
sudo apt install certbot python3-certbot-nginx -y
# Via snap (recommended)
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Obtaining Your First Certificate
# For Nginx
sudo certbot --nginx -d example.com -d www.example.com
# For Apache
sudo certbot --apache -d example.com -d www.example.com
# Standalone (no web server)
sudo certbot certonly --standalone -d example.com
Testing Auto-Renewal
# Dry run — simulates renewal without getting a real cert
sudo certbot renew --dry-run
# Success output: "Congratulations, all simulated renewals succeeded"
Certbot automatically installs a systemd timer or cron job that runs every 12 hours and renews any certificate with less than 30 days remaining.
DirectAdmin Auto-SSL for Hosting
If you use DirectAdmin-based hosting (such as AsiaGB Hosting), SSL management is extremely simple — DirectAdmin includes Auto-SSL built in.
Enabling Auto-SSL in DirectAdmin
- Log in to your DirectAdmin Control Panel
- Navigate to Advanced Features → SSL Certificates
- Select Free & automatic certificate from Let's Encrypt
- Check Force SSL with https redirect
- Click Save
AsiaGB Hosting: Auto-SSL is enabled by default for every domain pointing to our servers. No configuration needed — certificates renew automatically every 60 days.
Checking SSL Status via Command Line
# View current certificate expiry dates
echo | openssl s_client -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -dates
Setting Up a Cron Job for VPS Renewal
On a self-managed VPS, adding an explicit cron job provides extra assurance even though Certbot already installs a timer.
# Open the root crontab
sudo crontab -e
# Add this line (runs daily at 3:30 AM)
30 3 * * * /usr/bin/certbot renew --quiet --post-hook "systemctl reload nginx" 2>&1 | logger -t certbot-renew
Key Flags Explained
| Flag | Purpose |
|---|---|
--quiet | Suppress output unless something goes wrong |
--post-hook | Run a command after successful renewal (reload nginx) |
logger -t certbot-renew | Write output to syslog for later review |
Wildcard Certificates with DNS Challenge
For wildcard SSL (*.example.com), use DNS challenge instead of HTTP challenge:
# Request wildcard cert via DNS challenge
sudo certbot certonly --manual --preferred-challenges dns \
-d "*.example.com" -d "example.com"
# For auto-renewal, use a DNS plugin (e.g., Cloudflare)
sudo certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
-d "*.example.com"
SSL Expiry Monitoring & Alerts
Even with auto-renewal configured, independent monitoring ensures you know immediately if something fails.
Check Expiry via Command Line
# View expiry date
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null \
| openssl x509 -noout -enddate
# Example output: notAfter=Jan 17 12:00:00 2027 GMT
Automated Alert Script
#!/bin/bash
# ssl-check.sh — run daily via cron, email alert if < 30 days remain
DOMAIN="example.com"
DAYS_WARN=30
ALERT_EMAIL="[email protected]"
EXPIRY=$(echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:443 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s)
TODAY_EPOCH=$(date +%s)
DAYS_LEFT=$(( ($EXPIRY_EPOCH - $TODAY_EPOCH) / 86400 ))
if [ $DAYS_LEFT -lt $DAYS_WARN ]; then
echo "SSL for $DOMAIN expires in $DAYS_LEFT days!" | \
mail -s "SSL ALERT: $DOMAIN expires soon" $ALERT_EMAIL
fi
Online Monitoring Tools
| Tool | Features | Price |
|---|---|---|
| UptimeRobot | SSL + uptime checks, email/SMS alerts | Free (basic) |
| SSL Labs Monitor | Auto grade checks | Free |
| Freshping | 1-minute checks, Slack alerts | Free 50 checks |
| Zabbix/Grafana | Enterprise monitoring | Free self-hosted |
Renewing Paid Commercial SSL
Paid certificates like RapidSSL and GeoTrust require re-validation each renewal cycle, but can be semi-automated:
Commercial SSL Renewal Steps
- Generate a new CSR on your server 30–60 days before expiry
- Validate your domain via email, DNS TXT record, or file upload
- Download the new certificate and install it on your server
- Reload your web server to activate the new certificate
# Generate a new CSR
openssl req -new -newkey rsa:2048 -nodes \
-keyout example.com.key \
-out example.com.csr \
-subj "/C=TH/ST=Bangkok/L=Bangkok/O=My Company/CN=example.com"
AsiaGB SSL Pricing (per year)
| Type | Product | Price/year |
|---|---|---|
| DV SSL | RapidSSL | ฿1,000 |
| DV Wildcard | RapidSSL Wildcard | ฿5,000 |
| OV SSL | GeoTrust True BusinessID | ฿4,000 |
| EV SSL | GeoTrust True BusinessID w/EV | ฿7,000 |
Troubleshooting Auto-Renewal Failures
Common Error: certbot renew fails
Most common cause: DNS A record still points to an old server IP, or a firewall is blocking port 80 which Let's Encrypt needs for HTTP challenge validation.
# Check certbot logs
sudo journalctl -u certbot -n 50
# or
sudo cat /var/log/letsencrypt/letsencrypt.log | tail -50
# Verify port 80 is open
sudo ss -tlnp | grep :80
curl -I http://example.com/.well-known/acme-challenge/test 2>&1 | head -5
Common Issues and Fixes
| Issue | Cause | Fix |
|---|---|---|
| Connection refused port 80 | Firewall or web server stopped | Open port 80, start web server |
| Too many requests | Let's Encrypt rate limit hit | Wait 1 hour or use staging server for testing |
| DNS propagation delay | DNS not yet updated | Wait 24-48h or check with dig |
| Permission denied | Certbot lacks write permissions | Run with sudo or fix directory permissions |
SSL Expiry Prevention Checklist
Apply this checklist to every domain to fully prevent certificate expiration:
| Item | How to Verify | Status |
|---|---|---|
| Auto-renewal enabled | certbot renew --dry-run | ✅ Required |
| Cron job configured | crontab -l | grep certbot | ✅ Required |
| External monitoring | UptimeRobot or SSL alert service | ⚠️ Recommended |
| Correct alert email | Check at CA / DirectAdmin | ✅ Required |
| Port 80 open | curl http://domain/.well-known/test | ✅ For HTTP challenge |
| DNS correctly pointed | dig +short A example.com | ✅ Required |
Frequently Asked Questions
Updated: Oct 19, 2026 | Category: SSL Certificate | What is SSL Wildcard? →