S3: Aus der Kontosperre wird eine Wartezeit. Die alte Sperre wies auch das richtige Passwort ab — wer die Adresse eines Administrators kannte, konnte ihn alle 15 Minuten neu aussperren. Jetzt bleiben vier Fehlversuche folgenlos, danach verdoppelt sich die Wartezeit bis zu einer Minute. Der Besitzer kommt spaetestens nach einer Minute hinein, ein Fremder bekommt einen Versuch pro Minute. Ausgewertet wird sie vor der Passwortpruefung, damit ein ohnehin abgewiesener Versuch keine 128 MiB kostet. S4: Drei Stufen statt einer. Die Bremse je Absender liest X-Forwarded-For nur noch mit TRUST_PROXY=true — ohne Proxy waehlt den Wert jeder Aufrufer selbst, und eine so umgehbare Bremse ist eine Behauptung. Dazu die Wartezeit je Konto, die an der Datenbank haengt, und eine Obergrenze fuer die ganze Installation: 60 Passwortpruefungen und 120 Rueckmeldungen je Minute. Die letzte Stufe ist die einzige, die sich nicht ueber Kopfzeilen umgehen laesst, und sie schuetzt den Speicher. CSP: Eine vollstaendige Policy mit Nonce je Anfrage, strict-dynamic, default-src self, object-src none, base-uri und form-action self. Skripte ohne den Nonce dieser Anfrage laufen nicht mehr. Zwei Lockerungen bleiben und stehen begruendet in der Doku: style-src erlaubt unsafe-inline, weil ein Nonce keine style-Attribute deckt, und media-src erlaubt https, weil der Typ Video ausdruecklich Direktlinks annimmt. Protokoll: Sicherheitsereignisse als JSON auf die Standardausgabe — Fehlversuche, OIDC-Verknuepfungen samt abgelehnten, Vergabe von Administratorrechten. Ohne Passwoerter, Token und Adressen. Refs #20
92 lines
4.0 KiB
Bash
92 lines
4.0 KiB
Bash
# ---------------------------------------------------------------------------
|
|
# QR-Code-Generator — Konfiguration
|
|
# Diese Datei nach ".env" kopieren und anpassen:
|
|
# cp .env.example .env
|
|
# ---------------------------------------------------------------------------
|
|
|
|
# Öffentliche Adresse, unter der die App erreichbar ist. Sie wird in
|
|
# dynamische QR-Codes einkodiert ({BASE_URL}/r/{slug}) und muss deshalb von
|
|
# den Geräten erreichbar sein, die den Code scannen.
|
|
# Im LAN z. B.: http://192.168.1.50:3000
|
|
BASE_URL=http://localhost:3000
|
|
|
|
# Host-Port, unter dem die App veröffentlicht wird (Port-Mapping APP_PORT:3000).
|
|
APP_PORT=3000
|
|
|
|
# Anmeldung mit Benutzern, Gruppen und Rollen.
|
|
# true — Anmeldung erforderlich. Beim ersten Aufruf legst du den ersten
|
|
# Administrator an. Das ist die Vorgabe, auch wenn die Zeile fehlt.
|
|
# false — jeder, der die App erreicht, darf alles: Verwaltung, Uploads,
|
|
# saemtliche Codes. Nur fuer Einzelplatz- oder LAN-Betrieb, und
|
|
# nur, wenn niemand Fremdes an den Rechner kommt. Der Container
|
|
# warnt beim Start deutlich, solange das so steht.
|
|
# Bewusst hier und nicht in der Oberfläche: so kann man sich nicht aussperren.
|
|
# Wer den Zugang verliert, setzt den Wert auf false und startet neu.
|
|
AUTH_ENABLED=true
|
|
|
|
# Steht ein Reverse Proxy davor, der `X-Forwarded-For` selbst setzt?
|
|
# false — Vorgabe. Die Kopfzeile wird nicht gelesen. Ohne Proxy koennte
|
|
# sie jeder Aufrufer selbst waehlen; eine Bremse, die sich so
|
|
# umgehen laesst, waere eine Behauptung.
|
|
# true — Nur setzen, wenn wirklich ein Proxy davorsteht und die Kopfzeile
|
|
# ueberschreibt. Sonst schenkst du jedem Aufrufer beliebig viele
|
|
# Anmeldeversuche.
|
|
# Unabhaengig davon gelten immer: die Wartezeit je Konto und die Obergrenze
|
|
# fuer die ganze Installation.
|
|
TRUST_PROXY=false
|
|
|
|
# Groesste erlaubte Datei fuer die Typen "PDF" und "Bild", in Megabyte.
|
|
# Die Dateien liegen in der Datenbank — wer die sichert, hat alles. Sehr
|
|
# grosse Werte machen die Sicherung entsprechend schwer.
|
|
MAX_UPLOAD_MB=10
|
|
|
|
# Sitzungsdauer in Tagen.
|
|
# SESSION_IDLE_DAYS — ohne Aktivitaet laeuft die Sitzung ab.
|
|
# SESSION_MAX_DAYS — harte Obergrenze ab dem Anmelden, unabhaengig davon,
|
|
# wie oft sie benutzt wurde.
|
|
# OWASP empfiehlt fuer oeffentliche Anwendungen deutlich kuerzere Werte
|
|
# (Minuten bzw. Stunden); siehe docs/sicherheit.md.
|
|
SESSION_IDLE_DAYS=30
|
|
SESSION_MAX_DAYS=90
|
|
|
|
# --- Anmeldung ueber Authentik oder einen anderen OIDC-Anbieter -------------
|
|
# Setzt AUTH_ENABLED=true voraus. Einrichtung siehe docs/authentik.md.
|
|
OIDC_ENABLED=false
|
|
|
|
# Basis-URL des Anbieters, unter der /.well-known/openid-configuration liegt.
|
|
# Bei Authentik: https://auth.example.com/application/o/<slug>/
|
|
OIDC_ISSUER=
|
|
OIDC_CLIENT_ID=
|
|
OIDC_CLIENT_SECRET=
|
|
|
|
# Beschriftung des Knopfs auf der Anmeldeseite.
|
|
OIDC_BUTTON_LABEL=Mit Authentik anmelden
|
|
|
|
# Angeforderte Bereiche. "openid" ist Pflicht, "email" wird gebraucht.
|
|
OIDC_SCOPES=openid email profile
|
|
|
|
# Nur noch ueber den Anbieter anmelden? Dann verschwindet das Passwortfeld.
|
|
# Vorsicht: Faellt der Anbieter aus, kommt niemand mehr hinein — zum Loesen
|
|
# hier auf false setzen und neu starten.
|
|
OIDC_ONLY=false
|
|
|
|
# Rolle, die neu angelegte Benutzer in der Standardgruppe bekommen.
|
|
# VIEWER (nur lesen), EDITOR (Codes anlegen und aendern) oder ADMIN.
|
|
OIDC_DEFAULT_ROLE=VIEWER
|
|
|
|
# Gruppe beim Anbieter, deren Mitglieder die Verwaltung oeffnen duerfen.
|
|
# Leer lassen, um die Administratorrechte hier in der Anwendung zu pflegen.
|
|
OIDC_ADMIN_GROUP=
|
|
# Name des Anspruchs, in dem die Gruppen stehen (Authentik: groups).
|
|
OIDC_GROUPS_CLAIM=groups
|
|
|
|
# --- PostgreSQL ------------------------------------------------------------
|
|
POSTGRES_USER=qrcode
|
|
POSTGRES_PASSWORD=bitte-aendern
|
|
POSTGRES_DB=qrcode
|
|
|
|
# Verbindungsstring der App zur Datenbank.
|
|
# "db" ist der Servicename aus docker-compose.yml — innerhalb des Compose-
|
|
# Netzwerks wird darüber die Datenbank aufgelöst.
|
|
DATABASE_URL=postgresql://qrcode:bitte-aendern@db:5432/qrcode?schema=public
|