docs: add CONFIG_REFERENCE.md and CONTRIBUTING.md; update INTEGRATION and README

This commit is contained in:
2026-02-12 10:18:32 +01:00
parent 1768f61da1
commit d6a19929bf
5 changed files with 404 additions and 528 deletions

175
docs/INSTALLATION.md Normal file
View File

@@ -0,0 +1,175 @@
# Installation & Production Deployment Guide
This guide shows a minimal, secure installation and rollout path for `upload-logger.php`.
Follow these steps in a staging environment first; do not enable blocking until detectors are tuned.
**Prerequisites**
- A Linux host running PHP-FPM (PHP 8.0+ recommended).
- `composer` available for dev tasks.
- SSH/privileged access to configure the site pool and run provisioning scripts.
**Quick overview**
1. Place `upload-logger.php` in a secure per-site folder (recommended `.security`).
2. Create `logs/`, `quarantine/`, `state/` and set strict ownership and permissions.
3. Configure `upload-logger.json` for your environment; keep `ops.block_suspicious` off for initial tuning.
4. Enable `auto_prepend_file` in the site PHP-FPM pool to run the logger before application code.
5. Verify logging, tune detectors, deploy log rotation, and enable alerting.
**1. Clone & dependencies (developer workstation)**
- Clone the repository and install dev deps (for tests/static analysis):
```bash
git clone <repo-url> /srv/upload-logger
cd /srv/upload-logger
composer install --no-interaction --prefer-dist
```
Run tests locally:
```bash
vendor/bin/phpunit --configuration phpunit.xml
vendor/bin/phpstan analyse -c phpstan.neon
```
**2. Recommended file layout (per-site)**
Use a hidden per-site security folder so `upload-logger.php` is not web-accessible.
Example layout:
```
/var/www/sites/example-site/
├── public/
├── app/
├── uploads/
├── .security/
│ ├── upload-logger.php
│ └── logs/
│ └── uploads.log
├── quarantine/
└── state/
```
**3. Copy files & configure**
- Place `upload-logger.php` into `.security/upload-logger.php`.
- Copy `upload-logger.json` from the repository to the same directory and edit paths to absolute values, e.g.:
- `paths.log_file``/var/www/sites/example-site/.security/logs/uploads.log`
- `paths.quarantine_dir``/var/www/sites/example-site/quarantine`
- `paths.state_dir``/var/www/sites/example-site/state`
- Ensure `ops.block_suspicious` is `false` initially (observe mode).
**4. Create directories & set permissions (run as root)**
Adjust user/group to your site environment (`www-data` used in examples):
```bash
# example: run on target host as root
mkdir -p /var/www/sites/example-site/.security/logs
mkdir -p /var/www/sites/example-site/quarantine
mkdir -p /var/www/sites/example-site/state
chown -R root:www-data /var/www/sites/example-site/.security
chmod 750 /var/www/sites/example-site/.security
chmod 750 /var/www/sites/example-site/.security/logs
# quarantine must be restrictive
chown -R root:www-data /var/www/sites/example-site/quarantine
chmod 0700 /var/www/sites/example-site/quarantine
# state directory writable by PHP-FPM if required (group-write)
chown -R root:www-data /var/www/sites/example-site/state
chmod 0750 /var/www/sites/example-site/state
# ensure log file exists with safe perms
touch /var/www/sites/example-site/.security/logs/uploads.log
chown root:www-data /var/www/sites/example-site/.security/logs/uploads.log
chmod 0640 /var/www/sites/example-site/.security/logs/uploads.log
```
Alternatively use the included provisioning scripts on the host:
- `scripts/provision_dirs.sh` — run as root; idempotent and attempts to set SELinux fcontext.
- `scripts/ansible/upload-logger-provision.yml` — Ansible playbook for bulk provisioning.
**5. PHPFPM configuration (per-site pool)**
Edit the site's FPM pool (example: `/etc/php/8.1/fpm/pool.d/example-site.conf`) and add:
```ini
; Ensure upload-logger runs before application code
php_admin_value[auto_prepend_file] = /var/www/sites/example-site/.security/upload-logger.php
```
Then reload PHP-FPM:
```bash
sudo systemctl reload php8.1-fpm
```
Notes:
- Use the absolute path to `upload-logger.php`.
- If your host uses a shared PHP-FPM pool, consider enabling per-vhost `auto_prepend_file` via nginx/apache or create a dedicated pool for the site.
**6. Log rotation**
Create `/etc/logrotate.d/upload-logger` with content adapted to your paths:
```
/var/www/sites/example-site/.security/logs/uploads.log {
rotate 7
size 10M
compress
missingok
notifempty
copytruncate
create 0640 root www-data
sharedscripts
postrotate
if systemctl is-active --quiet php8.1-fpm; then
systemctl reload php8.1-fpm >/dev/null 2>&1 || true
fi
endscript
}
```
`copytruncate` is safe and avoids needing to stop PHP; alternatively use `postrotate` to reload FPM.
**7. Verify installation (smoke tests)**
- Upload a benign file via your app or via a simple test form and confirm a JSON `upload` line appears in the log.
- Upload a file containing `<?php` to confirm detectors log `suspicious_upload` entries.
- Check `logs/uploads.log` for events.
Example quick test (on host):
```bash
# from site root
php -S 127.0.0.1:8000 -t . -d auto_prepend_file=/var/www/sites/example-site/.security/upload-logger.php
# then curl a file POST to your test endpoint
curl -F "file=@/path/to/sample.txt" http://127.0.0.1:8000/upload_test.php
```
**8. Tuning & staging**
- Keep `ops.block_suspicious` set to `false` while monitoring logs and tuning:
- `allowlists.base64_uris` — add URIs for trusted base64 endpoints.
- `allowlists.ctypes` — add trusted content-types such as `image/svg+xml` if needed.
- `limits.sniff_max_bytes` / `limits.sniff_max_filesize` — tune scanning cost vs coverage.
- Run the system under representative traffic and check for false positives.
**9. Gradual enable blocking**
- After tuning, enable blocking in a controlled manner:
1. Set `ops.block_suspicious``true` in `upload-logger.json` on a small subset of sites or a canary host.
2. Monitor errors, rollback quickly if issues appear.
3. Gradually roll out to remaining hosts.
**10. Monitoring & alerting**
- Forward `logs/uploads.log` to your SIEM or log aggregator (Filebeat/Fluentd).
- Create alerts for `event == suspicious_upload` or `event == raw_body` and for rapid flood counts.
- Monitor disk usage for `logs/` and ensure `logrotate` is active.
**11. Security & operational checklist**
- Ensure `quarantine/` and `.security/logs` are not accessible from the web server.
- Verify SELinux/AppArmor contexts after running provisioning.
- Ensure owner/group are set to root and web group (e.g., `root:www-data`) and modes match the guide.
- Keep `upload-logger.php` readable by root (644) and the logs readable only by the intended group (640).
**Rollback**
- Disable `php_admin_value[auto_prepend_file]` in the pool and reload PHP-FPM.
- Remove or rotate the `upload-logger` files if needed.
**Further reading & files**
- Integration notes: [INTEGRATION.md](INTEGRATION.md)
- Provisioning script: `scripts/provision_dirs.sh`
- Ansible playbook: `scripts/ansible/upload-logger-provision.yml`
- Example configuration: `upload-logger.json`
---
If you want, I can: (a) generate a site-specific copy of these snippets for your exact paths/PHP version, (b) open a PR with the updated documentation, or (c) produce a one-command installer playbook that runs the provisioning and copies files to a remote host. Tell me which option you prefer.