bitip/docs/CONFIGURATION.md

15 KiB

Bitip GeoIP Service - Configuration Guide

This document provides detailed information about configuring the Bitip GeoIP Service using environment variables.

Table of Contents


Backend Configuration

The backend is configured via environment variables, typically stored in .env at the project root or src/backend/.env.

Configuration File Locations

  • Development: d:\Git\Home\Bitip\.env (project root)
  • Production: Set via Docker environment variables or system environment

Backend Environment Variables

API Keys

FRONTEND_API_KEY=frontend-dev-key
EXTERNAL_API_KEYS=external-dev-key-1,external-dev-key-2

FRONTEND_API_KEY

  • Purpose: API key used by the frontend application to authenticate with the backend
  • Format: String (alphanumeric recommended)
  • Required: Yes
  • Security: Change this to a secure random value in production
  • Example: your-secure-frontend-api-key-here

EXTERNAL_API_KEYS

  • Purpose: Comma-separated list of API keys for external clients (non-frontend applications)
  • Format: Comma-separated strings
  • Required: Yes (can be empty string if no external access needed)
  • Security: Use strong, randomly generated keys in production
  • Example: key1-abc123,key2-def456,key3-ghi789

Frontend Origin Validation

FRONTEND_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:5174,http://localhost:5175

FRONTEND_ALLOWED_ORIGINS

  • Purpose: Comma-separated list of allowed origins (domains) that can use the frontend API key
  • Format: Comma-separated full URLs (including protocol and port)
  • Required: Yes
  • Default: http://localhost:5173 (if not set)
  • Security:
    • Provides additional protection layer beyond rate limiting
    • Validates Origin or Referer header for requests using frontend API key
    • Only applies to frontend API key - external keys are not origin-restricted
    • Note: Can be bypassed from Postman/curl, but blocks browser-based abuse from other domains
  • Development Example: http://localhost:5173,http://localhost:5174,http://localhost:5175
  • Production Example: https://your-domain.com,https://www.your-domain.com
  • Use Cases:
    • Prevent frontend API key theft and reuse from other websites
    • Block cross-site abuse while still allowing legitimate frontend access
    • Works in conjunction with CORS for defense-in-depth
  • Important Notes:
    • Must include protocol (http:// or https://)
    • Must include port if non-standard (e.g., http://localhost:5173)
    • Requests without Origin or Referer header will be rejected
    • Multiple origins supported for staging/production environments

Server Configuration

PORT=5172
BASE_PATH=/geoip-ui
NODE_ENV=development
ENABLE_HTTPS_SECURITY=false

PORT

  • Purpose: Port number on which the backend API server listens
  • Format: Integer (1-65535)
  • Required: Yes
  • Default: 5172 (if not set)
  • Development: 5172
  • Production: Typically 5172 or 8080
  • Example: 5172

BASE_PATH

  • Purpose: Base URL path for all API routes and static files
  • Format: String starting with / (or just / for root)
  • Required: Yes
  • Default: /
  • Use Cases:
    • / - Application at root (e.g., http://localhost:5172/api/health)
    • /geoip-ui - Application under subpath (e.g., http://localhost:5172/geoip-ui/api/health)
    • Useful for reverse proxy scenarios or hosting multiple apps on same domain
  • Example: /geoip-ui
  • Note: All API routes are prefixed with this path automatically
  • Health Check: The /api/health endpoint is ALWAYS available at root (/api/health) for Docker HEALTHCHECK compatibility, AND also at {BASE_PATH}/api/health for consistency

NODE_ENV

  • Purpose: Node.js environment mode
  • Format: String
  • Required: No (defaults to 'development')
  • Valid Values:
    • development - Enables verbose logging, detailed errors
    • production - Optimized for performance, minimal logging
  • Example: production

LOG_LEVEL

  • Purpose: Minimum logging level for both console and Seq output
  • Format: String
  • Required: No
  • Default: info
  • Valid Values:
    • debug - All logs including debug messages (very verbose, use only for troubleshooting)
    • info - Informational messages, warnings, and errors (recommended for development)
    • warning - Only warnings and errors (recommended for production)
    • error - Only error messages (minimal logging)
  • Use Cases:
    • Development: debug or info - Full visibility into application behavior
    • Production: warning or error - Reduce log volume and focus on issues
    • Troubleshooting: Temporarily set to debug to diagnose problems
  • Example: warning
  • Note: Similar to Serilog's minimum level filtering in .NET
  • Impact: Affects both console output and Seq structured logging

ENABLE_HTTPS_SECURITY

  • Purpose: Enable/disable HTTPS security headers (Helmet middleware)
  • Format: Boolean string (true or false)
  • Required: No
  • Default: false
  • Valid Values:
    • false - Disables CSP, HSTS, COOP, and CORP headers (required for plain HTTP)
    • true - Enables all security headers (use when behind HTTPS reverse proxy)
  • Use Cases:
    • Set to false for development on HTTP
    • Set to false for production HTTP deployments
    • Set to true when using HTTPS with reverse proxy (nginx, Traefik, Caddy, etc.)
  • Important: Browser security policies will block resources if HTTPS security headers are enabled on plain HTTP connections. Only enable when serving over HTTPS.
  • Example: false

MaxMind Database Configuration

MAXMIND_DB_PATH=D:\\tools\\maxmind-dbs

MAXMIND_DB_PATH

  • Purpose: Absolute file system path to MaxMind GeoLite2 database files
  • Format: Absolute path (OS-specific)
  • Required: Yes
  • Windows Example: D:\\tools\\maxmind-dbs (note double backslashes)
  • Linux Example: /usr/share/maxmind
  • Docker Example: /usr/share/maxmind (mounted volume)
  • Expected Files:
    • GeoLite2-City.mmdb - City-level geolocation database
    • Provided by separate GeoIP update service or manual download
  • Note: Bitip does NOT download databases - they must be provided externally

Rate Limiting Configuration

FRONTEND_RATE_WINDOW_MS=60000
FRONTEND_RATE_MAX=30
EXTERNAL_RATE_WINDOW_MS=60000
EXTERNAL_RATE_MAX=1000

FRONTEND_RATE_WINDOW_MS

  • Purpose: Time window (milliseconds) for frontend API key rate limiting
  • Format: Integer (milliseconds)
  • Required: Yes
  • Default: 60000 (1 minute)
  • Example: 60000 = 1 minute window

FRONTEND_RATE_MAX

  • Purpose: Maximum number of requests allowed from frontend API key within the time window
  • Format: Integer
  • Required: Yes
  • Default: 100
  • Example: 100 = 100 requests per minute

EXTERNAL_RATE_WINDOW_MS

  • Purpose: Time window (milliseconds) for external API keys rate limiting
  • Format: Integer (milliseconds)
  • Required: Yes
  • Default: 60000 (1 minute)
  • Example: 60000 = 1 minute window

EXTERNAL_RATE_MAX

  • Purpose: Maximum number of requests allowed from external API keys within the time window
  • Format: Integer
  • Required: Yes
  • Default: 1000
  • Example: 1000 = 1000 requests per minute

Batch Configuration

BATCH_LIMIT=100
DEBOUNCE_MS=2000

BATCH_LIMIT

  • Purpose: Maximum number of IP addresses allowed in a single batch lookup request
  • Format: Integer
  • Required: Yes
  • Default: 100
  • Example: 100
  • Use Case: Prevents abuse and excessive memory usage

DEBOUNCE_MS

  • Purpose: Debounce delay (milliseconds) for frontend input - delays API calls until user stops typing
  • Format: Integer (milliseconds)
  • Required: Yes
  • Default: 2000 (2 seconds)
  • Example: 2000 = 2 seconds
  • Note: Also configured on frontend - backend value is for reference

Seq Logging Configuration (Optional)

# SEQ_URL=http://localhost:5341
# SEQ_API_KEY=your-seq-api-key

SEQ_URL

  • Purpose: URL of Seq structured logging server
  • Format: HTTP/HTTPS URL
  • Required: No (logging works without Seq)
  • Default: Not set (Seq logging disabled)
  • Example: http://localhost:5341
  • Use Case: Centralized structured logging and monitoring

SEQ_API_KEY

  • Purpose: API key for authenticating with Seq server
  • Format: String
  • Required: No (some Seq instances don't require authentication)
  • Default: Not set
  • Example: your-seq-api-key

Frontend Configuration

The frontend is configured via environment variables, typically stored in src/frontend/.env.

Configuration File Location

  • Development: src/frontend/.env
  • Production: Build-time environment variables or .env.production

Frontend Environment Variables

VITE_API_KEY=frontend-dev-key
VITE_API_URL=http://localhost:5172/geoip-ui
VITE_DEBOUNCE_MS=2000

VITE_API_KEY

  • Purpose: API key to authenticate with the backend (must match FRONTEND_API_KEY in backend)
  • Format: String
  • Required: Yes
  • Example: frontend-dev-key
  • Note: Must match backend's FRONTEND_API_KEY exactly

VITE_API_URL

  • Purpose: Base URL to the backend server
  • Format: HTTP/HTTPS URL
  • Required: Yes
  • Development Example: http://localhost:5172/geoip-ui
  • Production Example: https://your-domain.com/geoip-ui
  • Note: Must match backend's PORT and BASE_PATH configuration.

VITE_DEBOUNCE_MS

  • Purpose: Debounce delay (milliseconds) for IP input field - delays API calls until user stops typing
  • Format: Integer (milliseconds)
  • Required: Yes
  • Default: 2000 (2 seconds)
  • Example: 2000 = 2 seconds
  • Use Case: Reduces API calls while user is still typing

Development Setup

Quick Start

  1. Copy .env.example to .env:

    cp .env.example .env
    
  2. Edit .env for development:

    FRONTEND_API_KEY=frontend-dev-key
    EXTERNAL_API_KEYS=external-dev-key-1,external-dev-key-2
    PORT=5172
    BASE_PATH=/geoip-ui
    NODE_ENV=development
    ENABLE_HTTPS_SECURITY=false
    MAXMIND_DB_PATH=D:\\tools\\maxmind-dbs
    FRONTEND_RATE_WINDOW_MS=60000
    FRONTEND_RATE_MAX=30
    EXTERNAL_RATE_WINDOW_MS=60000
    EXTERNAL_RATE_MAX=1000
    BATCH_LIMIT=100
    DEBOUNCE_MS=2000
    
  3. Edit src/frontend/.env:

    VITE_API_KEY=frontend-dev-key
    VITE_API_URL=http://localhost:5172/geoip-ui
    VITE_DEBOUNCE_MS=2000
    
  4. Ensure MaxMind databases are available:

    • Databases should be provided by separate GeoIP update service
    • Place GeoLite2-City.mmdb in the path specified by MAXMIND_DB_PATH
  5. Start development servers:

    npm run dev
    

Development URLs


Production Setup

Environment Variables

Backend (via Docker or system environment):

FRONTEND_API_KEY=<secure-random-key>
EXTERNAL_API_KEYS=<key1>,<key2>,<key3>
FRONTEND_ALLOWED_ORIGINS=https://your-domain.com,https://www.your-domain.com
PORT=5172
BASE_PATH=/
NODE_ENV=production
ENABLE_HTTPS_SECURITY=true
MAXMIND_DB_PATH=/usr/share/maxmind
FRONTEND_RATE_WINDOW_MS=60000
FRONTEND_RATE_MAX=30
EXTERNAL_RATE_WINDOW_MS=60000
EXTERNAL_RATE_MAX=1000
BATCH_LIMIT=100
DEBOUNCE_MS=2000

Frontend (build-time .env.production):

VITE_API_KEY=<same-as-backend-FRONTEND_API_KEY>
VITE_API_URL=https://your-domain.com
VITE_DEBOUNCE_MS=2000

Security Recommendations

  1. Generate Strong API Keys:

    # Linux/Mac
    openssl rand -hex 32
    
    # PowerShell
    [Convert]::ToBase64String((1..32 | ForEach-Object { Get-Random -Maximum 256 }))
    
  2. Never Commit Real Keys:

    • Keep .env in .gitignore
    • Use .env.example as template only
    • Use secret management in production (Docker secrets, Kubernetes secrets, etc.)
  3. Configure Allowed Origins:

    • Set FRONTEND_ALLOWED_ORIGINS to your actual production domain(s)
    • Include all variants (www, non-www, subdomains)
    • Must use HTTPS in production: https://your-domain.com
    • This provides defense-in-depth against frontend API key theft
  4. Use HTTPS in Production:

    • Set VITE_API_URL to HTTPS endpoint
    • Configure reverse proxy (nginx, Traefik, etc.) for TLS termination
  5. Adjust Rate Limits:

    • Based on expected traffic patterns
    • Monitor and adjust as needed
    • Consider more aggressive limits for frontend key (e.g., 30-50 req/min)
  6. Understanding Security Model:

    • Frontend API Key: Semi-public, visible in browser
      • Protected by: Origin validation + Rate limiting + CORS
      • Can still be extracted and used from Postman/curl
      • Origin validation blocks browser-based cross-site abuse
    • External API Keys: Fully secret, never exposed to browser
      • Protected by: Rate limiting only
      • For trusted backend integrations
    • Best Practice: Use aggressive rate limiting on frontend key to make abuse impractical

Troubleshooting

Backend Won't Start

  • Check MAXMIND_DB_PATH: Ensure path exists and contains GeoLite2-City.mmdb
  • Check Port Conflicts: Ensure PORT is not already in use
  • Check Environment Loading: Verify .env file is at project root

Frontend Can't Connect to Backend

  • Check VITE_API_URL: Must match backend PORT and BASE_PATH
  • Check CORS: Backend allows frontend origin by default
  • Check API Key: VITE_API_KEY must match backend FRONTEND_API_KEY

Authentication Errors

  • 401 Unauthorized: API key mismatch between frontend and backend
  • Verify Keys Match: Frontend VITE_API_KEY === Backend FRONTEND_API_KEY

Origin Validation Errors

  • 403 Forbidden - "Origin header required": Request missing Origin or Referer header

    • Cause: Typically happens when testing from Postman/curl with frontend API key
    • Solution: Use external API key for non-browser clients, or add Origin header manually in testing tools
  • 403 Forbidden - "Invalid origin": Frontend origin not in allowed list

    • Check FRONTEND_ALLOWED_ORIGINS: Ensure your frontend domain is listed
    • Protocol Mismatch: Ensure protocol matches (http:// vs https://)
    • Port Mismatch: Include port if non-standard (e.g., http://localhost:5173)
    • Development: Add all Vite dev server ports (5173, 5174, 5175, etc.)
    • Production: Add all domain variants (www, non-www, subdomains)

Rate Limiting Issues

  • 429 Too Many Requests: Exceeded rate limits
  • Increase Limits: Adjust *_RATE_MAX values in .env
  • Check Time Window: Adjust *_RATE_WINDOW_MS values

Additional Resources

  • Main README: /README.md
  • Breaking Changes: /docs/BREAKING-CHANGES-FIXED.md
  • Package Updates: /docs/PACKAGE-UPDATES.md
  • API Documentation: See inline code comments in /src/backend/routes/api.ts