131 lines
4.3 KiB
Markdown
131 lines
4.3 KiB
Markdown
## Integration & Tuning
|
|
|
|
This document complements the installation steps in [docs/INSTALLATION.md](docs/INSTALLATION.md) by focusing on detector tuning, allowlists, and advanced integrations (log forwarding, Fail2Ban, etc.).
|
|
|
|
Example `upload-logger.json` (simplified) for UploadShield:
|
|
|
|
```json
|
|
{
|
|
"modules": {
|
|
"flood": true,
|
|
"filename": true,
|
|
"mime_sniff": true,
|
|
"hashing": true,
|
|
"base64_detection": true,
|
|
"raw_peek": false,
|
|
"archive_inspect": true,
|
|
"quarantine": true
|
|
},
|
|
"paths": {
|
|
"log_file": "logs/uploads.log",
|
|
"quarantine_dir": "quarantine",
|
|
"state_dir": "state",
|
|
"allowlist_file": "allowlist.json"
|
|
},
|
|
"limits": {
|
|
"max_size": 52428800,
|
|
"raw_body_min": 512000,
|
|
"sniff_max_bytes": 8192,
|
|
"sniff_max_filesize": 2097152
|
|
},
|
|
"ops": {
|
|
"quarantine_owner": "root",
|
|
"quarantine_group": "www-data",
|
|
"quarantine_dir_perms": "0700",
|
|
"block_suspicious": false
|
|
},
|
|
"allowlists": {
|
|
"base64_uris": [
|
|
"/api/uploads/avatars",
|
|
"#/hooks/(github|gitlab|stripe|slack)#"
|
|
],
|
|
"ctypes": ["image/svg+xml","application/xml","text/xml"]
|
|
}
|
|
}
|
|
```
|
|
|
|
Notes:
|
|
- Remove the `//` comments if copying from examples. Use absolute paths in production where possible.
|
|
|
|
### Content detector tuning
|
|
|
|
- The `ContentDetector` performs a fast head-scan to detect PHP open-tags and common webshell indicators (e.g., `passthru`, `system`, `exec`, `base64_decode`, `eval`, `assert`).
|
|
- Tuning options (in `upload-logger.json`):
|
|
- `limits.sniff_max_bytes` (default 8192) — how many bytes to scan from the file head.
|
|
- `limits.sniff_max_filesize` (default 2097152) — only scan files up to this size.
|
|
- `detectors.content.allow_xml_eval` — relax `eval()` detection for XML/SVG when appropriate.
|
|
|
|
False positives
|
|
- `eval(` appears in benign contexts (SVG/JS). To reduce false positives:
|
|
- Add trusted URIs to `allowlists.base64_uris`.
|
|
- Add trusted content-types to `allowlists.ctypes`.
|
|
- Tune scan size limits.
|
|
|
|
### Allowlists
|
|
|
|
- `allowlists.base64_uris`: URI patterns (substring or PCRE when wrapped with `#`) that should bypass base64/raw detection.
|
|
- `allowlists.ctypes`: content-types to treat as permitted for encoded payloads (e.g., `image/svg+xml`).
|
|
|
|
### Archive inspection & quarantine
|
|
|
|
- Archives uploaded are flagged and—if quarantine is enabled—moved to the quarantine directory for inspection.
|
|
- Quarantine should be owner `root`, group `www-data`, mode `0700`. Files inside should be `0600`.
|
|
|
|
## Fail2Ban integration (example)
|
|
|
|
Create a Fail2Ban filter that matches suspicious JSON log lines and captures the IP as `<HOST>`.
|
|
|
|
Filter (`/etc/fail2ban/filter.d/php-upload.conf`):
|
|
|
|
```ini
|
|
[Definition]
|
|
failregex = ^.*"event"\s*:\s*"suspicious".*"ip"\s*:\s*"(?P<host>\d{1,3}(?:\.\d{1,3}){3})".*$
|
|
ignoreregex =
|
|
```
|
|
|
|
Jail example (adjust `logpath`):
|
|
|
|
```ini
|
|
[php-upload]
|
|
enabled = true
|
|
filter = php-upload
|
|
logpath = /var/www/sites/*/.security/logs/uploads.log
|
|
maxretry = 3
|
|
findtime = 600
|
|
bantime = 86400
|
|
action = nftables[name=php-upload, port="http,https", protocol=tcp]
|
|
```
|
|
|
|
Test with `fail2ban-regex` using a representative JSON log line.
|
|
|
|
## Central log aggregation (Filebeat / rsyslog)
|
|
|
|
Forward JSON logs to your aggregator to centralize alerts and analysis. Example Filebeat input:
|
|
|
|
```yaml
|
|
filebeat.inputs:
|
|
- type: log
|
|
paths:
|
|
- /var/www/sites/*/.security/logs/uploads.log
|
|
json.keys_under_root: true
|
|
json.add_error_key: true
|
|
fields:
|
|
source: php-upload-logger
|
|
output.logstash:
|
|
hosts: ["logserver:5044"]
|
|
```
|
|
|
|
## Logrotate & SELinux notes
|
|
|
|
Per-site `logrotate` snippets are included in `examples/logrotate.d/upload-logger`. Use `copytruncate` or reload PHP-FPM after rotation.
|
|
|
|
If SELinux is enabled, the provisioning script attempts to register fcontexts and run `restorecon`. Verify contexts manually as needed.
|
|
|
|
## Final notes
|
|
|
|
- Use observe mode (`ops.block_suspicious: false`) while tuning.
|
|
- After tuning, enable blocking in a controlled rollout (canary hosts first).
|
|
- Keep `upload-logger.php` and `.security` owned by `root` and ensure logs and quarantine are not web-accessible.
|
|
|
|
For installation steps and per-site configuration, see `docs/INSTALLATION.md`.
|