🚫 Version 0.5 — Nginx support & security hardening

> firewall banlists, self-hosted 

One place to ban IPs, CIDRs, and FQDNs — with per-entry expiry, roles, and a full audit trail — served as plain-text feeds that pfSense, OPNsense, Palo Alto, FortiGate, or any URL-driven firewall polls straight from your own server.

Free & MIT licensed  ·  PHP 8.0+ / MariaDB  ·  Apache or Nginx
Why php-banlist

Built like the thing it feeds

A banlist manager is a security tool — it should hold up to the same scrutiny as the firewall consuming it.

📡

Feeds any firewall accepts

IP-list.txt and FQDN-list.txt — plain text, one entry per line, generated from the database on every request. Optional source-IP ACL and token gating.

Bans that expire themselves

Calendar-accurate durations from seconds to years (30m, 7d, 1mo, p for permanent). A nightly cron hard-deletes the stale rows.

🧮

Zero JavaScript, enforced

A strict CSP with no script-src at all. Confirmations, pagination, and pickers are all server round-trips — nothing for a browser exploit to hook.

🧤

Write API for automation

Add or remove bans from scripts and SIEM hooks with SHA-256-hashed tokens. Off by default and double-gated: a global switch plus a per-token write flag.

🔑

Hardened auth

Argon2id hashing, CSRF tokens on every state change (logout included), session pinning, brute-force lockout per account and per IP, optional remember-me.

📋

Roles + audit trail

readonly, admin, and superadmin roles; every login, ban, and settings change lands in a searchable audit log with actor and source IP.

🌐

IPv4 & IPv6 throughout

Single addresses or CIDR blocks, both families, validated on the way in and re-validated at feed emit time. FQDN lists fit pfBlockerNG / DNSBL workflows.

🛠

Apache or Nginx

Drop-in .htaccess for Apache, and (new in 0.5) a fully commented nginx.conf.example that mirrors every protection one-for-one.

The output

Point your firewall at a URL

What the UI manages, the feeds serve — and the write API automates.

php-banlist :: feeds + api
$ curl https://host/php-banlist/IP-list.txt
# php-banlist v0.5 ip list, generated 2026-07-12T22:00:41+00:00
185.220.101.0/24
203.0.113.99
2001:db8:bad::/48

$ curl https://host/php-banlist/FQDN-list.txt
# php-banlist v0.5 fqdn list, generated 2026-07-12T22:00:44+00:00
botnet-c2.example.net
phish.example.org

$ curl -X POST -H 'X-API-Token: TOKEN' \
    -d 'action=add&type=ip&value=198.51.100.7&reason=ssh scans&duration=7d' \
    https://host/php-banlist/api.php
{"ok":true,"added":1,"invalid":[]}
Getting started

Up and running in minutes

A standard LAMP/LEMP box is all it takes. The installer applies the schema and locks itself.

📋 Requirements

  • Web serverApache 2.4 + mod_rewrite, or Nginx + php-fpm
  • PHP8.0 or higher
  • DatabaseMariaDB 10.6+ / MySQL 8.0+
  • Extensionspdo_mysql, session, mbstring, openssl

🚀 Installation

  1. Extract & symlinkUnpack the tarball next to any prior version and point a php-banlist symlink at it — upgrades and rollbacks are one ln -sfn.
  2. Create the databaseOne database, one dedicated user. DDL rights only need to exist while the installer runs.
  3. Copy the configconfig.example.phpconfig.php, set the DB password. Apache reads the shipped .htaccess; Nginx users copy nginx.conf.example.
  4. Run the installerOpen install.php, create the first superadmin, delete the file. Point your firewall at the feed URLs.
Download

Get php-banlist 0.5

The whole application in one small tarball — free forever.

⬇ Download php-banlist-0.5.tar.gz
MIT licensed ~53 KB PHP 8.0+ Source on GitHub