#!/bin/bash # Main certificate renewal script set -e DOMAIN="${DOMAIN:-dev.uggla.uamils.com}" EMAIL="${EMAIL:-admin@uggla.uamils.com}" RENEWAL_DAYS="${RENEWAL_DAYS:-10}" LOG_FILE="/var/log/certbot/renewal.log" log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" } check_certificate_expiry() { local cert_path="/etc/letsencrypt/live/$DOMAIN/cert.pem" if [[ ! -f "$cert_path" ]]; then log "Certificate not found at $cert_path - will attempt to obtain new certificate" return 1 fi # Get certificate expiry date local expiry_date=$(openssl x509 -in "$cert_path" -noout -enddate | cut -d= -f2) local expiry_epoch=$(date -d "$expiry_date" +%s) local current_epoch=$(date +%s) local days_until_expiry=$(( (expiry_epoch - current_epoch) / 86400 )) log "Certificate expires in $days_until_expiry days" if [[ $days_until_expiry -le $RENEWAL_DAYS ]]; then log "Certificate expires in $days_until_expiry days - renewal needed" return 1 else log "Certificate is valid for $days_until_expiry more days - no renewal needed" return 0 fi } attempt_dns_challenge() { log "Attempting DNS challenge with Loopia API..." if [[ -z "$LOOPIA_USER" || -z "$LOOPIA_PASSWORD" ]]; then log "LOOPIA_USER or LOOPIA_PASSWORD not set - skipping DNS challenge" return 1 fi # Try with dns-lexicon if command -v lexicon >/dev/null 2>&1; then log "Using dns-lexicon for DNS challenge..." certbot certonly \ --dns-lexicon \ --dns-lexicon-provider loopia \ --dns-lexicon-loopia-username="$LOOPIA_USER" \ --dns-lexicon-loopia-password="$LOOPIA_PASSWORD" \ --email "$EMAIL" \ --agree-tos \ --non-interactive \ --expand \ -d "$DOMAIN" \ -d "*.$DOMAIN" return $? fi # Fallback: Manual DNS with custom hook if [[ -f "/app/scripts/loopia-hook.sh" ]]; then log "Using custom Loopia hook for DNS challenge..." certbot certonly \ --manual \ --preferred-challenges dns \ --manual-auth-hook "/app/scripts/loopia-hook.sh auth" \ --manual-cleanup-hook "/app/scripts/loopia-hook.sh cleanup" \ --email "$EMAIL" \ --agree-tos \ --non-interactive \ --expand \ -d "$DOMAIN" \ -d "*.$DOMAIN" return $? fi return 1 } attempt_http_challenge() { log "Attempting HTTP challenge..." # Start nginx for HTTP challenge nginx -t && nginx certbot certonly \ --webroot \ --webroot-path=/var/www/html \ --email "$EMAIL" \ --agree-tos \ --non-interactive \ --expand \ -d "$DOMAIN" local result=$? # Stop nginx nginx -s quit || true return $result } reload_nginx() { log "Copying certificates to shared directory..." # Copy certificates to shared SSL directory if [[ -d "/etc/letsencrypt/live/$DOMAIN" ]]; then mkdir -p /shared/ssl cp "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" "/shared/ssl/fullchain.pem" || log "Could not copy fullchain.pem" cp "/etc/letsencrypt/live/$DOMAIN/privkey.pem" "/shared/ssl/privkey.pem" || log "Could not copy privkey.pem" chmod 644 /shared/ssl/fullchain.pem chmod 600 /shared/ssl/privkey.pem log "Certificates copied to /shared/ssl/" fi log "Reloading nginx configuration..." # Check if nginx container exists and reload it if command -v docker >/dev/null 2>&1; then if docker ps --format "table {{.Names}}" | grep -q "nginx\|proxy"; then log "Reloading nginx container..." docker exec nginx nginx -s reload 2>/dev/null || \ docker exec drone-detection-nginx nginx -s reload 2>/dev/null || \ log "Could not reload nginx container - manual reload may be required" fi fi # Also try to reload host nginx if running if pgrep nginx >/dev/null; then log "Reloading host nginx..." nginx -s reload || log "Could not reload host nginx" fi } main() { log "Starting certificate renewal check for $DOMAIN" # Check if renewal is needed if check_certificate_expiry; then log "Certificate is still valid - no action needed" exit 0 fi log "Certificate renewal required - attempting to renew..." # Try DNS challenge first (for wildcard support) if attempt_dns_challenge; then log "DNS challenge successful!" reload_nginx log "Certificate renewal completed successfully" exit 0 fi # Fallback to HTTP challenge (for main domain only) log "DNS challenge failed - falling back to HTTP challenge" if attempt_http_challenge; then log "HTTP challenge successful!" reload_nginx log "Certificate renewal completed successfully" exit 0 fi log "ERROR: All certificate renewal attempts failed" exit 1 } # Run main function main "$@"