mirror of
https://dev.azure.com/tstanciu94/PhantomMind/_git/Bitip
synced 2025-10-13 01:52:19 +03:00
496 lines
15 KiB
Markdown
496 lines
15 KiB
Markdown
# Bitip GeoIP Service - Configuration Guide
|
|
|
|
This document provides detailed information about configuring the Bitip GeoIP Service using environment variables.
|
|
|
|
## Table of Contents
|
|
|
|
- [Backend Configuration](#backend-configuration)
|
|
- [Frontend Configuration](#frontend-configuration)
|
|
- [Development Setup](#development-setup)
|
|
- [Production Setup](#production-setup)
|
|
|
|
---
|
|
|
|
## 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
|
|
|
|
```env
|
|
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
|
|
|
|
```env
|
|
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
|
|
|
|
```env
|
|
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
|
|
|
|
**`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
|
|
|
|
```env
|
|
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
|
|
|
|
```env
|
|
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
|
|
|
|
```env
|
|
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)
|
|
|
|
```env
|
|
# 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
|
|
|
|
```env
|
|
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`**:
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
|
|
2. **Edit `.env` for development**:
|
|
|
|
```env
|
|
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`**:
|
|
|
|
```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**:
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
### Development URLs
|
|
|
|
- **Frontend**: http://localhost:5173/
|
|
- **Backend API**: http://localhost:5172/geoip-ui/api/
|
|
- **Health Check**: http://localhost:5172/geoip-ui/api/health
|
|
|
|
---
|
|
|
|
## Production Setup
|
|
|
|
### Environment Variables
|
|
|
|
**Backend** (via Docker or system environment):
|
|
|
|
```env
|
|
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`):
|
|
|
|
```env
|
|
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**:
|
|
|
|
```bash
|
|
# 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`
|