# ipban199 A PHP/MySQL web application for managing IP blacklists and whitelists. Provides both a browser UI and plain-text API endpoints consumed by external firewall/filtering tools. --- ## Database **Connection:** `conn.php` — connects to MySQL at database. `conn.php` is not included in version control. Create it with the following structure: ```php ``` ### Tables | Table | Purpose | |-------|---------| | `blacklist` | Banned IPs | | `whitelist` | Allowed IPs | | `type` | IP classification labels (e.g. type 1, 3, …) | | `info` | Tracks last-modified timestamps per list | ### `blacklist` / `whitelist` columns | Column | Type | Notes | |--------|------|-------| | `ip` | varchar | Primary key. CIDR notation, e.g. `1.2.3.4/32` | | `type` | int | FK to `type.type` | | `adddate` | bigint | `YYYYMMDDHHmmss` format | | `enddate` | bigint | `YYYYMMDDHHmmss` or `99999999999999` for permanent | | `reason` | varchar | Free-text description | ### `info` columns | Column | Notes | |--------|-------| | `list` | `0` = blacklist last-modified, `1` = whitelist last-modified, `> 1` = portspoof pull log (value is the run timestamp `YYYYMMDDHHmmss`) | | `last` | Timestamp of last change in `YYYYMMDDHHmmss` format | ### Date format All dates are stored as 14-digit integers: `YYYYMMDDHHmmss` (e.g. `20260316143000`). Helper functions in `functions.php` handle conversion, arithmetic, and display. --- ## API Endpoints Authentication is not enforced on the API endpoints — they are intended to be called from trusted internal/local sources. ### `blacklist.php` Returns a plain-text block list of currently active IPs (adddate ≤ now < enddate). | Action | Method | Parameters | Response | |--------|--------|-----------|---------| | `?a=display` (default) | GET | — | Plain-text IP list with comments | | `?a=add` | GET | `ip`, `type`, `date` (enddate), `reason` | `SUCCESS` (new) / `SUCCESS UPDATE` (existing) | | `?a=rem` | GET | `ip` | `SUCCESS` | | `?a=log` | GET | `ip`, `date`, `sf`, `type`, `account` | `SUCCESS` | `add` uses `INSERT … ON DUPLICATE KEY UPDATE` so duplicate IPs never cause an error. **Example:** ``` https://www.daprogs.com/api/ipban199/blacklist.php?a=add&ip=1.2.3.4/32&type=1&date=20271231235959&reason=Bad%20Actor ``` Also supports `HEAD` requests — returns `Last-Modified` header based on `info.last` for `list=0`. ### `whitelist.php` Same interface as `blacklist.php` but operates on the `whitelist` table (`info.list=1`). | Action | Method | Parameters | Response | |--------|--------|-----------|---------| | `?a=display` (default) | GET | — | Plain-text allow list | | `?a=add` | GET | `ip`, `type`, `date`, `reason` | `SUCCESS` / `SUCCESS UPDATE` | | `?a=rem` | GET | `ip` | `SUCCESS` | --- ## Portspoof Auto-Pull (`pull.php`) Fetches frequently seen IPs from the portspoof API and ingests them into the blacklist automatically. **Source API:** `https://www.home.daprogs.net/portspoof/api/frequent_ips.php` **Auth:** Bearer token (configured at top of `pull.php`) ### Behaviour - Compares each IP's `last_seen` against the timestamp of the most recent previous pull - Only ingests IPs where `last_seen > last_pulled` (new activity since last run) - Uses `INSERT … ON DUPLICATE KEY UPDATE` — safe to run repeatedly, existing IPs get their `enddate` and `type` refreshed - Inserts are batched in chunks of 100 rows to stay within MySQL's `max_allowed_packet` - Each run logs itself in `info` with `list = ` (the `MAX(list) WHERE list > 1` query finds the last run on the next execution) - Updates `info.last WHERE list=0` (blacklist last-modified) when at least one row was written ### Configuration (top of `pull.php`) | Variable | Default | Description | |----------|---------|-------------| | `$pull_type` | `3` | Blacklist type ID assigned to portspoof entries | | `$enddate_days` | `600` | Days until the ban expires | | `$reason` | `"Portspoof Auto-Ban"` | Reason string stored on each entry | ### Running via cron ```bash # Every hour 0 * * * * php /path/to/ipban199/pull.php >> /var/log/ipban_pull.log 2>&1 ``` ### Output ``` Done. Processed: 1700, Skipped: 42 ``` - **Processed** — rows sent to MySQL (new inserts + updates of existing IPs) - **Skipped** — rows filtered out because `last_seen <= last_pulled` --- ## Web UI Requires a login session (`$_SESSION['user_id']`). Login via `login.php`; logout via the navbar link. | Page | Description | |------|-------------| | `index.php` | Search blacklist/whitelist; shows last 20 entries per list | | `add_ip_frm.php?tbl=b` | Add a single IP to the blacklist | | `add_ip_frm.php?tbl=w` | Add a single IP to the whitelist | | `add_ip_bulk_frm.php` | Paste-in bulk IP import (CSV, one IP per line) | | `add_type_frm.php` | Add a new IP type/label | | `last_info.php` | Show last-modified timestamps for blacklist and whitelist | | `search_db.php` | Search results page (POST from index) | | `export.php` | Download current search results as CSV | | `error.php` | Displays error messages from session | ### Bulk Import format (`add_ip_bulk_frm.php`) One IP per line. Comma-separated; first field is the IP. IPs without a `/` suffix are automatically normalised to `/32`. ``` 1.2.3.4 5.6.7.8/24 ``` --- ## File Reference | File | Role | |------|------| | `conn.php` | DB connection | | `functions.php` | Date helpers (`print_datetime`, `add_days`, `add_months`, `add_years`, `datetodigits`, …) | | `sfunctions.php` | Additional helpers | | `header.php` | HTML `` + session start + navbar | | `topmenu.php` | Closing `` + `` + nav bar HTML | | `footer.php` | Page footer | | `stil.css` | Custom styles | | `blacklist.php` | Blacklist API endpoint | | `whitelist.php` | Whitelist API endpoint | | `pull.php` | Portspoof auto-pull ingestion script | | `export.php` | CSV export |