diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 64d9e721..0999e191 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -16,9 +16,9 @@ services: restart: unless-stopped ports: # HTTP port (redirects to HTTPS if SSL enabled) - - "${PORT:-8080}:8080" + - "${PORT:-8080}:${PORT:-8080}" # HTTPS port (when SSL is enabled) - - "${SSL_PORT:-8443}:8443" + - "${SSL_PORT:-8443}:${SSL_PORT:-8443}" volumes: - termix-data:/app/data - termix-config:/app/config # Auto-generated .env keys are persisted here diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index cbd5fec0..9c50ab08 100644 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -27,6 +27,64 @@ mkdir -p /app/data chown -R node:node /app/data chmod 755 /app/data +# If SSL is enabled, generate certificates first +if [ "$ENABLE_SSL" = "true" ]; then + echo "Generating SSL certificates..." + mkdir -p /app/ssl + chown -R node:node /app/ssl + chmod 755 /app/ssl + + # Generate SSL certificates using OpenSSL directly (faster and more reliable) + DOMAIN=${SSL_DOMAIN:-localhost} + echo "Generating certificate for domain: $DOMAIN" + + # Create OpenSSL config + cat > /app/ssl/openssl.conf << EOF +[req] +default_bits = 2048 +prompt = no +default_md = sha256 +distinguished_name = dn +req_extensions = v3_req + +[dn] +C=US +ST=State +L=City +O=Termix +OU=IT Department +CN=$DOMAIN + +[v3_req] +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment +subjectAltName = @alt_names + +[alt_names] +DNS.1 = $DOMAIN +DNS.2 = localhost +DNS.3 = 127.0.0.1 +IP.1 = 127.0.0.1 +IP.2 = ::1 +EOF + + # Generate private key + openssl genrsa -out /app/ssl/termix.key 2048 + + # Generate certificate + openssl req -new -x509 -key /app/ssl/termix.key -out /app/ssl/termix.crt -days 365 -config /app/ssl/openssl.conf -extensions v3_req + + # Set proper permissions + chmod 600 /app/ssl/termix.key + chmod 644 /app/ssl/termix.crt + chown node:node /app/ssl/termix.key /app/ssl/termix.crt + + # Clean up config + rm -f /app/ssl/openssl.conf + + echo "SSL certificates generated successfully for domain: $DOMAIN" +fi + echo "Starting nginx..." nginx diff --git a/docker/nginx-https.conf b/docker/nginx-https.conf index d05a7a8a..a6007a7b 100644 --- a/docker/nginx-https.conf +++ b/docker/nginx-https.conf @@ -19,16 +19,16 @@ http { # HTTP Server - Redirect to HTTPS server { listen ${PORT}; - server_name localhost; + server_name _; # Redirect all HTTP traffic to HTTPS - return 301 https://$server_name:${SSL_PORT}$request_uri; + return 301 https://$host:${SSL_PORT}$request_uri; } # HTTPS Server server { listen ${SSL_PORT} ssl; - server_name localhost; + server_name _; # SSL Certificate paths ssl_certificate ${SSL_CERT_PATH}; diff --git a/src/backend/database/database.ts b/src/backend/database/database.ts index bfc8da52..10499049 100644 --- a/src/backend/database/database.ts +++ b/src/backend/database/database.ts @@ -1496,34 +1496,14 @@ app.listen(HTTP_PORT, async () => { }); }); -// Start HTTPS server if SSL is enabled +// Note: HTTPS is handled by nginx reverse proxy, not directly by Node.js +// The backend runs on HTTP and nginx terminates SSL const sslConfig = AutoSSLSetup.getSSLConfig(); -if (sslConfig.enabled && fs.existsSync(sslConfig.certPath) && fs.existsSync(sslConfig.keyPath)) { - const httpsOptions = { - cert: fs.readFileSync(sslConfig.certPath), - key: fs.readFileSync(sslConfig.keyPath) - }; - - https.createServer(httpsOptions, app).listen(HTTPS_PORT, () => { - databaseLogger.success(`Database API server started on HTTPS port ${HTTPS_PORT}`, { - operation: "server_start", - port: HTTPS_PORT, - protocol: "HTTPS", - domain: sslConfig.domain, - routes: [ - "/users", - "/ssh", - "/alerts", - "/credentials", - "/health", - "/version", - "/releases/rss", - "/encryption/status", - "/database/export", - "/database/import", - "/database/export/:exportPath/info", - "/database/restore", - ], - }); +if (sslConfig.enabled) { + databaseLogger.info(`SSL is enabled - HTTPS termination handled by nginx on port ${sslConfig.port}`, { + operation: "ssl_info", + nginx_https_port: sslConfig.port, + backend_http_port: HTTP_PORT, + note: "Backend runs on HTTP, nginx handles SSL termination" }); }