174 lines
5.1 KiB
Bash
174 lines
5.1 KiB
Bash
#!/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 "$@"
|