Files
Zefix_search/README.md
T

107 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Silias ZEFIX Export
Ein PHP-Dienst, der ZEFIX-Suchaufträge asynchron verarbeitet und den fertigen CSV-Export über einen zeitlich begrenzten Download-Link zustellt.
Vorausgesetzt werden PHP 8.1 oder neuer, die Erweiterungen cURL und JSON sowie ein korrekt konfigurierter CA-Zertifikatsspeicher für die TLS-Prüfung von Cloudflare, ZEFIX und SMTP.
## Missbrauchsschutz
Der Export ist standardmässig **fail-closed**: Ohne vollständig konfigurierte Cloudflare-Turnstile-Schlüssel bleibt der Absende-Button deaktiviert und `submit.php` nimmt keine Aufträge an.
Aktivierte Schutzschichten:
- Cloudflare Turnstile im Managed-Modus, inklusive serverseitiger Siteverify-Prüfung
- Hostname- und Action-Prüfung für Turnstile-Tokens
- signierte Formularzeit und Honeypot-Feld ohne Session-Cookie
- Rate-Limits pro IP-Adresse und E-Mail-Adresse
- harte Grenzen für Orte, Rechtsformen, resultierende API-Aufrufe und Queue-Grösse
- Deduplizierung identischer offener Aufträge
- private Speicherung von Auftragsdaten und Exportdateien ausserhalb des Webroots
- 128-Bit-Download-Token und automatische Ablaufzeit
- CLI-Sperre für Executor, Cleanup und administratives Löschen
- eintägiger Cache für Gemeinden und Rechtsformen
## Erforderliche Umgebungsvariablen
| Variable | Bedeutung |
| --- | --- |
| `TURNSTILE_SECRET` | Geheimer Schlüssel des bestehenden Turnstile-Widgets für Siteverify |
| `APP_SECRET` | Zufälliger geheimer Wert für Formulartoken und pseudonymisierte Rate-Limits |
| `ZEFIX_PRIVATE_DIR` | Absoluter, dauerhaft beschreibbarer Pfad **ausserhalb** des Webroots |
| `username` | Benutzername der ZEFIX-API |
| `password` | Passwort der ZEFIX-API |
| `smtppassword` | Passwort des SMTP-Kontos |
Verwendet wird ausschliesslich das bestehende Turnstile-Widget `Zefix` mit dem Sitekey `0x4AAAAAAD7CJrWpNiK0-A7h`. Es darf nicht neu erstellt oder rotiert werden. Das Widget muss im Cloudflare-Dashboard als **Managed** mit dem Hostnamen `zefix.silias.ch` konfiguriert sein; Pre-Clearance bleibt deaktiviert. Das Secret gehört ausschliesslich als `TURNSTILE_SECRET` in die Serverumgebung und niemals ins Repository.
Empfohlene Werte:
```text
TURNSTILE_ALLOWED_HOSTNAME=zefix.silias.ch
PUBLIC_BASE_URL=https://zefix.silias.ch
ZEFIX_PRIVATE_DIR=/var/lib/zefix-export
APP_SECRET=<mindestens 32 zufällige Bytes>
```
Das bisherige, nicht versionierte `env_vars.php` wird für eine schonende Migration weiterhin geladen. Neue Installationen sollten echte Prozess-/PHP-FPM-Umgebungsvariablen verwenden.
Eine vollständige Vorlage ohne echte Zugangsdaten liegt in [`.env.example`](.env.example). Sie kann für das Deployment-Panel, Docker Compose (`env_file`) oder als Vorlage für die PHP-FPM-Konfiguration verwendet werden. Die Anwendung lädt `.env`-Dateien nicht selbstständig; die Deployment-Umgebung muss die Werte an den PHP-Prozess weiterreichen.
## Optionale Konfiguration
| Variable | Standard | Bedeutung |
| --- | ---: | --- |
| `RATE_LIMIT_IP_MAX` | `3` | Aufträge pro IP-Zeitfenster |
| `RATE_LIMIT_IP_WINDOW_SECONDS` | `900` | IP-Zeitfenster |
| `RATE_LIMIT_EMAIL_MAX` | `5` | Aufträge pro E-Mail-Zeitfenster |
| `RATE_LIMIT_EMAIL_WINDOW_SECONDS` | `86400` | E-Mail-Zeitfenster |
| `MAX_SEATS_PER_JOB` | `500` | maximale Orte pro Auftrag |
| `MAX_LEGAL_FORMS_PER_JOB` | `50` | maximale Rechtsformen pro Auftrag |
| `MAX_REQUESTS_PER_JOB` | `5000` | maximales Produkt aus Orten × Rechtsformen |
| `MAX_QUEUE_SIZE` | `20` | maximale offene Aufträge |
| `DOWNLOAD_RETENTION_HOURS` | `48` | Gültigkeit fertiger Exporte |
| `STALE_TASK_RETENTION_HOURS` | `168` | maximale Lebensdauer offener Aufträge |
| `REFERENCE_CACHE_SECONDS` | `86400` | Cache für Gemeinden und Rechtsformen |
| `TRUSTED_PROXY_IPS` | leer | kommaseparierte IPs eigener Reverse-Proxies |
| `EXPORT_BCC_EMAIL` | leer | optionale BCC-Adresse; standardmässig kein BCC |
| `APP_ENV` | leer | nur lokal auf `development` setzen; erlaubt die offiziellen Turnstile-Testschlüssel auf Loopback |
| `SMTP_HOST` | `mxe98c.netcup.net` | SMTP-Server |
| `SMTP_USERNAME` | `info@silias.ch` | SMTP-Benutzer |
| `SMTP_SECURE` | `ssl` | SMTP-Verschlüsselung |
| `SMTP_PORT` | `465` | SMTP-Port |
`TRUSTED_PROXY_IPS` darf nur tatsächlich kontrollierte Proxy-Adressen enthalten. Ohne Eintrag werden vom Browser gelieferte `X-Forwarded-For`- oder `CF-Connecting-IP`-Header bewusst ignoriert.
## Cronjob
`cronjobs.sh` führt zuerst die automatische Bereinigung und danach den Task-Executor aus. Beide PHP-Skripte akzeptieren ausschliesslich CLI-Aufrufe.
Beispiel:
```cron
*/2 * * * * /absoluter/pfad/cronjobs.sh
```
Ein manueller Cleanup kann mit `php cleanup.php` gestartet werden. Alle offenen Aufträge werden nur nach ausdrücklicher Bestätigung gelöscht:
```bash
php deleteFiles.php --confirm
```
## Nginx-Härtung
Die PHP-Skripte sperren Webzugriffe selbst. Zusätzlich sollten Altpfade und Wartungsskripte bereits in Nginx blockiert werden:
```nginx
location ~ ^/(taskExecuter|cleanup|deleteFiles)\.php$ { return 404; }
location ^~ /tasks/ { return 404; }
location ^~ /download/ { return 404; }
location = /env_vars.php { return 404; }
```
Nach dem ersten CLI-Lauf werden alte JSON-Aufträge aus `tasks/` in den privaten Speicher migriert. Anschliessend sollten die alten öffentlichen Verzeichnisse `tasks/` und `download/` nach Kontrolle entfernt werden.
## Datenschutz
Die öffentliche Datenschutzerklärung liegt unter `datenschutz.php`. Sie beschreibt Turnstile, die verarbeiteten Daten und die implementierten Löschfristen. Wenn später Analyse-, Marketing- oder weitere Drittanbieter-Dienste ergänzt werden, müssen Text und gegebenenfalls die Einwilligungsverwaltung erneut geprüft werden.