Skip to content

Security: Admin-UI standardmäßig nur auf Loopback binden + ACME-Versuche für den Ownership-Marker stoppen - #230

Merged
CallMeTechie merged 1 commit into
masterfrom
fix/bind-localhost-and-marker-acme
Jul 25, 2026
Merged

CallMeTechie merged 1 commit into
masterfrom
fix/bind-localhost-and-marker-acme

Conversation

@CallMeTechie

Copy link
Copy Markdown
Owner

Aufgefallen bei einer Neuinstallation auf einem fremden Server. Beide Befunde sind nicht installationsspezifisch — der erste ist auf unserem eigenen Produktivhost reproduziert.

1 · Admin-UI war unverschlüsselt aus dem Internet erreichbar (Security)

Die ausgelieferte Compose-Datei läuft mit network_mode: host (docker-compose.yml:5, deploy/docker-compose.yml:5). Es gibt also kein Port-Mapping, das die Bindung eingrenzen könnte — was der Prozess bindet, liegt unmittelbar auf allen Interfaces des Hosts. Der Default war GC_HOST=0.0.0.0, und zwar sowohl in config/default.js:28 als auch in beiden .env.example.

Belegt, nicht vermutet: auf unserem eigenen Server zeigt ss ein LISTEN 0.0.0.0:3000, und http://54.36.233.20:3000 antwortet mit HTTP 302 — die Admin-Oberfläche also im Klartext, an Caddy, TLS und HSTS vorbei.

Änderung: Default auf 127.0.0.1, an allen drei Stellen. Caddy spricht die App ohnehin über 127.0.0.1:3000 an (caddyConfig.js:696 und :749, in der Live-Config gegengeprüft), erreicht sie im Host-Netz also unverändert.

Bewusste Inkaufnahme: Wer den Port aus einem Bridge-Netzwerk veröffentlicht statt Host-Networking zu nutzen, muss GC_HOST=0.0.0.0 künftig ausdrücklich setzen. Das ist eine sichtbare, schnell diagnostizierte Änderung — die Alternative wäre, dass jede Standardinstallation eine Admin-Anmeldemaske unverschlüsselt ins Netz stellt. Die Umstellung steht deshalb ausdrücklich im CHANGELOG.

Wirkt nicht rückwirkend: laufende Installationen übernehmen das erst nach Anpassung ihrer .env und einem Neustart.

2 · Dauerhafte ACME-Fehlversuche für gc-owner.invalid

Der Ownership-Marker aus #191 nutzt den RFC-6761-Namen gc-owner.invalid (caddyOwner.js:47), für den es naturgemäß kein öffentliches Zertifikat geben kann. Ursache der Fehlversuche ist eine Reihenfolge im Config-Builder:

  • buildTlsAutomation() wird bei caddyConfig.js:683 aus den Routen-Domains gebaut.
  • Die Marker-Route wird erst bei caddyConfig.js:842 angehängt.

Der Marker-Host erreicht die TLD-Klassifizierung also nie — obwohl invalid in NON_PUBLIC_TLDS steht und korrekt als intern eingestuft würde. Caddys automatisches HTTPS greift dadurch und versucht endlos, ein Zertifikat zu beziehen.

Änderung: automatic_https: { skip: [MARKER_HOST] } am Server-Block. Präziser als eine Umsortierung der Config-Erzeugung, denn für diesen Host ist kein Zertifikat gewünscht — auch kein internes.

Nicht geändert: GC_CADDY_EMAIL

Der ursprüngliche Hinweis lautete, die generierte Config enthalte kein Mail-Feld, obwohl die Variable gesetzt sei. Das konnte ich nicht nachvollziehen: buildTlsAutomation schreibt die Adresse (caddyTlsAutomation.js:53), sobald sie gesetzt ist, und es gibt keinen Pfad, der sie verwirft. Ist sie leer, wird allerdings der komplette Automation-Block verworfen (return null, Zeile 30) — was dasselbe Symptom erzeugt und zusätzlich Punkt 2 auslöst, weil dann keine Regel mehr .invalid auf den internen Aussteller lenkt.

Ob der Default von GC_CADDY_EMAIL künftig gesetzt sein sollte, ist eine Produktentscheidung und bleibt hier bewusst außen vor.

Tests

tests/bind_host_and_marker_tls.test.js, 6 Fälle. Er prüft nicht nur die geänderten Werte, sondern auch die Annahme dahinter: dass die Compose-Dateien weiterhin Host-Networking nutzen und Caddy die App über Loopback anspricht. Fällt eine der beiden Voraussetzungen weg, schlägt der Test an, statt still falsch zu werden.

Gegen den ungefixten Stand gegengeprüft: 2 der 6 Fälle schlagen fehl, die Tests sind also nicht tautologisch.

Volle Suite: 2296 bestanden, 0 fehlgeschlagen.

@CallMeTechie
CallMeTechie force-pushed the fix/bind-localhost-and-marker-acme branch from e9f20f6 to 808f9ec Compare July 25, 2026 20:21
@CallMeTechie
CallMeTechie merged commit fc31a59 into master Jul 25, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant