5.6 KiB
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:
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. 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:
*/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:
php deleteFiles.php --confirm
Nginx-Härtung
Die PHP-Skripte sperren Webzugriffe selbst. Zusätzlich sollten Altpfade und Wartungsskripte bereits in Nginx blockiert werden:
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.