Pynblok
Pynblok is a Docker-based honeypot intelligence and network-blocking system. It collects and analyses hostile web traffic, enriches IP and network intelligence, scores activity, promotes hostile infrastructure where justified, and synchronises blocks with Cloudflare.
PostgreSQL is the operational database. Reports and charts are generated as static HTML.
Architecture
The main flow is:
Caddy honeypot logs
↓
Import and enrichment
↓
Classification and scoring
↓
IP blocking and network promotion
↓
CIDR housekeeping
↓
Cloudflare synchronisation
Crawler intelligence is handled separately from general hostile-IP blocking. A crawler's User-Agent is a claim, not proof of identity.
Runtime services
The deployment may include these Compose services:
caddy— serves sites and honeypot endpoints.pynblok— imports and processes observations; runs the main application, scheduler and asynchronous worker.pynblok-reporting— serves the reporting interface.pynblok-receiver— receives forwarded Wordfence/Pynblok events.pynblok-sender— sends configured events to another Pynblok instance.postgres_server— PostgreSQL database service, if defined in the same Compose project.
The actual deployment is defined by the live Docker Compose file. Example deployment files belong in docker.sample/.
Repository and configuration
The repository is located at:
/srv/volumes/pynblok
The application is mounted into the container at /pynblok/app. The live configuration directory on the host is config/, mounted into containers at /etc/pynblok.
config/contains live, deployment-specific settings and is not version controlled.config.sample/contains safe example configuration files and documentation.docker.sample/is intended for sanitised deployment examples.html/reporting/andhtml/static/are version controlled.- Generated reports, runtime data, logs, secrets and database contents should not be committed.
config.json is the configuration entry point. It identifies subordinate configuration files, whose relative paths are resolved from the configuration directory. Avoid hard-coding configuration paths in application modules.
Configuration includes scoring, attack classes and frequency, IP/CIDR/ASN reputation, Cloudflare, domains, GeoIP, geographic policy, scheduler, watcher and whitelist settings.
GeoIP.conf is kept with the live Pynblok configuration at /etc/pynblok/GeoIP.conf. Do not put credentials in the repository.
Database and processing
Pynblok uses PostgreSQL. The application and reporting service use separate database roles. The current schema version is maintained by the application; consult the live database and migrations rather than relying on a version number written in this README.
The main processing and asynchronous work use PostgreSQL-backed job queues. Jobs record status and timing, and stale-job recovery supports recovery when a worker disappears.
The runtime processes are:
main.py
scheduler.py
async_worker.py
The application also includes import, parsing, enrichment, classification, scoring, CIDR housekeeping, Cloudflare synchronisation, crawler and reporting modules.
Cloudflare and blocking
Cloudflare is the enforcement layer; Pynblok does not apply its normal blocking decisions directly in Caddy.
Pynblok can block individual IP addresses as /32, promote hostile infrastructure into /24 networks, and aggregate networks through CIDR housekeeping when policy and evidence justify it. Whitelists and reputation/policy evidence must be respected.
Cloudflare list capacity is finite, so block lifecycle, reconciliation and removal of subsumed entries matter.
Crawler intelligence
Crawler identification, verification and behavioural assessment are separate from the general blocking pipeline. The system considers request evidence and crawler IP verification; a recognised name or User-Agent alone should not be treated as proof that traffic is legitimate.
Crawler classification and policy remain active development areas.
Reporting
The reporting service generates static HTML reports and charts. Reports are read-only and should not change security state.
The reporting interface includes areas such as the dashboard, attackers, scoring, blocks, ASN/ISP, AbuseIPDB, escalations, crawlers, Cloudflare, job queues and charts.
Requirements
- Docker and Docker Compose
- PostgreSQL
- Cloudflare API access
- GeoIP database/update access
- AbuseIPDB API access if that enrichment is enabled
Python dependencies are listed in app/requirements.txt.
Running and inspecting the deployment
Run these commands from the directory containing the live Compose file:
docker compose ps
docker compose logs -f
docker compose up -d
For application-specific commands, check the current app/main.py help/output before using a command against production. Older SQLite instructions and commands from previous versions may no longer apply.
For Python syntax checks:
cd /srv/volumes/pynblok
python -m py_compile app/module.py
Replace module.py with the file being checked. Compile and test targeted changes before restarting a running service.
Security and data handling
Do not commit:
- API tokens, passwords or
.envfiles - live configuration
- database contents
- raw honeypot logs or runtime data
- generated report output
Use least-privilege Cloudflare credentials. Protect retained IP addresses, request data and reputation information appropriately, and define retention in line with the deployment's operational and legal requirements.
Development priorities
Current work is tracked in TODO.md. Broad areas include crawler classification and verification, scoring and ASN intelligence, block lifecycle, reporting improvements, configuration validation, and deployment cleanup.
The guiding principle is to identify hostile infrastructure from accumulated evidence and block proportionately, rather than treating every observed IP address in isolation.