mnemo_cards/tools/ssl/setup_ssl.sh

140 lines
4.7 KiB
Bash
Raw Permalink Normal View History

2025-12-02 23:28:12 +00:00
#!/bin/bash
# SSL Certificate Setup Script for All Mnemo Cards Domains
# Usage: ./setup_ssl.sh
2025-12-03 01:49:34 +00:00
#
# This script uses nginx webroot mode for certificate issuance/renewal
# which doesn't require stopping nginx.
2025-12-02 23:28:12 +00:00
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
echo "🔐 Setting up SSL certificates for all Mnemo Cards domains..."
# Check if running as root
if [ "$EUID" -ne 0 ]; then
print_error "This script must be run as root (sudo)"
exit 1
fi
# Email for Let's Encrypt (can be overridden)
LETSENCRYPT_EMAIL="${LETSENCRYPT_EMAIL:-admin@mnemo-cards.online}"
2025-12-03 01:49:34 +00:00
# Domains to set up certificates for (only mnemo-cards.online domains)
2025-12-02 23:28:12 +00:00
DOMAINS=(
"mnemo-cards.online"
"api.mnemo-cards.online"
"admin.mnemo-cards.online"
"code.mnemo-cards.online"
"vscode.mnemo-cards.online"
)
2025-12-03 01:49:34 +00:00
# Webroot path for ACME challenge
WEBROOT_PATH="/var/www/html"
2025-12-02 23:28:12 +00:00
# Check if certbot is installed
if ! command -v certbot &> /dev/null; then
2025-12-03 01:49:34 +00:00
print_status "Installing certbot and nginx plugin..."
2025-12-02 23:28:12 +00:00
apt update
2025-12-03 01:49:34 +00:00
apt install -y certbot python3-certbot-nginx
2025-12-02 23:28:12 +00:00
print_success "Certbot installed"
fi
2025-12-03 01:49:34 +00:00
# Ensure webroot directory exists
mkdir -p "$WEBROOT_PATH/.well-known/acme-challenge"
chmod -R 755 "$WEBROOT_PATH/.well-known"
# Clean up old/invalid certificate for hosting domain (not our domain)
if [ -d "/etc/letsencrypt/live/5492281-cf88967.twc1.net" ]; then
print_warning "Removing old hosting certificate (5492281-cf88967.twc1.net)..."
certbot delete --cert-name 5492281-cf88967.twc1.net --non-interactive 2>/dev/null || true
rm -rf /etc/letsencrypt/live/5492281-cf88967.twc1.net 2>/dev/null || true
rm -rf /etc/letsencrypt/archive/5492281-cf88967.twc1.net 2>/dev/null || true
rm -f /etc/letsencrypt/renewal/5492281-cf88967.twc1.net.conf 2>/dev/null || true
print_success "Old hosting certificate removed"
fi
2025-12-02 23:28:12 +00:00
2025-12-03 01:49:34 +00:00
# Get certificates for all domains using nginx plugin (no downtime)
2025-12-02 23:28:12 +00:00
for domain in "${DOMAINS[@]}"; do
2025-12-03 01:49:34 +00:00
if [ -d "/etc/letsencrypt/live/$domain" ] && [ -f "/etc/letsencrypt/live/$domain/fullchain.pem" ]; then
2025-12-02 23:28:12 +00:00
print_success "Certificate already exists for $domain"
else
print_status "Obtaining certificate for $domain..."
2025-12-03 01:49:34 +00:00
# Use nginx plugin - it handles configuration automatically without stopping nginx
if certbot certonly --nginx -d "$domain" --non-interactive --agree-tos --email "$LETSENCRYPT_EMAIL"; then
2025-12-02 23:28:12 +00:00
print_success "Certificate obtained for $domain"
else
2025-12-03 01:49:34 +00:00
print_warning "Nginx plugin failed for $domain, trying standalone..."
# Fallback to standalone (requires stopping nginx briefly)
systemctl stop nginx 2>/dev/null || true
if certbot certonly --standalone -d "$domain" --non-interactive --agree-tos --email "$LETSENCRYPT_EMAIL"; then
print_success "Certificate obtained for $domain (standalone)"
else
print_error "Failed to obtain certificate for $domain"
fi
systemctl start nginx 2>/dev/null || true
2025-12-02 23:28:12 +00:00
fi
fi
done
2025-12-03 01:49:34 +00:00
# Ensure nginx is running
if ! systemctl is-active --quiet nginx; then
print_status "Starting nginx..."
systemctl start nginx
fi
2025-12-02 23:28:12 +00:00
2025-12-03 01:49:34 +00:00
# Set up automatic renewal cron job (uses nginx plugin, no downtime)
2025-12-02 23:28:12 +00:00
print_status "Setting up automatic certificate renewal..."
2025-12-03 01:49:34 +00:00
# Remove old cron jobs that might cause issues
crontab -l 2>/dev/null | grep -v "certbot" | crontab - 2>/dev/null || true
2025-12-02 23:28:12 +00:00
2025-12-03 01:49:34 +00:00
# Add single renewal job that uses nginx plugin
CRON_JOB="0 3 * * * /usr/bin/certbot renew --quiet --deploy-hook \"systemctl reload nginx\""
(crontab -l 2>/dev/null | grep -v certbot; echo "$CRON_JOB") | crontab -
print_success "Automatic renewal cron job configured"
2025-12-02 23:28:12 +00:00
2025-12-03 01:49:34 +00:00
# Test renewal (dry-run)
2025-12-02 23:28:12 +00:00
print_status "Testing certificate renewal..."
2025-12-03 01:49:34 +00:00
if certbot renew --dry-run 2>&1 | grep -q "Congratulations\|would have been renewed\|No renewals were attempted"; then
2025-12-02 23:28:12 +00:00
print_success "Certificate renewal test passed"
else
2025-12-03 01:49:34 +00:00
print_warning "Certificate renewal test had issues - check /var/log/letsencrypt/letsencrypt.log"
2025-12-02 23:28:12 +00:00
fi
echo ""
print_success "SSL certificate setup completed!"
echo ""
echo "📋 Summary:"
2025-12-03 01:49:34 +00:00
echo "- Certificates configured for: ${DOMAINS[*]}"
echo "- Using nginx plugin (no downtime during renewal)"
echo "- Automatic renewal scheduled at 3:00 AM daily"
2025-12-02 23:28:12 +00:00
echo ""
echo "🔍 Run './check_ssl.sh' to verify certificate status"
echo "🔄 Certificates will auto-renew before expiration"