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. Für eine klassische Installation kann sie als .env einen Ordner über dem Projektverzeichnis abgelegt werden. Diese Datei wird beim Start automatisch geladen. Bereits gesetzte Prozessvariablen und Werte aus der bisherigen env_vars.php haben Vorrang.
Beispiel bei einem Projekt unter /var/www/zefix:
/var/www/.env # echte, nicht versionierte Zugangsdaten
/var/www/zefix/app.php # Projekt
Alternativ kann die Vorlage weiterhin für ein Deployment-Panel, Docker Compose (env_file) oder die PHP-FPM-Konfiguration verwendet werden.
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.