# 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)