2026-01-18 01:43:27 +00:00
2026-01-18 00:53:17 +00:00
2026-01-17 20:43:29 +00:00
2026-01-18 01:43:27 +00:00
2026-01-16 20:13:07 +00:00
2026-01-18 01:29:39 +00:00
2026-01-17 21:11:11 +00:00
2026-01-17 21:06:07 +00:00
2026-01-17 23:51:09 +00:00

Geofeed 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.

Features

  • Modern Apple-esque UI - Clean, responsive interface with dark mode support
  • RFC 8805 Compliant - Generates valid geofeed CSV files per the specification
  • Authentication - Secure login with environment-based credentials
  • 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 to your geofeed with detailed history
  • IP Enrichment - Automatic ISP, hostname, and security flag data via ipregistry.co
  • Client Logos - Associate logo images with client shortnames
  • Webhook Integration - Debounced n8n webhooks for on-demand 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

What's New

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

Authentication

  • Secure login page with session-based authentication
  • Credentials configured via environment variables
  • Automatic session timeout after 24 hours

Webhook System

  • On-demand webhook notifications to n8n (replaces hourly polling)
  • Debouncing to batch multiple changes and reduce API calls
  • Queue status monitoring in the Advanced tab

UI Improvements

  • Dark mode with automatic OS detection
  • Mobile Safari optimizations with safe area support
  • Client logo management with grid display
  • Wider table layout for better data visibility

Directory Structure

geofeed-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
│   ├── error.log           # PHP error log (auto-created)
│   └── .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):
# Git Repository
GIT_REPO=https://git.prpl.tools/PurpleComputing/geofeed-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
AUTH_USERNAME=admin
AUTH_PASSWORD=your_secure_admin_password

# IP Registry (optional - for IP enrichment)
IPREGISTRY_API_KEY=your_ipregistry_api_key

# Cloudflare Tunnel (optional)
CLOUDFLARE_TUNNEL_TOKEN=your_tunnel_token
  1. Deploy with Docker Compose:
docker compose up -d
  1. Access the web interface at http://your-server:8080

  2. Login with your configured credentials (default: admin/changeme)

  3. Import your geofeed via the Advanced tab in the UI

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:

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

Authentication is required to access the application. Configure credentials via environment variables:

AUTH_USERNAME=admin
AUTH_PASSWORD=your_secure_password

Default Credentials:

  • Username: admin
  • Password: changeme

Warning: Change the default password immediately after deployment! Set AUTH_PASSWORD in your .env file or environment variables.

The login session expires after 24 hours of inactivity.

IP Registry Integration

To enable automatic IP enrichment:

  1. Sign up for a free API key at ipregistry.co
  2. Set the API key via environment variable:
    IPREGISTRY_API_KEY=your_api_key
    
    Or configure it in the Advanced tab of the web interface.
  3. Enable auto-enrichment in the Advanced tab

When enabled, new IP entries are automatically enriched with:

  • Hostname (reverse DNS)
  • ISP and organization name
  • ASN information
  • Connection type
  • Timezone and coordinates
  • Security flags (proxy, VPN, Tor, threat, etc.)

AWS Route53 Integration

Configure AWS credentials in the Advanced tab to enable PTR record checking:

  1. Create an IAM user in AWS with route53:ListHostedZones and route53:ListResourceRecordSets permissions
  2. Generate an access key and secret key for the IAM user
  3. In the Advanced tab, enter:
    • AWS Access Key ID - Your IAM access key
    • AWS Secret Access Key - Your IAM secret key
    • AWS Region - Select your preferred region (Route53 is global, but a region is required for API signing)
    • Hosted Zone IDs - Comma-separated list of Route53 hosted zone IDs (e.g., Z1234567890ABC, Z0987654321DEF)
  4. Click "Test Connection" to verify credentials
  5. Go to the PTR tab to view A records and check PTR status

IAM Policy Example:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "route53:ListHostedZones",
                "route53:ListResourceRecordSets",
                "route53:GetHostedZone"
            ],
            "Resource": "*"
        }
    ]
}

Webhook Integration

Configure webhooks in the Advanced tab to notify n8n when data changes:

  1. Enter your n8n webhook URL
  2. Set the debounce delay (1-60 minutes)
  3. Enable webhook notifications

The system batches multiple changes within the debounce window to reduce API calls.

n8n Workflow Setup

  1. In n8n, go to Settings > Environment Variables and add:

    • BUNNY_STORAGE_ZONE - Your BunnyCDN storage zone name
    • BUNNY_API_KEY - Your BunnyCDN Storage API key
  2. Create MySQL credentials in n8n:

    • Go to Credentials
    • Add new MySQL credential
    • Configure with your database details
    • Note the credential ID
  3. Import the workflow:

    • Go to Workflows
    • Click Import from File
    • Select n8n/geofeed-export-workflow.json
  4. Update credential references:

    • Open the imported workflow
    • For each MySQL node, select your MySQL credential
    • Save the workflow
  5. Activate the workflow - it will trigger via webhook when data changes

Developer Tools

Access developer tools via the Developer tab in the web interface.

Database Backup & Restore

  • Download Full Backup - Exports all data as a timestamped JSON file including:

    • All geofeed entries with enrichment data
    • Application settings
    • Client logos
    • Last 1000 audit log entries
  • Import Backup - Restore from a previously exported JSON file

    • Validates backup structure before import
    • Replaces all existing data
    • Shows import summary with counts

Database Schema Sync

Keep your database schema up-to-date with the latest code:

  1. Click Check for Updates to compare your database against the repository schema
  2. View missing tables, columns, and indexes
  3. Click Apply Schema Updates to add missing elements

This is useful after pulling new code that includes database changes.

PHP Error Logs

  • View recent PHP errors directly in the browser
  • Filter by number of lines (50, 100, 250, 500)
  • Color-coded by severity (fatal, error, warning, notice)
  • Clear logs with one click

System Information

View current system status:

  • App and PHP versions
  • Server software and timezone
  • Database statistics (entries, enriched count, settings, audit log size)
  • Database size on disk

API Reference

Authentication

All API endpoints (except export and webhook_process) require authentication.

List Entries

GET api.php?action=list&page=1&limit=25&search=term&country=GB&sort=ip|custom

Get Single Entry

GET api.php?action=get&id=123

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

Get Statistics

GET api.php?action=stats

Enrich Single IP

POST api.php?action=enrich_ip
Content-Type: application/json

{
  "id": 123,
  "csrf_token": "..."
}

Enrich All Un-enriched IPs

POST api.php?action=enrich_all
Content-Type: application/json

{
  "csrf_token": "..."
}

Database Backup

GET api.php?action=database_backup

Returns a JSON file download with full database backup.

Database Import

POST api.php?action=database_import
Content-Type: application/json

{
  "backup_data": { ... },
  "csrf_token": "..."
}

Schema Check

GET api.php?action=schema_check

Returns missing tables, columns, and indexes compared to repository schema.

Schema Apply

POST api.php?action=schema_apply
Content-Type: application/json

{
  "csrf_token": "..."
}

Error Logs

GET api.php?action=error_logs&lines=100

Clear Error Logs

POST api.php?action=error_logs_clear
Content-Type: application/json

{
  "csrf_token": "..."
}

System Info

GET api.php?action=system_info

AWS Settings

GET api.php?action=aws_settings_get

Returns current AWS Route53 configuration.

POST api.php?action=aws_settings_save
Content-Type: application/json

{
  "aws_access_key_id": "AKIAIOSFODNN7EXAMPLE",
  "aws_secret_access_key": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
  "aws_region": "us-east-1",
  "aws_hosted_zones": "Z1234567890ABC, Z0987654321DEF",
  "csrf_token": "..."
}

Test AWS Connection

GET api.php?action=aws_test

Tests AWS credentials and returns hosted zone count.

List AWS Hosted Zones

GET api.php?action=aws_zones

Returns list of configured hosted zones with their names and IDs.

List A Records

GET api.php?action=aws_records&zone_id=Z1234567890ABC

Returns all A records from the specified hosted zone.

PTR Lookup

GET api.php?action=ptr_lookup&ip=192.168.1.1

Performs reverse DNS lookup and returns the PTR record for the given IP.

Get Whitelabel Settings

GET api.php?action=whitelabel_get

Returns current whitelabel configuration (company name, icon URL, favicon URL, default import URL).

Save Whitelabel Settings

POST api.php?action=whitelabel_save
Content-Type: application/json

{
  "company_name": "My Company",
  "icon_url": "https://example.com/logo.svg",
  "favicon_url": "https://example.com/favicon.ico",
  "default_import_url": "https://example.com/geofeed.csv",
  "csrf_token": "..."
}

Geofeed Format (RFC 8805)

Each line in the exported CSV follows this format:

ip_prefix,country_code,region_code,city,postal_code

Example:

# Geofeed - Generated by Geofeed 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. The workflow uploads to: https://storage.bunnycdn.com/{zone}/geofeed.csv
  4. 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 AUTH_USERNAME and AUTH_PASSWORD environment variables are set
  • Check container logs for authentication errors
  • Clear browser cookies and try again

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 the Advanced tab
  • Review error logs in the Developer tab for API errors

Hostname not showing

  • Hostname requires re-enriching entries (the API parameter was added recently)
  • Click the globe icon on individual entries to re-enrich them

n8n workflow fails

  • Check that environment variables are set correctly
  • Verify MySQL credentials are configured
  • Check BunnyCDN API key permissions

Web interface shows database error

  • Verify database credentials in environment variables
  • Ensure the database and tables exist
  • Check MySQL/MariaDB is running
  • Try running Schema Sync in the Developer tab

Missing columns after update

  • Go to Developer tab
  • Click "Check for Updates"
  • Apply any missing schema changes

Dark mode not working

  • Ensure your browser/OS has dark mode enabled
  • Try clearing browser cache

AWS Route53 connection fails

  • Verify your AWS Access Key ID and Secret Access Key are correct
  • Ensure the IAM user has the required permissions (ListHostedZones, ListResourceRecordSets)
  • Check that the hosted zone IDs are correct (format: Z followed by alphanumeric characters)
  • Review error logs in the Developer tab for detailed error messages

PTR records showing as MISSING

  • PTR records are managed by your IP provider (e.g., IPXO, your ISP, or cloud provider)
  • Contact your IP provider to set up reverse DNS for your IP addresses
  • PTR lookups use the server's DNS resolver - results may vary based on DNS propagation

PTR records showing as MISMATCH

  • The PTR record exists but doesn't match the expected hostname
  • Verify the PTR is set correctly with your IP provider
  • Note: Trailing dots in hostnames are normalized during comparison

License

MIT License - Feel free to use and modify as needed.


Built with care by Purple Computing

Description
No description provided
Readme 2.3 MiB
Languages
PHP 77.2%
JavaScript 18.3%
CSS 4.5%