bash DevOps

SSL Certificate Auto-Renewal

Automated SSL certificate renewal script using Certbot with pre/post hooks for web server restart and Slack notifications.

Apex Logic 0 copies
bash
#!/bin/bash
# SSL Certificate Auto-Renewal with notifications
set -euo pipefail

DOMAIN="${1:-example.com}"
EMAIL="admin@${DOMAIN}"
WEBROOT="/var/www/html"
SLACK_WEBHOOK="${SLACK_WEBHOOK_URL:-}"
LOG_FILE="/var/log/ssl-renewal.log"

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"; }
notify() {
    if [ -n "$SLACK_WEBHOOK" ]; then
        curl -s -X POST "$SLACK_WEBHOOK" \
            -H 'Content-Type: application/json' \
            -d "{\"text\": \"$1\"}" > /dev/null
    fi
}

log "Starting SSL renewal check for $DOMAIN"

# Check certificate expiry
EXPIRY=$(openssl s_client -connect "${DOMAIN}:443" -servername "$DOMAIN" </dev/null 2>/dev/null | \
    openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)

if [ -n "$EXPIRY" ]; then
    EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s 2>/dev/null || date -jf "%b %d %T %Y %Z" "$EXPIRY" +%s)
    NOW_EPOCH=$(date +%s)
    DAYS_LEFT=$(( (EXPIRY_EPOCH - NOW_EPOCH) / 86400 ))
    log "Certificate expires in $DAYS_LEFT days ($EXPIRY)"

    if [ "$DAYS_LEFT" -gt 30 ]; then
        log "No renewal needed. Exiting."
        exit 0
    fi
fi

log "Attempting certificate renewal..."
if certbot renew --webroot -w "$WEBROOT" --quiet --deploy-hook "systemctl reload nginx"; then
    log "SSL certificate renewed successfully"
    notify "SSL certificate for $DOMAIN renewed successfully"
else
    log "ERROR: SSL renewal failed!"
    notify "ALERT: SSL renewal FAILED for $DOMAIN"
    exit 1
fi

Tags

ssl certbot letsencrypt security

Related Snippets

bash

Docker Cleanup Script

bash

MongoDB Backup Script

bash

PM2 Deployment Script

bash

Log Rotation Script