- Add license.php with tiered licensing (Trial, Basic, Professional, Enterprise) - Add license_info table to database schema - Add license management UI to settings (License tab) - Add license status, activation, and usage API endpoints - Add entry and user limit enforcement based on license tier - Add feature flags for webhooks, IP enrichment, whitelabel, PTR records - Update README with licensing documentation and customer deployment guide Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
488 lines
16 KiB
Markdown
488 lines
16 KiB
Markdown
# ISP IP Manager
|
|
|
|
A complete solution for managing RFC 8805 compliant IP geolocation feeds (geofeeds). This system provides a modern web interface for managing geofeed entries, stores data in MariaDB/MySQL, and automatically exports to BunnyCDN via n8n workflows.
|
|
|
|
**Copyright (c) 2025 Purple Computing Ltd. All rights reserved.**
|
|
|
|
This is proprietary closed-source software. Unauthorized copying, modification, distribution, or use of this software is strictly prohibited.
|
|
|
|
## Features
|
|
|
|
- **Modern Apple-esque UI** - Clean, responsive interface with dark mode support
|
|
- **RFC 8805 Compliant** - Generates valid geofeed CSV files per the specification
|
|
- **Role-Based Access Control** - Admin and staff roles with Cloudflare Access integration
|
|
- **CRUD Operations** - Create, read, update, and delete geofeed entries
|
|
- **Search & Filter** - Find entries by IP prefix, city, region, or country
|
|
- **Audit Logging** - Track all changes with user attribution (email-based)
|
|
- **IP Enrichment** - Automatic ISP, hostname, and security flag data via ipregistry.co
|
|
- **Client Logos** - Associate logo images with client shortnames
|
|
- **Webhook Integration** - Immediate or debounced n8n webhooks for CDN updates
|
|
- **Mobile Optimized** - Full mobile Safari support with PWA capabilities
|
|
- **CSRF Protection** - Secure form submissions
|
|
- **Developer Tools** - Database backup/restore, schema sync, and error log viewer
|
|
- **PTR Record Management** - AWS Route53 integration for checking reverse DNS records
|
|
- **Cache Busting** - Automatic JavaScript versioning for reliable deployments
|
|
|
|
## What's New
|
|
|
|
### Webhook System Improvements
|
|
- **Immediate Webhooks** - Set delay to 0 for instant webhook delivery when entries change
|
|
- **Queue Management** - Clear pending, failed, or all webhook history from the UI
|
|
- **Automatic Processing** - Webhooks now process automatically (no cron required for immediate mode)
|
|
- **Queue Status** - View pending, completed, and failed webhooks with HTTP status codes
|
|
|
|
### User Management & Authentication
|
|
- **Cloudflare Access Integration** - Users authenticated via CF Access headers
|
|
- **Database-Driven Roles** - Admin users stored in `admin_users` table
|
|
- **User Attribution** - Audit log now shows user email instead of IP address
|
|
- **Display Names** - Optional display names for admin users
|
|
|
|
### UI Improvements
|
|
- **Client Settings Tab** - Renamed from "Advanced" for clarity
|
|
- **Cache Busting** - JavaScript files now include version parameter to prevent stale caches
|
|
- **Improved Error Handling** - Better error messages for webhook failures
|
|
|
|
### Whitelabel Settings
|
|
- **Custom Branding** - Customize the application with your company name and logo
|
|
- **Webapp Icon** - Set a custom header icon (SVG or PNG)
|
|
- **Favicon** - Set a custom browser favicon
|
|
- **Default Import URL** - Pre-populate the CSV import URL field
|
|
- **Live Preview** - See branding changes before saving
|
|
|
|
### PTR Records Tab
|
|
- **AWS Route53 Integration** - Connect to your AWS account to list A records from hosted zones
|
|
- **PTR Lookup** - Check if PTR (reverse DNS) records match your forward DNS hostnames
|
|
- **Bulk Checking** - Check all PTR records in a zone with one click
|
|
- **Status Indicators** - Visual indicators for MATCH, MISMATCH, and MISSING PTR records
|
|
- **Zone Selector** - Easily switch between multiple hosted zones
|
|
- **Auto-Select Single Zone** - When only one zone is configured, it's automatically selected
|
|
- **Local Caching** - A records are cached locally for faster access
|
|
|
|
### Developer Mode Tab
|
|
- **Database Backup** - Export full database backup as JSON (entries, settings, logos, audit log)
|
|
- **Database Import** - Restore from a previously exported backup file
|
|
- **Schema Sync** - Check for and apply missing database columns/tables from the repository
|
|
- **PHP Error Logs** - View, filter, and clear PHP error logs directly in the UI
|
|
- **System Information** - View app version, PHP version, database stats, and server info
|
|
|
|
### Entry Details Modal
|
|
- Click the info (i) icon on any entry to view full details
|
|
- Shows all enrichment data including hostname, ISP, ASN, coordinates
|
|
- Displays all 11 security flags with checkmarks and crosses
|
|
- Shows record timestamps (created, updated, enriched)
|
|
|
|
### IP Registry Integration
|
|
- Automatic IP enrichment when entries are created or imported
|
|
- **Hostname lookup** - Reverse DNS hostname for each IP
|
|
- ISP and organization data displayed in the table
|
|
- Security flags for: Abuser, Attacker, Bogon, Cloud Provider, Proxy, Relay, Tor, Tor Exit, VPN, Anonymous, Threat
|
|
- Manual enrichment option for existing entries
|
|
|
|
## Directory Structure
|
|
|
|
```
|
|
ip-manager/
|
|
├── database/
|
|
│ ├── schema.sql # Database schema
|
|
│ └── import_csv.php # CSV import utility (CLI)
|
|
├── webapp/
|
|
│ ├── config.php # Configuration & helpers
|
|
│ ├── api.php # RESTful API endpoints
|
|
│ ├── login.php # Authentication page
|
|
│ ├── index.php # Main web interface
|
|
│ ├── settings.php # Settings & admin interface
|
|
│ ├── includes/
|
|
│ │ ├── app.js # Main application JavaScript
|
|
│ │ ├── auth.php # Authentication & RBAC helpers
|
|
│ │ ├── header.php # Page header
|
|
│ │ └── footer.php # Page footer with cache-busted JS
|
|
│ └── .htaccess # Security rules
|
|
├── n8n/
|
|
│ └── geofeed-export-workflow.json # n8n workflow
|
|
├── docker-compose.yml # Docker Compose configuration
|
|
└── .env.example # Environment variables template
|
|
```
|
|
|
|
## Installation (Docker / Dokploy)
|
|
|
|
The application automatically pulls code from the Git repository on startup - no local files needed!
|
|
|
|
### Quick Start
|
|
|
|
1. **Set environment variables** in Dokploy (or create `.env` file):
|
|
|
|
```env
|
|
# Git Repository
|
|
GIT_REPO=https://git.prpl.tools/PurpleComputing/ip-manager.git
|
|
GIT_BRANCH=main
|
|
|
|
# Database
|
|
DB_ROOT_PASSWORD=your_secure_root_password
|
|
DB_NAME=geofeed_manager
|
|
DB_USER=geofeed
|
|
DB_PASSWORD=your_secure_password
|
|
|
|
# Authentication (fallback when Cloudflare Access not available)
|
|
AUTH_USERNAME=admin
|
|
AUTH_PASSWORD=your_secure_admin_password
|
|
|
|
# Admin Users (comma-separated emails for initial seeding)
|
|
ADMIN_EMAILS=admin@example.com,user@example.com
|
|
|
|
# IP Registry (optional - for IP enrichment)
|
|
IPREGISTRY_API_KEY=your_ipregistry_api_key
|
|
|
|
# Cloudflare Tunnel (optional)
|
|
CLOUDFLARE_TUNNEL_TOKEN=your_tunnel_token
|
|
```
|
|
|
|
2. **Deploy with Docker Compose:**
|
|
|
|
```bash
|
|
docker compose up -d
|
|
```
|
|
|
|
3. **Access the web interface** at `http://your-server:8080`
|
|
|
|
4. **Login** with your configured credentials or via Cloudflare Access
|
|
|
|
5. **Import your geofeed** via the Client Settings tab in Settings
|
|
|
|
### How It Works
|
|
|
|
On startup, a `git-sync` container:
|
|
1. Clones the repository from Git
|
|
2. Copies `webapp/` files to the PHP container volume
|
|
3. Copies `database/schema.sql` for MariaDB initialization
|
|
4. Exits after sync completes
|
|
|
|
The webapp and database containers then start with the synced code.
|
|
|
|
### Updating Code
|
|
|
|
To pull the latest code from Git, simply restart the stack:
|
|
|
|
```bash
|
|
docker compose down
|
|
docker compose up -d
|
|
```
|
|
|
|
Or in Dokploy, just redeploy the service.
|
|
|
|
**Schema Updates:** After pulling new code, go to the Developer tab and click "Check for Updates" to apply any new database columns or tables.
|
|
|
|
### Container Details
|
|
|
|
| Service | Port | Description |
|
|
|---------|------|-------------|
|
|
| webapp | 8080 | PHP web interface |
|
|
| mariadb | 3306 | MariaDB database (exposed for n8n) |
|
|
| git-sync | - | Pulls code on startup, then exits |
|
|
| cloudflared | - | Cloudflare Tunnel (optional) |
|
|
| phpmyadmin | 8081 | Database admin (optional, use `--profile admin`) |
|
|
|
|
## Configuration
|
|
|
|
### Authentication
|
|
|
|
The application supports two authentication methods:
|
|
|
|
**1. Cloudflare Access (Recommended)**
|
|
- Users are authenticated via Cloudflare Access headers
|
|
- Email is read from `CF-Access-Authenticated-User-Email` header
|
|
- Roles are determined by the `admin_users` database table
|
|
|
|
**2. Session-based Authentication (Fallback)**
|
|
- Used when Cloudflare Access headers are not present
|
|
- Configure via environment variables:
|
|
```env
|
|
AUTH_USERNAME=admin
|
|
AUTH_PASSWORD=your_secure_password
|
|
```
|
|
|
|
### User Roles
|
|
|
|
- **Admin** - Full access to all features including user management and danger zone
|
|
- **Staff** - Standard access to geofeed management features
|
|
|
|
Admin users are stored in the `admin_users` table and can be managed via the Users tab in Settings.
|
|
|
|
### IP Registry Integration
|
|
|
|
To enable automatic IP enrichment:
|
|
|
|
1. Sign up for a free API key at [ipregistry.co](https://ipregistry.co)
|
|
2. Set the API key via environment variable:
|
|
```env
|
|
IPREGISTRY_API_KEY=your_api_key
|
|
```
|
|
Or configure it in Settings > n8n Integration tab.
|
|
3. Enable auto-enrichment in the settings
|
|
|
|
### AWS Route53 Integration
|
|
|
|
Configure AWS credentials in the Settings > n8n Integration tab to enable PTR record checking:
|
|
|
|
1. Create an IAM user in AWS with Route53 read permissions
|
|
2. Generate an access key and secret key for the IAM user
|
|
3. Enter AWS credentials in the settings
|
|
4. Click "Test Connection" to verify credentials
|
|
5. Go to the PTR tab to view A records and check PTR status
|
|
|
|
### Webhook Integration
|
|
|
|
Configure webhooks in Settings > n8n Integration tab:
|
|
|
|
1. Enter your n8n webhook URL
|
|
2. Set the debounce delay (0 for immediate, 1-60 minutes for batched)
|
|
3. Enable webhook notifications
|
|
|
|
**Immediate Mode (delay = 0):**
|
|
- Webhooks are sent instantly when entries change
|
|
- Each change triggers a separate webhook
|
|
- Best for real-time updates
|
|
|
|
**Batched Mode (delay > 0):**
|
|
- Multiple changes within the delay window are consolidated
|
|
- Reduces API calls for bulk operations
|
|
- Webhooks process when the delay expires
|
|
|
|
### Webhook Queue Management
|
|
|
|
The webhook queue can be managed from the n8n Integration tab:
|
|
|
|
- **View Status** - See pending, completed, and failed webhooks
|
|
- **Clear Pending** - Remove webhooks waiting to be sent
|
|
- **Clear Failed** - Remove failed webhook records
|
|
- **Clear All** - Remove entire webhook history
|
|
|
|
## API Reference
|
|
|
|
### Authentication
|
|
All API endpoints (except `export` and `webhook_process`) require authentication.
|
|
|
|
### Webhook Queue Clear
|
|
```
|
|
POST api.php?action=webhook_queue_clear
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"clear_type": "pending|failed|all",
|
|
"csrf_token": "..."
|
|
}
|
|
```
|
|
|
|
### List Entries
|
|
```
|
|
GET api.php?action=list&page=1&limit=25&search=term&country=GB&sort=ip|custom
|
|
```
|
|
|
|
### Create Entry
|
|
```
|
|
POST api.php?action=create
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"ip_prefix": "192.168.1.0/24",
|
|
"country_code": "GB",
|
|
"region_code": "GB-ENG",
|
|
"city": "London",
|
|
"postal_code": "EC1A 1BB",
|
|
"client_short_name": "acme",
|
|
"notes": "Main office",
|
|
"csrf_token": "..."
|
|
}
|
|
```
|
|
|
|
### Update Entry
|
|
```
|
|
POST api.php?action=update
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"id": 123,
|
|
"ip_prefix": "192.168.1.0/24",
|
|
"country_code": "GB",
|
|
"region_code": "GB-ENG",
|
|
"city": "Manchester",
|
|
"postal_code": "M1 1AA",
|
|
"csrf_token": "..."
|
|
}
|
|
```
|
|
|
|
### Delete Entry
|
|
```
|
|
POST api.php?action=delete
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"id": 123,
|
|
"csrf_token": "..."
|
|
}
|
|
```
|
|
|
|
### Export CSV
|
|
```
|
|
GET api.php?action=export&format=download
|
|
```
|
|
|
|
## Geofeed Format (RFC 8805)
|
|
|
|
Each line in the exported CSV follows this format:
|
|
|
|
```
|
|
ip_prefix,country_code,region_code,city,postal_code
|
|
```
|
|
|
|
Example:
|
|
```csv
|
|
# Geofeed - Generated by ISP IP Manager
|
|
# Format: ip_prefix,country_code,region_code,city,postal_code
|
|
192.168.1.0/24,GB,GB-ENG,London,EC1A 1BB
|
|
10.0.0.0/8,US,US-CA,San Francisco,94105
|
|
2001:db8::/32,DE,DE-BY,Munich,80331
|
|
```
|
|
|
|
## BunnyCDN Setup
|
|
|
|
1. Create a Storage Zone in BunnyCDN
|
|
2. Get your Storage API key from the FTP & API Access section
|
|
3. Use the regional endpoint URL (e.g., `uk.storage.bunnycdn.com` for UK)
|
|
4. Configure the n8n HTTP Request node with:
|
|
- Method: PUT
|
|
- URL: `https://uk.storage.bunnycdn.com/{zone}/geofeed.csv`
|
|
- Headers: `AccessKey: your-storage-password`, `Content-Type: application/octet-stream`
|
|
5. Your public URL will be: `https://{zone}.b-cdn.net/geofeed.csv`
|
|
|
|
## Security Considerations
|
|
|
|
- Always use HTTPS in production (use Cloudflare Tunnel or reverse proxy)
|
|
- Change the default admin password immediately
|
|
- Keep your database credentials secure
|
|
- The application uses session-based authentication with CSRF protection
|
|
- IP Registry API keys are stored securely and masked in the UI
|
|
- Input validation is performed on all fields
|
|
- Error logs are protected from direct web access via .htaccess
|
|
|
|
## Troubleshooting
|
|
|
|
### Cannot login
|
|
- Verify Cloudflare Access is configured correctly
|
|
- Check AUTH_USERNAME and AUTH_PASSWORD environment variables
|
|
- Clear browser cookies and try again
|
|
|
|
### Webhooks not sending
|
|
- Ensure webhook URL is configured and enabled
|
|
- Set delay to 0 for immediate delivery
|
|
- Check the webhook queue status for errors
|
|
- Verify n8n workflow is active and in "Production" mode
|
|
|
|
### Webhook shows as failed
|
|
- Check the HTTP response code in the queue status
|
|
- 404 - Webhook URL not found or n8n workflow not active
|
|
- 401/403 - Authentication issue with the webhook endpoint
|
|
|
|
### Stale JavaScript (old version running)
|
|
- The app includes automatic cache busting via version parameters
|
|
- If issues persist, clear browser cache or use incognito mode
|
|
- Redeploy the application to trigger a new git pull
|
|
|
|
### Import fails with "Invalid IP prefix"
|
|
Ensure your IP prefixes are in valid CIDR notation (e.g., `192.168.1.0/24`)
|
|
|
|
### IP enrichment not working
|
|
- Verify your ipregistry.co API key is valid
|
|
- Check that auto-enrichment is enabled in Settings
|
|
- Review error logs in the Developer tab for API errors
|
|
|
|
### n8n workflow fails
|
|
- Check that environment variables are set correctly
|
|
- Verify MySQL credentials are configured
|
|
- Check BunnyCDN API key permissions
|
|
|
|
### Missing columns after update
|
|
- Go to Developer tab
|
|
- Click "Check for Updates"
|
|
- Apply any missing schema changes
|
|
|
|
## Licensing
|
|
|
|
ISP IP Manager uses a tiered licensing system. Each deployment requires a valid license key.
|
|
|
|
### License Tiers
|
|
|
|
| Feature | Trial | Basic | Professional | Enterprise |
|
|
|---------|-------|-------|--------------|------------|
|
|
| Duration | 14 days | 1 year | 1 year | Perpetual |
|
|
| Max Entries | 100 | 500 | 2,500 | Unlimited |
|
|
| Max Users | 2 | 5 | 15 | Unlimited |
|
|
| Basic CRUD | ✓ | ✓ | ✓ | ✓ |
|
|
| CSV Export | ✓ | ✓ | ✓ | ✓ |
|
|
| Webhooks | ✗ | ✓ | ✓ | ✓ |
|
|
| Audit Log | ✗ | ✓ | ✓ | ✓ |
|
|
| IP Enrichment | ✗ | ✗ | ✓ | ✓ |
|
|
| Whitelabel | ✗ | ✗ | ✓ | ✓ |
|
|
| PTR Records | ✗ | ✗ | ✓ | ✓ |
|
|
| API Access | ✗ | ✗ | ✗ | ✓ |
|
|
| Priority Support | ✗ | ✗ | ✗ | ✓ |
|
|
|
|
### License Key Format
|
|
|
|
License keys follow the format: `IPMAN-XXXX-XXXX-XXXX-XXXX`
|
|
|
|
The first character after `IPMAN-` determines the license tier:
|
|
- `B` - Basic license
|
|
- `P` - Professional license
|
|
- `E` - Enterprise license
|
|
- Any other character - Trial license
|
|
|
|
### Activating a License
|
|
|
|
1. Navigate to **Settings > License** tab
|
|
2. Enter your license key in the format `IPMAN-XXXX-XXXX-XXXX-XXXX`
|
|
3. Enter your company/licensee name
|
|
4. Enter your billing email address
|
|
5. Click **Activate License**
|
|
|
|
The license status will update immediately showing your tier and usage limits.
|
|
|
|
### Customer Deployment
|
|
|
|
Each ISP customer deploys their own dedicated instance:
|
|
|
|
1. **Provision Infrastructure**
|
|
- Deploy using Docker Compose or Dokploy
|
|
- Configure MariaDB database
|
|
- Set up Cloudflare Access for authentication (recommended)
|
|
|
|
2. **Configure Environment**
|
|
```env
|
|
DB_NAME=geofeed_manager
|
|
DB_USER=geofeed
|
|
DB_PASSWORD=secure_password
|
|
ADMIN_EMAILS=admin@customer-isp.com
|
|
```
|
|
|
|
3. **Activate License**
|
|
- Provide the customer with their license key
|
|
- Customer activates via Settings > License tab
|
|
- License determines available features and limits
|
|
|
|
4. **Optional Integrations**
|
|
- **Webhooks** (Basic+): Configure n8n for CDN automation
|
|
- **IP Enrichment** (Professional+): Add ipregistry.co API key
|
|
- **PTR Records** (Professional+): Configure AWS Route53 credentials
|
|
- **Whitelabel** (Professional+): Customize branding with customer logo
|
|
|
|
### Generating License Keys
|
|
|
|
Contact Purple Computing for license key generation:
|
|
- Email: info@purplecomputing.com
|
|
- Include: Customer name, email, desired tier
|
|
|
|
---
|
|
|
|
**Copyright (c) 2025 Purple Computing Ltd. All rights reserved.**
|
|
|
|
Built by [Purple Computing](https://purplecomputing.com)
|