HTTPS: eigene lokale Root-CA statt externem DuckDNS/Let's Encrypt

This commit is contained in:
2026-07-19 17:19:03 +02:00
parent a695159b1d
commit 31e17ff77b
6 changed files with 160 additions and 69 deletions

View File

@@ -20,11 +20,25 @@ docker compose up -d --build
## HTTPS im lokalen Netz
LaunchPad ist per HTTPS auf Port `8443` erreichbar (`https://<deine-ip>:8443`),
zusätzlich zu HTTP auf `8080` kein erzwungener Redirect. Beim ersten Start
erzeugt der Frontend-Container automatisch ein selbstsigniertes Zertifikat für
die in `.env` hinterlegte `LAUNCHPAD_HOST` (IP oder Hostname). Der Browser
zeigt dafür trotzdem eine Sicherheitswarnung das ist bei selbstsignierten
Zertifikaten normal, nicht per se unsicher fürs eigene LAN.
zusätzlich zu HTTP auf `8080` kein erzwungener Redirect, kein externer
Dienst beteiligt.
Der Frontend-Container erzeugt beim ersten Start automatisch eine **eigene
lokale Root-CA** (`LaunchPad Local CA`) und signiert damit ein Server-
Zertifikat für die in `.env` hinterlegte `LAUNCHPAD_HOST` (IP oder Hostname).
Beides liegt in einem Docker-Volume (`launchpad-certs`) und bleibt über
Neustarts und `--build` hinweg stabil die CA wird nur einmal erzeugt, nicht
bei jedem Deploy neu.
**Ohne weiteren Schritt** funktioniert HTTPS sofort, der Browser zeigt aber
eine Warnung (unbekannte CA). Für eine echte, warnungsfreie Verbindung und
damit Chrome die PWA auch wirklich "installiert" statt nur eine Verknüpfung
anzulegen reicht **ein einziger, pro Gerät einmaliger Schritt**: die
Root-CA importieren. Es gibt dafür keinen Weg drumherum, der nicht doch einen
externen Dienst braucht (siehe Kasten unten) aber so ist es so einfach wie
möglich gehalten.
### Root-CA einmal pro Gerät importieren
```bash
# .env: IP/Hostname eintragen, unter der du zugreifst
@@ -33,40 +47,40 @@ LAUNCHPAD_HOST=192.168.1.49
docker compose up -d --force-recreate frontend
```
Danach: `https://192.168.1.49:8443` (Warnung einmalig bestätigen/Ausnahme
hinzufügen).
**Am Handy (Android):** `http://192.168.1.49:8080/ca.crt` im Browser öffnen
(bewusst HTTP, dafür braucht's noch kein Vertrauen) → Android bietet direkt
"Zertifikat installieren" an → als "VPN und App" oder "WLAN"-Zertifikat
speichern (je nach Android-Version heißt die Kategorie leicht anders,
Hauptsache es landet unter "Von Nutzer installierte Zertifikate"). Danach ggf.
kurz Chrome neu starten.
### Ohne Browser-Warnung (empfohlen): eigenes Zertifikat per mkcert
**Am PC (Windows):** dieselbe URL im Browser öffnen, `ca.crt` herunterladen,
Datei doppelklicken → "Zertifikat installieren" → "Lokaler Computer" →
"Alle Zertifikate in folgendem Speicher speichern" → "Vertrauenswürdige
Stammzertifizierungsstellen" → Fertigstellen. Kein zusätzliches Tool nötig.
[mkcert](https://github.com/FiloSottile/mkcert) erzeugt lokal vertrauenswürdige
Zertifikate dein Browser vertraut ihnen automatisch, keine Warnung mehr.
**macOS:** `ca.crt` herunterladen, doppelklicken (öffnet Schlüsselbundverwaltung),
dort öffnen, Vertrauenseinstellung auf "Immer vertrauen" setzen.
```bash
# Einmalig auf dem Rechner, von dem aus du zugreifst (nicht auf dem Server):
mkcert -install
Danach zeigt `https://192.168.1.49:8443` keine Warnung mehr, und die
PWA-Installation sollte funktionieren.
# Zertifikat für IP/Hostname erzeugen:
mkcert -cert-file fullchain.pem -key-file privkey.pem 192.168.1.49 launchpad.home localhost 127.0.0.1
```
> **Warum es keinen Weg ganz ohne diesen Schritt gibt:** Damit ein Browser
> einem Zertifikat *automatisch*, ohne jeden manuellen Trust-Schritt, vertraut,
> muss es entweder von einer öffentlich vorinstallierten CA stammen (z. B.
> Let's Encrypt) das erfordert zwangsläufig einen externen Dienst und meist
> einen öffentlich auflösbaren Domainnamen oder eben eine lokale CA, die du
> einmal manuell für vertrauenswürdig erklärst. Es gibt keine dritte Option.
> Diese Lösung minimiert den Aufwand auf "eine Datei öffnen, einmal pro Gerät",
> mehr geht ohne externe Dienste nicht.
Die beiden erzeugten Dateien nach `/opt/LaunchPad/certs/` kopieren, dann in
`docker-compose.yml` die auskommentierten `volumes:`-Zeilen beim
`frontend`-Service aktivieren:
### Zertifikat wechseln / eigenes einbinden
```yaml
volumes:
- ./certs/fullchain.pem:/etc/nginx/certs/fullchain.pem:ro
- ./certs/privkey.pem:/etc/nginx/certs/privkey.pem:ro
```
```bash
docker compose up -d --force-recreate frontend
```
`mkcert -install` legt eine lokale Root-CA an, der nur *dieser* Rechner
vertraut. Für weitere Geräte (Handy etc.) muss die Root-CA
(`mkcert -CAROOT` zeigt den Pfad) dort zusätzlich installiert werden, oder es
bleibt bei der Browser-Warnung des automatisch generierten Zertifikats.
Falls du lieber ein eigenes Zertifikat verwendest (z. B. von einer internen
CA, die du schon hast): `fullchain.pem` + `privkey.pem` ins Volume
`launchpad-certs` legen (z. B. `docker cp fullchain.pem launchpad-frontend:/etc/nginx/certs/` bei laufendem Container, oder das Volume direkt mounten),
danach `docker compose restart frontend`. Liegt dabei keine `ca-cert.pem` im
selben Verzeichnis, generiert der Entrypoint nichts automatisch nach.
## Quickstart (lokale Entwicklung)