157 lines
No EOL
4.8 KiB
Bash
Executable file
157 lines
No EOL
4.8 KiB
Bash
Executable file
#!/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" |