docs: Installationsanleitung fuer vorhandenes Docker und externen Proxy
Die Anleitung setzt jetzt voraus, was ohnehin da ist: ein Server mit laufendem Docker und ein Reverse Proxy, der schon steht - auch auf einem anderen Rechner. Docker-Installation und Betriebssystemhaertung sind raus, dafuer ist der Proxy-Abschnitt der ausfuehrlichste geworden. Damit ein externer Proxy die Anwendung ueberhaupt erreicht, war eine Aenderung noetig: Die Bindeadresse stand fest auf 127.0.0.1. Jetzt gibt es APP_BIND, Standard bleibt die Loopback-Adresse. Der Weg dorthin ist nach Vorzug sortiert - privates Netz, dann WireGuard, dann als Notloesung oeffentliche Adresse mit Firewallregel. Zwischen Proxy und Anwendung laeuft unverschluesseltes HTTP; das gehoert nicht ins offene Netz. Deshalb steht in der Kontrolle eine Gegenprobe, die fehlschlagen MUSS: Antwortet der Anwendungsport von aussen, ist die Firewallregel falsch. Fertige Konfigurationen fuer Caddy, nginx und Traefik, jeweils mit den Werten, die sonst uebersehen werden: - Zeitgrenze 10 Minuten - sonst brechen Belegmappe, Rechnungslegung und Vollexport mitten im Erzeugen ab. Die Standardwerte von nginx liegen bei 60 Sekunden. - Antwort nicht puffern - der Vollexport kommt als Strom. Puffert der Proxy, wartet der Browser, bis alles im Speicher des Proxys liegt, und laeuft dabei in die Zeitgrenze. - Und der Hinweis, dass der Proxy KEINE eigene CSP setzen darf: Sie enthaelt eine Nonce, die pro Anfrage neu ist. Eine feste CSP blockiert die eigenen Skripte - die Seite laedt dann, laesst sich aber nicht bedienen. Der A-Record zeigt auf den Proxy-Server, nicht auf den Anwendungsserver. Stand vorher falsch da. Etappe: 8 Phase: Haertung
This commit is contained in:
@@ -51,7 +51,7 @@ eines Angehörigen: Fristen, Vorgänge, Belege, Vermögen, Sozialhilfe, Berichte
|
||||
|
||||
| Wofür | Wo |
|
||||
|---|---|
|
||||
| **Einen Server aufsetzen** — von der leeren Maschine bis zur laufenden Anwendung, mit Kontrolle nach jedem Schritt | [`docs/INSTALLATION.md`](docs/INSTALLATION.md) |
|
||||
| **Die Anwendung aufsetzen** — auf einem Server, der Docker und einen Proxy schon hat, mit Kontrolle nach jedem Schritt | [`docs/INSTALLATION.md`](docs/INSTALLATION.md) |
|
||||
| **Täglich damit arbeiten** — die zwölf Handgriffe, der Jahresrhythmus, was tun wenn etwas schiefgeht | [`docs/ANLEITUNG.md`](docs/ANLEITUNG.md), in der Anwendung unter `/anleitung` |
|
||||
| **Wissen, was sich ändert** — was neu ist, was du vor einem Update beachten musst | [`CHANGELOG.md`](CHANGELOG.md) |
|
||||
|
||||
@@ -188,61 +188,45 @@ Backup anstoßen** (siehe unten) — eine Migration lässt sich nicht zurückrol
|
||||
|
||||
## Reverse Proxy
|
||||
|
||||
Die Anwendung erwartet, dass der Proxy TLS beendet und die echte Client-IP
|
||||
weiterreicht. Sie liest `X-Forwarded-For` bzw. `X-Real-IP` für das
|
||||
Rate-Limiting am Login und für das Audit-Log (dort nur als Hash).
|
||||
Die Anwendung **beendet selbst kein TLS** und bringt keinen Proxy mit. Sie
|
||||
horcht standardmäßig auf `127.0.0.1:3000`.
|
||||
|
||||
**Caddy**
|
||||
**Läuft der Proxy auf demselben Server**, ist damit alles gesagt: Er zeigt
|
||||
auf `127.0.0.1:3000`, fertig.
|
||||
|
||||
```caddyfile
|
||||
cockpit.example.de {
|
||||
encode zstd gzip
|
||||
reverse_proxy 127.0.0.1:3000
|
||||
**Läuft er auf einem anderen Server**, setz in der `.env` die Adresse, über
|
||||
die er herankommt — am besten die eines privaten Netzes oder eines
|
||||
WireGuard-Tunnels:
|
||||
|
||||
# Uploads: Fotos von Behördenschreiben können groß sein.
|
||||
request_body {
|
||||
max_size 30MB
|
||||
}
|
||||
}
|
||||
```bash
|
||||
APP_BIND=10.0.0.5
|
||||
APP_PORT=3000
|
||||
```
|
||||
|
||||
**nginx**
|
||||
`0.0.0.0` nur, wenn eine Firewall den Port ausschließlich für die IP des
|
||||
Proxy-Servers öffnet. Zwischen Proxy und Anwendung läuft unverschlüsseltes
|
||||
HTTP — dieser Weg darf nie durchs offene Netz gehen.
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name cockpit.example.de;
|
||||
### Was der Proxy leisten muss
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/cockpit.example.de/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/cockpit.example.de/privkey.pem;
|
||||
| Anforderung | Was ohne sie passiert |
|
||||
|---|---|
|
||||
| TLS beenden | Der Browser lehnt Cookies mit `Secure`-Kennzeichen ab, die Anmeldung schlägt stumm fehl |
|
||||
| `Host` durchreichen | Auth.js vergleicht ihn mit `AUTH_URL` und weist die Anmeldung ab |
|
||||
| `X-Forwarded-Proto: https` | Die Anwendung baut Adressen mit `http` |
|
||||
| `X-Forwarded-For` | Die Login-Sperre zählt alle Zugriffe als denselben Anschluss |
|
||||
| Uploads ≥ 30 MB | Fotos mehrseitiger Bescheide werden abgeschnitten |
|
||||
| Zeitgrenze ≥ 10 Minuten | Belegmappe, Rechnungslegung und Vollexport brechen ab |
|
||||
| Antwort nicht puffern | Der Vollexport kommt als Strom |
|
||||
|
||||
client_max_body_size 30M;
|
||||
**Keine eigenen Sicherheitskopfzeilen setzen.** CSP, `X-Frame-Options`,
|
||||
`nosniff` und HSTS kommen aus der Anwendung. Die CSP enthält eine Nonce,
|
||||
die pro Anfrage neu ist — eine feste CSP aus dem Proxy blockiert die
|
||||
eigenen Skripte.
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3000;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Traefik** (Labels am `app`-Dienst)
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
- traefik.enable=true
|
||||
- traefik.http.routers.cockpit.rule=Host(`cockpit.example.de`)
|
||||
- traefik.http.routers.cockpit.tls.certresolver=letsencrypt
|
||||
- traefik.http.services.cockpit.loadbalancer.server.port=3000
|
||||
```
|
||||
|
||||
In allen Fällen muss `AUTH_URL` in der `.env` auf die öffentliche Adresse
|
||||
zeigen (`https://cockpit.example.de`), sonst schlägt die Anmeldung fehl.
|
||||
**Fertige Konfigurationen** für Caddy, nginx und Traefik, mit Zeitgrenzen
|
||||
und den Gegenproben, stehen in
|
||||
[`docs/INSTALLATION.md`](docs/INSTALLATION.md), Schritt 7.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user