Infrapod IP Lists API
This project is the source of truth for Infrapod IP blocklists.
It provides:
- A FastAPI service that stores and serves internal and external IP sets
- Scheduled refresh of external lists (for example FireHOL)
- Cached, deduplicated outputs for reliable client consumption
- A companion
ipclipackage (.deband.rpm) for host-side automation
What this replaces
The API replaces static publication from iplists.infrapod.nl as the
authoritative source for internal Infrapod lists.
Internal lists are stored in the application database and managed through the API.
Core concepts
- Internal sources:
infrapod_abuse,infrapod_bots,infrapod_spam - External sources: API-configured feeds such as
firehol_level1 - Snapshots: normalized, deduplicated list materializations used by readers
- Combined views: dynamic union of multiple sources, also deduplicated
Normalization and deduplication are performed using netaddr.IPSet and exposed
as canonical CIDR output.
API overview
All API endpoints require authentication.
Source management
GET /v1/sourcesPOST /v1/sourcesPATCH /v1/sources/{name}DELETE /v1/sources/{name}POST /v1/sources/{name}/refresh
Internal list mutations
POST /v1/internal/entriesDELETE /v1/internal/entries
Read endpoints
GET /v1/ipsets/{name}GET /v1/ipsets/{name}/plainGET /v1/ipsets/combined?include=source_a,source_bGET /v1/ipsets/combined/plain?include=source_a,source_bGET /v1/health
Internal entry endpoints
POST /v1/internal/entriesDELETE /v1/internal/entries
Authentication
Every endpoint is protected by an API key sent as a bearer token.
- Header format:
Authorization: Bearer <api_key> - Keys are hashed at rest and shown only once at creation time
- Keys can be scoped, revoked, and optionally expired
Bootstrap and first key
The first API key is created using a bootstrap secret set in the runtime environment.
- Set
BOOTSTRAP_API_KEYin the container environment. - Call
POST /v1/auth/keyswith that value in the bearer token header. - Store the returned key securely; it is not retrievable later.
- Rotate or remove
BOOTSTRAP_API_KEYafter initial provisioning.
Key management endpoints
POST /v1/auth/keysGET /v1/auth/keysPATCH /v1/auth/keys/{id}DELETE /v1/auth/keys/{id}
Scheduler behavior
- External sources are fetched on a configurable interval
- Conditional requests use
ETagandLast-Modifiedwhen available - Failed refreshes keep the last known good snapshot available
- Internal source changes trigger immediate recomputation of affected snapshots
Runtime flags:
SCHEDULER_ENABLED(1by default)SCHEDULER_TICK_SECONDS(60by default)
Storage model
SQLite is used for persistence (mounted in a Docker volume):
sourcesfor internal and external source definitionsinternal_entriesas source-of-truth entries forinfrapod_*snapshotsfor read-optimized normalized outputsexternal_fetch_statefor metadata (etag,last_success,last_error)
Docker runtime
The API runs as a container and persists data in /data.
Typical deployment shape:
- Image based on
python:3.14-alpine - Entrypoint starts uvicorn and DB initialization runs in lifespan
- Health check probes
GET /v1/healthwith a bearer key
Build and deploy jobs are tag-only in GitLab CI.
Local run:
pip install -r requirements.txt
export BOOTSTRAP_API_KEY="change-me"
uvicorn iplists_api.main:app --app-dir src --host 0.0.0.0 --port 8080
Container run:
docker build -t iplists-api .
docker run --rm -p 8080:8080 \
-e BOOTSTRAP_API_KEY="change-me" \
-e HEALTHCHECK_API_KEY="change-me" \
-v iplists-data:/data \
iplists-api
ipcli package
ipcli is distributed as .deb and .rpm for host usage.
It can:
- Consume API endpoints for source and list operations
- Export IP data in formats suitable for web proxies:
- Plain list
- HAProxy include file format
- Nginx deny directives format
Example usage:
ipcli --api-url https://iplists-api.example --api-key "$IPLISTS_API_KEY" \
sources list
ipcli --api-url https://iplists-api.example --api-key "$IPLISTS_API_KEY" \
ipsets get firehol_level1 --format haproxy
ipcli --api-url https://iplists-api.example --api-key "$IPLISTS_API_KEY" \
ipsets get combined --include firehol_level1,infrapod_abuse --format nginx
Current status
This repository is currently transitioning from the legacy netset workflow to the API-first architecture described above.