Security: Admin-UI standardmäßig nur auf Loopback binden + ACME-Versuche für den Ownership-Marker stoppen - #230
Merged
Conversation
…e ownership marker
CallMeTechie
force-pushed
the
fix/bind-localhost-and-marker-acme
branch
from
July 25, 2026 20:21
e9f20f6 to
808f9ec
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 warGC_HOST=0.0.0.0, und zwar sowohl inconfig/default.js:28als auch in beiden.env.example.Belegt, nicht vermutet: auf unserem eigenen Server zeigt
sseinLISTEN 0.0.0.0:3000, undhttp://54.36.233.20:3000antwortet 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 über127.0.0.1:3000an (caddyConfig.js:696und: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.0kü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
.envund einem Neustart.2 · Dauerhafte ACME-Fehlversuche für
gc-owner.invalidDer 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 beicaddyConfig.js:683aus den Routen-Domains gebaut.caddyConfig.js:842angehängt.Der Marker-Host erreicht die TLD-Klassifizierung also nie — obwohl
invalidinNON_PUBLIC_TLDSsteht 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_EMAILDer ursprüngliche Hinweis lautete, die generierte Config enthalte kein Mail-Feld, obwohl die Variable gesetzt sei. Das konnte ich nicht nachvollziehen:
buildTlsAutomationschreibt 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.invalidauf den internen Aussteller lenkt.Ob der Default von
GC_CADDY_EMAILkü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.