From cc14c288d3718dfae7b2b9fba834ec35fcf3f311 Mon Sep 17 00:00:00 2001 From: nmemmert <67961292+nmemmert@users.noreply.github.com> Date: Wed, 5 Nov 2025 11:59:32 -0500 Subject: [PATCH] Add self-signed SSL certificate generation option to Ubuntu install script --- ubuntu-install.sh | 103 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 95 insertions(+), 8 deletions(-) diff --git a/ubuntu-install.sh b/ubuntu-install.sh index 9b8166c..87b3bb0 100644 --- a/ubuntu-install.sh +++ b/ubuntu-install.sh @@ -113,10 +113,18 @@ SERVER_HOST=${SERVER_HOST:-$DNS_DOMAIN} # Determine if we should use HTTPS USE_HTTPS=false +GENERATE_SELF_SIGNED=false if [[ "$DNS_DOMAIN" != "localhost" && "$DNS_DOMAIN" != "127.0.0.1" ]]; then read -p "Do you have SSL certificates for $DNS_DOMAIN? (y/n) [n]: " HAS_SSL if [[ "${HAS_SSL,,}" == "y" || "${HAS_SSL,,}" == "yes" ]]; then USE_HTTPS=true + else + read -p "Would you like to generate self-signed SSL certificates? (y/n) [y]: " GEN_SELF + GEN_SELF=${GEN_SELF:-y} + if [[ "${GEN_SELF,,}" == "y" || "${GEN_SELF,,}" == "yes" ]]; then + USE_HTTPS=true + GENERATE_SELF_SIGNED=true + fi fi fi @@ -149,13 +157,86 @@ EOF log_success "Azure AD configuration saved to .env file" +# Generate self-signed SSL certificates if requested +if [[ "$GENERATE_SELF_SIGNED" == "true" ]]; then + log_info "Generating self-signed SSL certificates..." + sudo mkdir -p /etc/ssl/certs /etc/ssl/private + + # Generate self-signed certificate + sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ + -keyout /etc/ssl/private/pdf-sort-merge.key \ + -out /etc/ssl/certs/pdf-sort-merge.crt \ + -subj "/C=US/ST=State/L=City/O=Organization/CN=$DNS_DOMAIN" \ + -addext "subjectAltName=DNS:$DNS_DOMAIN" + + log_success "Self-signed SSL certificates generated" +fi + # Install and configure nginx log_info "Installing and configuring nginx..." sudo apt install -y nginx # Create nginx configuration NGINX_CONF="/etc/nginx/sites-available/pdf-sort-merge" -sudo tee "$NGINX_CONF" > /dev/null << EOF +if [[ "$USE_HTTPS" == "true" ]]; then + # HTTPS configuration with SSL + sudo tee "$NGINX_CONF" > /dev/null << EOF +server { + listen 80; + server_name $DNS_DOMAIN; + return 301 https://\$server_name\$request_uri; +} + +server { + listen 443 ssl http2; + server_name $DNS_DOMAIN; + + ssl_certificate /etc/ssl/certs/pdf-sort-merge.crt; + ssl_certificate_key /etc/ssl/private/pdf-sort-merge.key; + + # SSL security settings + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384; + ssl_prefer_server_ciphers off; + + # Security headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header X-Content-Type-Options "nosniff" always; + add_header Referrer-Policy "no-referrer-when-downgrade" always; + add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + # Proxy to Flask app + location / { + proxy_pass http://127.0.0.1:5000; + proxy_set_header Host \$host; + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto \$scheme; + + # WebSocket support (if needed) + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "upgrade"; + + # Timeout settings + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } + + # Static files + location /static/ { + alias $APP_DIR/static/; + expires 1y; + add_header Cache-Control "public, immutable"; + } +} +EOF +else + # HTTP-only configuration + sudo tee "$NGINX_CONF" > /dev/null << EOF server { listen 80; server_name $DNS_DOMAIN; @@ -194,6 +275,7 @@ server { } } EOF +fi # Enable the site sudo ln -sf "$NGINX_CONF" /etc/nginx/sites-enabled/ @@ -250,6 +332,9 @@ mkdir -p results static templates # Set up firewall (optional) log_info "Configuring firewall..." sudo ufw allow 80/tcp || log_warning "Failed to configure firewall for port 80 - you may need to do this manually" +if [[ "$USE_HTTPS" == "true" ]]; then + sudo ufw allow 443/tcp || log_warning "Failed to configure firewall for port 443 - you may need to do this manually" +fi sudo ufw allow ssh/tcp || log_warning "Failed to configure firewall for SSH - you may need to do this manually" # Enable and start service @@ -314,10 +399,12 @@ echo "==================================================================" echo "NEXT STEPS:" echo "1. Point your DNS for $DNS_DOMAIN to this server's IP address" echo "" -echo "2. If you have SSL certificates, update the nginx config:" -echo " sudo nano /etc/nginx/sites-available/pdf-sort-merge" -echo " (add SSL configuration and change listen 80 to 443)" -echo "" +if [[ "$GENERATE_SELF_SIGNED" == "true" ]]; then + echo "2. IMPORTANT: Self-signed certificates are now active!" + echo " - Browsers will show a security warning - click 'Advanced' and 'Proceed'" + echo " - For production, consider getting a proper SSL certificate from Let's Encrypt" + echo "" +fi echo "3. Update your Azure AD app registration redirect URI to:" if [[ "$USE_HTTPS" == "true" ]]; then echo " https://$SERVER_HOST/auth/callback" @@ -326,10 +413,10 @@ else fi echo "" echo "4. Access the application at:" -if [[ "$DNS_DOMAIN" != "localhost" ]]; then - echo " http://$DNS_DOMAIN" +if [[ "$USE_HTTPS" == "true" ]]; then + echo " https://$DNS_DOMAIN" else - echo " http://localhost:5000" + echo " http://$DNS_DOMAIN" fi echo "" echo "MANAGEMENT COMMANDS:"