bitip/README.md

599 lines
18 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 🌍 Bitip - GeoIP Lookup Service
Bitip is a professional GeoIP lookup service that provides IP geolocation data through a REST API and user-friendly web interface. Built with Express.js, TypeScript, React, and MaxMind GeoLite2 databases.
## ✨ Features
- **🔍 IP Geolocation Lookup**: Get detailed location information for any public IP address
- **🌐 Web Interface**: Clean, professional web UI with interactive maps
- **📡 REST API**: Comprehensive API for single and batch IP lookups
- **📦 .NET Client Library**: Official Bitip.Client NuGet package with strongly-typed models and async support
- **<2A>🗺 Interactive Maps**: Static preview and interactive map popups using OpenStreetMap/Leaflet
- **🔐 API Key Authentication**: Secure access with configurable rate limiting
- **⚡ Performance**: In-memory caching and efficient database access
- **📊 Structured Logging**: Optional integration with Seq for advanced logging
- **🐳 Docker Ready**: Production deployment with Docker and geoipupdate integration
- **🔧 Configurable**: Runtime configuration via environment variables
## 📚 Client Libraries
### .NET / C#
Official NuGet package with full async/await support and dependency injection integration:
```bash
dotnet add package Bitip.Client
```
```csharp
// Register in your DI container
services.UseBitipClient("https://your-bitip-instance.com/api", "your-api-key");
// Inject and use
public class MyService
{
private readonly IBitipClient _bitipClient;
public MyService(IBitipClient bitipClient)
{
_bitipClient = bitipClient;
}
public async Task<IpLocation> LookupAsync(string ip)
{
return await _bitipClient.GetIpLocation(ip);
}
}
```
See [src/clients/dotnet/Bitip.Client/README.md](src/clients/dotnet/Bitip.Client/README.md) for complete documentation.
### Node.js / JavaScript
Coming soon! In development at [src/clients/node](src/clients/node).
### Other Languages
Use the REST API directly - see API documentation below.
## 🚀 Quick Start
### Local Development (No Docker Required)
#### Prerequisites
- Node.js >= 18.0.0
- npm >= 9.0.0
- MaxMind GeoLite2 databases (download from https://www.maxmind.com/en/geolite2/signup or use geoipupdate)
#### 1. Clone and Setup
```bash
git clone <repository-url>
cd Bitip
```
#### 2. Install Dependencies
```bash
npm run install:all
```
#### 3. Configure Environment
Create a `.env` file in the root directory:
```env
# API Keys (change these for production!)
FRONTEND_API_KEY=frontend-dev-key
EXTERNAL_API_KEYS=external-dev-key-1,external-dev-key-2
# Server Configuration
PORT=5172
BASE_PATH=/
NODE_ENV=development
ENABLE_HTTPS_SECURITY=false
LOG_LEVEL=debug # debug | info | warning | error
# Database Path - Point to your MaxMind databases location
# Both GeoLite2-City.mmdb and GeoLite2-ASN.mmdb are required
MAXMIND_DB_PATH=D:\tools\maxmind-dbs # Windows
# MAXMIND_DB_PATH=/usr/share/maxmind # Linux/Mac
# Rate Limiting Configuration
FRONTEND_RATE_WINDOW_MS=60000
FRONTEND_RATE_MAX=30
EXTERNAL_RATE_WINDOW_MS=60000
EXTERNAL_RATE_MAX=1000
# Batch Configuration
BATCH_LIMIT=100
DEBOUNCE_MS=2000
# Seq Logging (Optional)
# SEQ_URL=http://localhost:5341
# SEQ_API_KEY=your-seq-api-key
```
#### 4. Start Development Servers
```bash
npm run dev
```
This will start:
- Backend API server on http://localhost:5172
- Frontend dev server on http://localhost:5173 (or next available port)
- Frontend proxies API requests to backend
#### 5. Access the Application
- **Web Interface**: http://localhost:5173 (or the port shown in console)
- **API Endpoint**: http://localhost:5172/api
- **Health Check**: http://localhost:5172/api/health
### Production Deployment (Docker)
#### Prerequisites
- Docker and Docker Compose
- MaxMind GeoLite2 account (free): https://www.maxmind.com/en/geolite2/signup
#### 1. Configure Environment
Edit `.env` file with your MaxMind credentials and logging level:
```env
GEOIPUPDATE_ACCOUNT_ID=your_account_id_here
GEOIPUPDATE_LICENSE_KEY=your_license_key_here
FRONTEND_API_KEY=your-secure-frontend-api-key-here
EXTERNAL_API_KEYS=your-secure-external-api-key-1,your-secure-external-api-key-2
LOG_LEVEL=warning # Recommended for production (debug | info | warning | error)
```
#### 2. Start Services
```bash
docker-compose up -d
```
**Or with Docker run:**
```bash
# Build image
docker build -t bitip-geoip:latest .
# Run with custom log level
docker run -d \
-p 5172:5172 \
-e LOG_LEVEL=warning \
-e FRONTEND_API_KEY=your-api-key \
-v /path/to/maxmind-dbs:/usr/share/maxmind \
bitip-geoip:latest
```
**Available log levels:**
- `debug` - All logs (verbose, for development/troubleshooting)
- `info` - Info + warnings + errors (default)
- `warning` - Warnings + errors only (recommended for production)
- `error` - Errors only (minimal logging)
#### 3. Access the Service
- **Web Interface**: http://localhost:5172
- **API Endpoint**: http://localhost:5172/api
- **Health Check**: http://localhost:5172/api/health
## 📖 API Documentation
### Authentication
All API requests require an API key sent via header or query parameter:
```bash
# Via Header (recommended)
curl -H "X-API-Key: your-api-key" http://localhost:5172/api/lookup?ip=8.8.8.8
# Via Query Parameter
curl "http://localhost:5172/api/lookup?ip=8.8.8.8&apikey=your-api-key"
```
### Endpoints
#### Get Current IP
```http
GET /api/ip
```
Returns the client's current IP address.
**Response:**
```json
{
"ip": "203.0.113.42"
}
```
#### Simple IP Lookup
```http
GET /api/lookup?ip=8.8.8.8
```
Returns basic location information:
```json
{
"ip": "8.8.8.8",
"country": "United States",
"country_code": "US",
"is_in_european_union": false,
"region": "California",
"region_code": "CA",
"city": "Mountain View",
"latitude": 37.4056,
"longitude": -122.0775,
"timezone": "America/Los_Angeles",
"postal_code": "94043",
"continent_code": "NA",
"continent_name": "North America",
"organization": "Google LLC",
"asn": 15169
}
```
#### Detailed IP Lookup
```http
GET /api/lookup/detailed?ip=8.8.8.8
```
Returns comprehensive MaxMind database information including all available fields.
#### Batch IP Lookup
```http
POST /api/lookup/batch
Content-Type: application/json
{
"ips": ["8.8.8.8", "1.1.1.1", "208.67.222.222"]
}
```
**Response:**
```json
{
"results": [
{
"ip": "8.8.8.8",
"country": "United States",
...
},
{
"ip": "1.1.1.1",
"country": "Australia",
...
}
]
}
```
#### Health Check
```http
GET /api/health
```
Returns service health status including database connectivity.
### Error Handling
The API returns appropriate HTTP status codes:
- `400` - Bad Request (invalid IP, private IP, validation errors)
- `401` - Unauthorized (missing or invalid API key)
- `404` - Not Found (IP not in database)
- `429` - Too Many Requests (rate limit exceeded)
- `500` - Internal Server Error
- `503` - Service Unavailable (database maintenance)
## 🛠️ Development
### Project Structure
```
Bitip/
├── src/
│ ├── backend/ # Express.js API server
│ │ ├── routes/ # API route handlers
│ │ ├── services/ # Business logic (GeoIP, config, logger)
│ │ ├── middleware/ # Express middleware (auth, rate limiting)
│ │ ├── types/ # TypeScript type definitions
│ │ ├── index.ts # Main server entry point
│ │ ├── nodemon.json # Nodemon configuration
│ │ ├── tsconfig.json # TypeScript configuration
│ │ └── package.json # Backend dependencies
│ └── frontend/ # React web application
│ ├── src/
│ │ ├── components/ # React components (MapComponent)
│ │ ├── services/ # API client services
│ │ ├── types/ # TypeScript types
│ │ ├── App.tsx # Main App component
│ │ ├── App.css # Application styles
│ │ └── main.tsx # React entry point
│ ├── index.html # HTML template
│ ├── vite.config.ts # Vite configuration
│ ├── tsconfig.json # TypeScript configuration
│ └── package.json # Frontend dependencies
├── content/ # Content files (Overview.json, ReleaseNotes.json)
├── docs/ # Documentation (PRD, tech stack)
├── .env # Environment variables (not in git)
├── .env.example # Example environment file
├── Dockerfile # Production Docker image
├── package.json # Root package configuration
└── README.md
```
### Available Scripts
```bash
# Development
npm run dev # Start both frontend and backend in dev mode
npm run dev:backend # Start backend development server only
npm run dev:frontend # Start frontend development server only
# Building
npm run build # Build both frontend and backend for production
npm run build:backend # Build backend only
npm run build:frontend # Build frontend only
# Production
npm start # Start production backend server (after build)
# Code Quality
npm run lint # Lint both frontend and backend
npm run lint:fix # Fix linting issues
npm run format # Format code with Prettier
# Utilities
npm run clean # Clean build artifacts
npm run install:all # Install all dependencies (root + backend + frontend)
```
### Technology Stack
**Backend:**
- Express.js 5.x with TypeScript
- @maxmind/geoip2-node 6.x - GeoIP database reader
- node-cache - In-memory caching
- express-rate-limit 8.x - Rate limiting
- helmet - Security headers
- joi - Request validation
- seq-logging - Optional structured logging
- **tsup** - Modern bundler for fast builds (88ms vs ~1000ms with tsc) ⚡
**Frontend:**
- React 19.x with TypeScript
- Vite 7.x - Build tool and dev server
- Leaflet & react-leaflet - Interactive maps
- Axios - HTTP client
- OpenStreetMap - Map tiles
**Development Tools:**
- TypeScript 5.x
- ESLint & Prettier
- nodemon - Auto-restart on changes
- tsx - TypeScript execution
**Build System:**
- **tsup** (backend) - esbuild-based bundler with ESM support, no `.js` extensions needed
- **Vite** (frontend) - Lightning-fast HMR and optimized production builds
> 📖 See [tsup Migration Guide](docs/tsup-migration.md) for details on the modern build system.
## ⚙️ Configuration
### Environment Variables
| Variable | Default | Description |
| -------------------------- | ---------------------- | ----------------------------------------------------- |
| `PORT` | `5172` | Server port |
| `BASE_PATH` | `/` | Application base path |
| `NODE_ENV` | `development` | Environment mode (development/production) |
| `ENABLE_HTTPS_SECURITY` | `false` | Enable HTTPS security headers (CSP, HSTS, COOP, CORP) |
| `MAXMIND_DB_PATH` | `/usr/share/maxmind` | MaxMind database directory |
| `FRONTEND_API_KEY` | `frontend-default-key` | Frontend API key |
| `EXTERNAL_API_KEYS` | `external-default-key` | External API keys (comma-separated) |
| `FRONTEND_ALLOWED_ORIGINS` | `http://localhost:*` | Allowed CORS origins for frontend (comma-separated) |
| `FRONTEND_RATE_WINDOW_MS` | `60000` | Frontend rate limit window (milliseconds) |
| `FRONTEND_RATE_MAX` | `30` | Frontend rate limit max requests |
| `EXTERNAL_RATE_WINDOW_MS` | `60000` | External rate limit window (milliseconds) |
| `EXTERNAL_RATE_MAX` | `1000` | External rate limit max requests |
| `BATCH_LIMIT` | `100` | Maximum IPs per batch request |
| `DEBOUNCE_MS` | `2000` | Frontend input debounce delay (milliseconds) |
| `SEQ_URL` | - | Seq logging server URL (optional) |
| `SEQ_API_KEY` | - | Seq API key (optional) |
### MaxMind Database Setup
The service requires both MaxMind GeoLite2-City and GeoLite2-ASN databases. You have two options:
**Option 1: Manual Download**
1. Sign up at https://www.maxmind.com/en/geolite2/signup
2. Download both databases (`.mmdb` files):
- GeoLite2-City.mmdb
- GeoLite2-ASN.mmdb
3. Place them in the same directory (e.g., `D:\tools\maxmind-dbs` on Windows)
4. Set `MAXMIND_DB_PATH` environment variable to that directory
**Option 2: Using geoipupdate (Production)**
- Use the provided `docker-compose.yml` which includes geoipupdate service
- geoipupdate automatically downloads and updates both databases
- Both services share a Docker volume for database access
### Rate Limiting
Bitip implements different rate limiting for frontend and external API consumers:
- **Frontend**: More restrictive limits for web UI usage (default: 100 req/min)
- **External**: Higher limits for programmatic API access (default: 1000 req/min)
Rate limits are fully configurable via environment variables and include standard HTTP headers in responses.
### HTTPS Security Headers
The `ENABLE_HTTPS_SECURITY` variable controls security headers provided by Helmet:
- **`false` (default)**: Disables CSP, HSTS, COOP, and CORP headers - required for HTTP deployments
- **`true`**: Enables all security headers - use when deploying behind HTTPS reverse proxy (nginx, Traefik, etc.)
**Important**: If running on plain HTTP without a reverse proxy, keep this set to `false`. Browser security policies will block resources if HTTPS security headers are enabled on HTTP connections.
## 🐳 Docker Deployment
### Production Setup
The service is designed to run alongside MaxMind's geoipupdate service:
```bash
# Start both services
docker-compose up -d
# View logs
docker-compose logs -f bitip
# Stop services
docker-compose down
```
The `docker-compose.yml` includes:
- **geoipupdate**: Downloads and updates MaxMind databases
- **bitip**: Main application server (API + Web UI)
- **Shared volume**: For database access between services
### Health Monitoring
The service includes comprehensive health checks:
- Docker health check endpoint: `/api/health`
- Database connectivity verification
- Service status monitoring
## 🔧 Troubleshooting
### Common Issues
**1. Database Not Found**
- Ensure both databases are downloaded to the path specified in `MAXMIND_DB_PATH`
- Check that both `GeoLite2-City.mmdb` and `GeoLite2-ASN.mmdb` files exist in that directory
- Verify file permissions (read access required)
**2. TypeScript Errors**
- Run `npm run install:all` to ensure all dependencies are installed
- Check that Node.js version is >= 18.0.0
- Try deleting `node_modules` and reinstalling
**3. API Authentication Errors**
- Verify API key in `.env` file matches the one you're using
- Check `X-API-Key` header or `apikey` query parameter format
- Ensure API key doesn't contain extra spaces
**4. Rate Limiting**
- Check rate limit headers in API responses (`X-RateLimit-*`)
- Adjust rate limiting configuration if needed
- Use external API keys for higher limits
**5. Map Display Issues**
- Verify internet connectivity for OpenStreetMap tiles
- Check browser console for JavaScript errors
- Ensure Leaflet CSS is loading correctly
**6. Port Already in Use**
- Frontend dev server will auto-increment port (5173, 5174, etc.)
- Backend port can be changed via `PORT` environment variable
- Check for other services using the same ports
### Logs and Debugging
- Application logs are printed to console
- Use `npm run dev` for detailed development logs
- Configure Seq integration for structured logging
- Docker logs: `docker-compose logs -f bitip`
## 📦 Package Versions
**Current versions (as of project creation):**
- Major packages are on stable versions but not latest
- Consider updating for newer features and security fixes
- Check `npm outdated` for available updates
- Test thoroughly after major version updates
**Key outdated packages:**
- Express 4.x (5.x available but still beta)
- React 18.x (19.x available)
- Vite 4.x (7.x available - major update)
- Many dev dependencies have newer versions
## 📄 License
**Copyright © 2025 Tudor Stanciu. All rights reserved.**
This software is **proprietary** and confidential. Unauthorized use, copying, modification, distribution, or reverse engineering of this software, in whole or in part, is strictly prohibited without explicit written permission from the copyright holder.
### License Summary
-**Evaluation Period**: 30-day trial for evaluation purposes
-**Approved Use**: Requires explicit written approval from Tudor Stanciu
-**No Redistribution**: Cannot be distributed, sublicensed, or transferred to third parties
-**No Modification**: Cannot be modified or create derivative works without permission
-**No Commercial Use**: Cannot be used for commercial services without separate license
### Obtaining a License
For licensing inquiries, commercial use, or approval requests:
**Contact**: Tudor Stanciu
**Email**: tudor.stanciu94@gmail.com
Please include:
- Intended use case
- Organization name and size
- Expected deployment scale
- Duration of use
See [LICENSE](LICENSE) file for complete terms and conditions.
## 🙏 Acknowledgments
- **MaxMind** for providing GeoLite2 databases
- **OpenStreetMap** for map tiles
- **Leaflet** for interactive mapping
- All open-source contributors
---
**Bitip** - Professional GeoIP Lookup Service 🌍
Built with ❤️ using Express.js, React, and MaxMind GeoLite2