Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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
- Set environment variables in Dokploy (or create
.envfile):
# 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
- Deploy with Docker Compose:
docker compose up -d
-
Access the web interface at
http://your-server:8080 -
Login with your configured credentials (default: admin/changeme)
-
Import your geofeed via the Advanced tab in the UI
How It Works
On startup, a git-sync container:
- Clones the repository from Git
- Copies
webapp/files to the PHP container volume - Copies
database/schema.sqlfor MariaDB initialization - 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_PASSWORDin your.envfile or environment variables.
The login session expires after 24 hours of inactivity.
IP Registry Integration
To enable automatic IP enrichment:
- Sign up for a free API key at ipregistry.co
- Set the API key via environment variable:
Or configure it in the Advanced tab of the web interface.
IPREGISTRY_API_KEY=your_api_key - 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:
- Create an IAM user in AWS with
route53:ListHostedZonesandroute53:ListResourceRecordSetspermissions - Generate an access key and secret key for the IAM user
- 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)
- Click "Test Connection" to verify credentials
- 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:
- Enter your n8n webhook URL
- Set the debounce delay (1-60 minutes)
- Enable webhook notifications
The system batches multiple changes within the debounce window to reduce API calls.
n8n Workflow Setup
-
In n8n, go to Settings > Environment Variables and add:
BUNNY_STORAGE_ZONE- Your BunnyCDN storage zone nameBUNNY_API_KEY- Your BunnyCDN Storage API key
-
Create MySQL credentials in n8n:
- Go to Credentials
- Add new MySQL credential
- Configure with your database details
- Note the credential ID
-
Import the workflow:
- Go to Workflows
- Click Import from File
- Select
n8n/geofeed-export-workflow.json
-
Update credential references:
- Open the imported workflow
- For each MySQL node, select your MySQL credential
- Save the workflow
-
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:
- Click Check for Updates to compare your database against the repository schema
- View missing tables, columns, and indexes
- 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
- Create a Storage Zone in BunnyCDN
- Get your Storage API key from the FTP & API Access section
- The workflow uploads to:
https://storage.bunnycdn.com/{zone}/geofeed.csv - 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