From 57e7353d4f8fd436c426b713832fd839cd68659c Mon Sep 17 00:00:00 2001 From: Alexander Borg Date: Tue, 23 Sep 2025 15:13:06 +0200 Subject: [PATCH] Fix jwt-token --- DOCKER_SECURITY.md | 173 ++++++++++++++++++++++++++++++++++++++++ docker-compose.prod.yml | 97 ++++++++++++++++++++++ docker-compose.yml | 12 ++- 3 files changed, 278 insertions(+), 4 deletions(-) create mode 100644 DOCKER_SECURITY.md create mode 100644 docker-compose.prod.yml diff --git a/DOCKER_SECURITY.md b/DOCKER_SECURITY.md new file mode 100644 index 0000000..8317387 --- /dev/null +++ b/DOCKER_SECURITY.md @@ -0,0 +1,173 @@ +# Docker Security Configuration + +## Overview + +The drone detection system uses a multi-layered security approach with different configurations for development and production environments. + +## Security Layers + +### 🔒 **Internal-Only Services (No External Access)** + +#### 1. PostgreSQL Database +- **Risk**: Direct database access from internet +- **Security**: Only accessible via Docker internal network +- **Development**: Port 5433 exposed via override file +- **Production**: No external ports + +#### 2. Redis Cache/Sessions +- **Risk**: Session data and cache accessible from internet +- **Security**: Only accessible via Docker internal network +- **Development**: Port 6380 exposed via override file +- **Production**: No external ports, password protected + +#### 3. Data Retention Service +- **Risk**: System metrics and cleanup data exposure +- **Security**: Only accessible via management portal with authentication +- **Development**: Port 3004 can be exposed for testing +- **Production**: No external ports + +#### 4. Backend API (Production) +- **Risk**: Direct API access bypassing reverse proxy +- **Security**: Only accessible via nginx reverse proxy in production +- **Development**: Port 3002 exposed for direct access +- **Production**: No external ports + +### 🌐 **Public-Facing Services (External Access)** + +#### 1. Frontend Application +- **Port**: 3001 (development) / 80 via nginx (production) +- **Purpose**: User interface for tenant users +- **Security**: Static files only, no sensitive data + +#### 2. Management Portal +- **Port**: 3003 (development) / 80 via nginx (production) +- **Purpose**: Administrative interface +- **Security**: Authentication required, role-based access + +#### 3. Nginx Reverse Proxy (Production) +- **Ports**: 8080 (HTTP), 8443 (HTTPS) +- **Purpose**: Single entry point for all services +- **Security**: SSL termination, request filtering + +## Configuration Files + +### Base Configuration: `docker-compose.yml` +- **Purpose**: Secure baseline configuration +- **Security**: All internal services locked down +- **Database**: No external ports +- **Redis**: No external ports +- **Data Retention**: No external ports + +### Development Override: `docker-compose.override.yml` +- **Purpose**: Development convenience +- **Security**: Exposes internal services for debugging +- **Usage**: `docker-compose up` (automatically uses override) +- **Warning**: ⚠️ Never deploy to production with override file + +### Production Configuration: `docker-compose.prod.yml` +- **Purpose**: Maximum security for production +- **Security**: All services internal-only except nginx +- **Usage**: `docker-compose -f docker-compose.yml -f docker-compose.prod.yml up` +- **Features**: Password protection, SSL, enhanced logging + +## Deployment Commands + +### Development (Less Secure, More Convenient) +```bash +# Uses docker-compose.yml + docker-compose.override.yml +docker-compose up -d + +# Direct database access available on localhost:5433 +# Direct Redis access available on localhost:6380 +# Direct backend access available on localhost:3002 +``` + +### Production (Maximum Security) +```bash +# Uses docker-compose.yml + docker-compose.prod.yml +docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d + +# No direct database access +# No direct Redis access +# No direct backend access +# All access via nginx reverse proxy only +``` + +### Staging/Testing (Secure but with Monitoring) +```bash +# Uses base configuration only +docker-compose -f docker-compose.yml up -d + +# Secure but allows manual inspection if needed +``` + +## Security Checklist + +### ✅ **Applied Security Measures** + +- **Database Isolation**: PostgreSQL not externally accessible +- **Cache Security**: Redis internal-only with authentication +- **API Protection**: Backend only accessible via reverse proxy in production +- **Metrics Security**: Data retention metrics require management authentication +- **Network Segmentation**: All services on isolated Docker network +- **Access Control**: Role-based permissions for sensitive endpoints +- **Audit Logging**: All data retention access logged +- **Security Headers**: Applied to all management endpoints + +### 🔍 **Additional Security Recommendations** + +#### Network Security +- **Firewall**: Configure host firewall to only allow necessary ports +- **VPN**: Consider VPN access for management interfaces +- **IP Allowlisting**: Restrict management portal access by IP + +#### Database Security +- **Encryption**: Enable TLS for database connections +- **Backup Encryption**: Encrypt database backups +- **User Permissions**: Use least-privilege database users + +#### Application Security +- **JWT Secrets**: Use strong, unique JWT secrets +- **Session Security**: Configure secure session settings +- **Rate Limiting**: Enable rate limiting on all endpoints + +#### Container Security +- **Image Scanning**: Scan container images for vulnerabilities +- **User Permissions**: Run containers as non-root users +- **Resource Limits**: Set memory and CPU limits + +## Emergency Access + +### Development Database Access +```bash +# Connect to development database (when override is active) +psql -h localhost -p 5433 -U postgres -d drone_detection +``` + +### Production Database Access (Emergency Only) +```bash +# Temporarily expose database for emergency access +docker-compose -f docker-compose.yml -f docker-compose.override.yml up -d postgres + +# Connect and then immediately remove override +psql -h localhost -p 5433 -U postgres -d drone_detection + +# Restore production security +docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d +``` + +## Monitoring & Alerting + +### Security Events to Monitor +- **Unauthorized Access**: Failed authentication attempts on management portal +- **Data Retention Access**: All access to system metrics endpoints +- **Database Connections**: Unusual database connection patterns +- **Network Traffic**: Unexpected traffic to internal services + +### Log Locations +- **Security Logs**: `/app/logs/data_retention_access.log` +- **Application Logs**: Container logs via `docker-compose logs` +- **Database Logs**: PostgreSQL container logs +- **Nginx Logs**: Reverse proxy access logs + +This security configuration ensures that sensitive infrastructure components are isolated while maintaining operational flexibility for different environments. \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..01e5147 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,97 @@ +# Production Docker Compose Configuration +# This file provides production-specific settings with maximum security + +version: '3.8' + +services: + # Backend - Production Security + backend: + # Remove external port exposure - only accessible via reverse proxy + ports: [] + expose: + - "3001" # Internal only + environment: + NODE_ENV: production + # Security settings + API_DEBUG: false + LOG_LEVEL: warn + # Session security + SESSION_SECURE: true + SESSION_SAME_SITE: strict + # Enhanced security headers + ENABLE_SECURITY_HEADERS: true + + # PostgreSQL - Production Security + postgres: + # No external ports in production + ports: [] + expose: + - "5432" # Internal only + environment: + # Production database settings + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # Must be set via environment + POSTGRES_INITDB_ARGS: "--auth-host=scram-sha-256" + # Additional security + command: > + postgres + -c ssl=on + -c ssl_cert_file=/var/lib/postgresql/server.crt + -c ssl_key_file=/var/lib/postgresql/server.key + -c log_connections=on + -c log_disconnections=on + -c log_statement=all + + # Redis - Production Security + redis: + # No external ports in production + ports: [] + expose: + - "6379" # Internal only + command: > + redis-server + --appendonly yes + --requirepass ${REDIS_PASSWORD} + --maxmemory 256mb + --maxmemory-policy allkeys-lru + environment: + REDIS_PASSWORD: ${REDIS_PASSWORD} # Must be set via environment + + # Data Retention - Production Security + data-retention: + # No external ports in production + ports: [] + expose: + - "3001" # Internal only + environment: + NODE_ENV: production + IMMEDIATE_CLEANUP: false + + # Frontend - Production Optimization + frontend: + environment: + # Production optimizations + NGINX_WORKER_PROCESSES: auto + NGINX_WORKER_CONNECTIONS: 1024 + + # Management - Production Optimization + management: + environment: + # Production optimizations + NGINX_WORKER_PROCESSES: auto + NGINX_WORKER_CONNECTIONS: 1024 + + # Health Probe - Production Settings + healthprobe: + environment: + PROBE_FAILRATE: 5 # Lower failure rate in production + PROBE_INTERVAL_SECONDS: 300 # Less frequent in production + +# Production-specific network settings +networks: + drone-network: + driver: bridge + driver_opts: + # Enhanced network security + com.docker.network.bridge.enable_icc: "false" + com.docker.network.bridge.enable_ip_masquerade: "true" + com.docker.network.driver.mtu: 1500 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 40ba5ca..c5d0041 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,8 +14,10 @@ services: volumes: - postgres_data:/var/lib/postgresql/data - ./server/scripts/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql - ports: - - "5433:5432" + # SECURITY: No external ports - internal access only + # Remove this line for production: ports: - "5433:5432" + expose: + - "5432" # Internal port only networks: - drone-network healthcheck: @@ -32,8 +34,10 @@ services: command: redis-server --appendonly yes volumes: - redis_data:/data - ports: - - "6380:6379" + # SECURITY: No external ports - internal access only + # Remove this line for production: ports: - "6380:6379" + expose: + - "6379" # Internal port only networks: - drone-network healthcheck: