#!/bin/bash # SSL Setup script for Mnemo Cards Web App using webroot method # This script sets up Let's Encrypt SSL certificate set -e # Load configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/config.sh" # Check if we're in the right directory check_project_root # Build the Flutter web app for production build_flutter_app print_status "Uploading Flutter web app to server..." # Upload the built Flutter web app rsync -avz --delete build/web/ "$SERVER_USER@$SERVER_IP:$WEB_ROOT/" print_status "Setting up Let's Encrypt SSL certificate using webroot method..." # Execute SSL setup on server ssh "$SERVER_USER@$SERVER_IP" << EOF set -e echo "Creating temporary nginx config for domain validation..." cat > /etc/nginx/sites-available/${APP_NAME}_temp << 'NGINX_EOF' server { listen 80; server_name $DOMAIN; location /.well-known/acme-challenge/ { root /var/www/html; } location / { return 301 https://\$server_name\$request_uri; } } NGINX_EOF # Enable temporary site ln -sf /etc/nginx/sites-available/${APP_NAME}_temp /etc/nginx/sites-enabled/ rm -f /etc/nginx/sites-enabled/$APP_NAME # Create webroot directory mkdir -p /var/www/html/.well-known/acme-challenge # Test and restart nginx nginx -t systemctl restart nginx echo "Obtaining SSL certificate using webroot method..." certbot certonly --webroot -w /var/www/html --non-interactive --agree-tos --email $LETSENCRYPT_EMAIL -d $DOMAIN echo "Setting proper permissions for web files..." chown -R $WEB_USER:$WEB_GROUP $WEB_ROOT chmod -R $WEB_PERMISSIONS $WEB_ROOT echo "Creating final nginx configuration with Let's Encrypt certificates..." cat > $NGINX_CONFIG << 'NGINX_EOF' server { listen 80; server_name $DOMAIN; # Redirect HTTP to HTTPS return 301 https://\$server_name\$request_uri; } server { listen 443 ssl http2; server_name $DOMAIN; # SSL configuration with Let's Encrypt certificates ssl_certificate $SSL_CERT_PATH; ssl_certificate_key $SSL_KEY_PATH; ssl_protocols $SSL_PROTOCOLS; ssl_ciphers $SSL_CIPHERS; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # Security headers add_header X-Frame-Options "$X_FRAME_OPTIONS" always; add_header X-XSS-Protection "$X_XSS_PROTECTION" always; add_header X-Content-Type-Options "$X_CONTENT_TYPE_OPTIONS" always; add_header Referrer-Policy "$REFERRER_POLICY" always; add_header Content-Security-Policy "$CSP_POLICY" always; add_header Strict-Transport-Security "$STRICT_TRANSPORT_SECURITY" always; # Root directory root $WEB_ROOT; index index.html; # Gzip compression gzip on; gzip_vary on; gzip_min_length 1024; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript; # Main location block location / { try_files \$uri \$uri/ /index.html; # Cache static assets location ~* \\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)\$ { expires 1y; add_header Cache-Control "public, immutable"; } } # Handle Flutter web assets location ~* \\.(wasm|js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)\$ { expires $CACHE_EXPIRES; add_header Cache-Control "$CACHE_CONTROL"; # Disabled COEP/COOP headers to allow CORS requests to API # add_header Cross-Origin-Embedder-Policy "$COEP_POLICY"; # add_header Cross-Origin-Opener-Policy "$COOP_POLICY"; } # Security - deny access to hidden files location ~ /\\. { deny all; } } NGINX_EOF # Remove temporary site and enable final site rm -f /etc/nginx/sites-enabled/${APP_NAME}_temp ln -sf $NGINX_CONFIG $NGINX_ENABLED echo "Testing nginx configuration..." nginx -t echo "Starting nginx..." systemctl restart nginx systemctl enable nginx echo "Setting up automatic certificate renewal..." # Create renewal script cat > /etc/cron.d/certbot-renew << 'CRON_EOF' # Renew Let's Encrypt certificates twice daily $CRON_RENEWAL_TIMES root $CRON_RENEWAL_COMMAND CRON_EOF echo "SSL setup completed successfully!" echo "Your app is now available at: https://$DOMAIN" echo "Certificate will auto-renew every 12 hours" EOF print_success "SSL setup completed successfully! 🎉" print_success "Your app is now available at: https://$DOMAIN" print_success "Certificate will automatically renew every 12 hours" print_warning "Note: Make sure your domain DNS is properly configured"