php-banlist :: INSTALL
======================

Requirements: Apache 2.4 + mod_rewrite OR Nginx + php-fpm (new in
0.5), PHP 8.0+, MariaDB 10.6+ (or MySQL 8.0+). PHP extensions: pdo,
pdo_mysql, session, mbstring, openssl, filter, hash.

Apache users follow section 4; Nginx users follow section 4b instead.


1. FILES
--------

Extract the tarball inside your document root (or wherever you want
the app served from). The version-numbered directory lives alongside
any previous version; a symlink named `php-banlist` points to the
active release. This makes rollback a one-command symlink re-point.

    cd /path/to/document-root
    tar xzf php-banlist-0.5.tar.gz
    sudo ln -s php-banlist-0.5 php-banlist
    cd php-banlist
    sudo chown -R apache:apache .
    sudo find . -type d -exec chmod 750 {} \;
    sudo find . -type f -exec chmod 640 {} \;


2. DATABASE
-----------

install.php applies the schema, so the MySQL user needs DDL privileges
at install time:

    sudo mysql <<'SQL'
    CREATE DATABASE banlist CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    CREATE USER 'banlist'@'localhost' IDENTIFIED BY 'CHANGE_ME';
    GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, INDEX, DROP, REFERENCES
        ON banlist.* TO 'banlist'@'localhost';
    FLUSH PRIVILEGES;
    SQL

After install you can revoke DDL to tighten posture, then re-grant
when upgrading:

    sudo mysql -e "REVOKE CREATE, ALTER, INDEX, DROP ON banlist.* FROM 'banlist'@'localhost';"


3. CONFIG
---------

    sudo cp config.example.php config.php
    sudo $EDITOR config.php           # set db.pass
    sudo chown root:apache config.php
    sudo chmod 640 config.php

base_path is auto-detected; no need to set it.


4. APACHE
---------

Most LAMP installs ship AllowOverride All for DocumentRoot and need
nothing - drop the files in and the shipped .htaccess does the work.

If your AllowOverride is locked down, either loosen it for this
directory:

    <Directory "/path/to/php-banlist">
        AllowOverride AuthConfig FileInfo Indexes Options
        Require all granted
    </Directory>

...or copy the .htaccess contents into matching <Directory> blocks in
your vhost. Required module: mod_rewrite.

    sudo apachectl configtest
    sudo systemctl reload httpd       # or apache2


4b. NGINX (alternative to section 4)
------------------------------------

Nginx ignores the shipped .htaccess files, so their protections MUST
be recreated in the server config — without them config.php, private/,
cron/, and sql/ are served to anyone who asks. nginx.conf.example
translates every .htaccess rule one-for-one, with a comment naming the
Apache rule each block mirrors. Copy the location blocks into your
vhost, adjust the /php-banlist path prefix, root, and fastcgi_pass to
your layout, then:

    sudo nginx -t
    sudo systemctl reload nginx

Sanity-check the denies before first run — all four must return 403
(or 404), never file contents:

    curl -sI https://your-server/php-banlist/config.php        | head -1
    curl -sI https://your-server/php-banlist/private/db.php    | head -1
    curl -sI https://your-server/php-banlist/cron/expire.php   | head -1
    curl -sI https://your-server/php-banlist/sql/migrations/0001-initial.sql | head -1

Adjust the ownership commands from section 1 to your php-fpm user
(often nginx or www-data instead of apache).


5. FIRST RUN
------------

Open https://your-server/php-banlist/install.php in a browser.
install.php applies any pending migrations from sql/migrations/ and
prompts for the first superadmin. It auto-locks once a user exists and
nothing is pending. Delete the file afterward:

    sudo rm install.php


6. CRON
-------

Nightly expiry + log pruning, as the apache user:

    3 4 * * *  /usr/bin/php /path/to/php-banlist/cron/expire.php


7. FEEDS
--------

    https://your-server/php-banlist/IP-list.txt
    https://your-server/php-banlist/FQDN-list.txt

Test:

    curl https://your-server/php-banlist/IP-list.txt | head

For feeds exposed to the public internet, set list_acl in config.php
to a CIDR list and/or enable the token requirement on the settings
page (then pass ?token=... or X-API-Token: header).


8. BACKUPS
----------

    mysqldump --single-transaction banlist | zstd -19 > banlist-$(date +%F).sql.zst


9. UPGRADES
-----------

Extract the new version next to the old one, carry your config.php
forward, re-point the symlink, then re-run install.php to apply any
new migrations.

0.5 ships NO schema changes, so upgrading from 0.4 is just the file
swap below — re-running install.php is harmless but not required.
(Upgrading from 0.3 or earlier still needs install.php for migration
0003; make sure the DB user has DDL privileges at that moment — see
section 2 if you revoked them after the last install.)

    cd /path/to/document-root
    tar xzf php-banlist-0.5.tar.gz                  # adjust version
    sudo cp php-banlist/config.php php-banlist-0.5/
    sudo chown -R apache:apache php-banlist-0.5
    sudo find php-banlist-0.5 -type d -exec chmod 750 {} \;
    sudo find php-banlist-0.5 -type f -exec chmod 640 {} \;
    sudo ln -sfn php-banlist-0.5 php-banlist        # atomic swap

If migrations are pending, open install.php in your browser to apply
them. Delete install.php afterward.

New in 0.5: Nginx is now a supported web server (see section 4b and
nginx.conf.example). Also note logout is now a POST — if you scripted
GET /logout.php anywhere, that request now just redirects.

To roll back, just point the symlink at the previous version:

    sudo ln -sfn php-banlist-0.3 php-banlist        # the prior release

(If the newer version's migrations are incompatible with the older
code, restore your pre-upgrade SQL dump first.)
