diff --git a/resources/views/livewire/help/content/de/domain-tls.blade.php b/resources/views/livewire/help/content/de/domain-tls.blade.php new file mode 100644 index 0000000..e1daea4 --- /dev/null +++ b/resources/views/livewire/help/content/de/domain-tls.blade.php @@ -0,0 +1,51 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; + $li = 'text-sm leading-relaxed text-ink-2'; + $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text'; + $pre = 'overflow-x-auto rounded-md border border-line bg-inset p-3 font-mono text-[11px] leading-relaxed text-ink-2'; +@endphp + +
+

Drei Betriebsarten

+

Wo und wie das Panel erreichbar ist, stellst du unter System → Domain & TLS ein. + Änderungen an der Domain greifen erst nach einem Stack-Neustart (Knopf in System).

+ +
+ +
+

Eingebautes TLS (Let's Encrypt)

+
    +
  1. DNS deiner Domain auf die Server-IP zeigen lassen.
  2. +
  3. System → Domain eintragen, TLS-Terminierung auf „Eingebautes TLS".
  4. +
  5. Speichern → Stack neu starten. Das Zertifikat wird beim ersten HTTPS-Aufruf automatisch ausgestellt und erneuert.
  6. +
+
+ +
+

Hinter einem externen Reverse-Proxy (Proxy Manager)

+

In diesem Modus terminiert dein vorgelagerter Proxy TLS; Clusev stellt kein eigenes Zertifikat aus.

+ +

1. Im Panel: System → Domain eintragen → TLS-Terminierung auf „Externer Reverse-Proxy" → speichern → Stack neu starten.

+ +

2. Im Proxy Manager: einen neuen Host/Eintrag anlegen mit diesen Werten:

+
Eingehende Domain:   panel.<deine-domain>
+Ziel / Backend:      http://<Clusev-Server-IP>:80        (HTTP, nicht HTTPS)
+Weiterreichen:       Host-Header  +  X-Forwarded-Proto: https
+WebSocket:           aktivieren  (für Realtime: /app/*  und  /apps/*)
+

Wichtig: das Ziel ist HTTP auf Port 80 des Clusev-Servers, und der Proxy muss X-Forwarded-Proto: https sowie WebSocket-Upgrades weiterreichen — sonst bleiben Assets/Login bzw. die Live-Verbindung leer.

+ +

3. Auf dem Clusev-Server (`.env`): setze die Proxy-Adresse als vertrauenswürdig — sonst sind das `Secure`-Cookie und die echte Besucher-IP im Audit-Log nicht korrekt:

+
TRUSTED_PROXY_CIDR=<Proxy-IP>/32
+
+# danach einmal anwenden:
+sudo ./update.sh
+ +

4. Firewall: sichere den HTTP-Port (80) des Clusev-Servers so ab, dass er nur vom Proxy erreichbar ist.

+ +

Hinweis: Über die Domain (HTTPS) funktioniert alles inkl. Security-Keys. Der Bare-IP-Weg (http://<Server-IP>) bleibt als Recovery erreichbar — dort gelten die Einschränkungen aus „Sicherheit & 2FA".

+
diff --git a/resources/views/livewire/help/content/en/domain-tls.blade.php b/resources/views/livewire/help/content/en/domain-tls.blade.php new file mode 100644 index 0000000..fef45f7 --- /dev/null +++ b/resources/views/livewire/help/content/en/domain-tls.blade.php @@ -0,0 +1,51 @@ +@php + $h = 'font-display text-base font-semibold text-ink'; + $p = 'text-sm leading-relaxed text-ink-2'; + $li = 'text-sm leading-relaxed text-ink-2'; + $code = 'rounded bg-inset px-1.5 py-0.5 font-mono text-[12px] text-accent-text'; + $pre = 'overflow-x-auto rounded-md border border-line bg-inset p-3 font-mono text-[11px] leading-relaxed text-ink-2'; +@endphp + +
+

Three modes

+

Where and how the panel is reachable is set under System → Domain & TLS. + Domain changes apply only after a stack restart (button in System).

+ +
+ +
+

Built-in TLS (Let's Encrypt)

+
    +
  1. Point your domain's DNS at the server IP.
  2. +
  3. System → enter the domain, TLS termination set to "Built-in TLS".
  4. +
  5. Save → restart the stack. The certificate is issued and renewed automatically on the first HTTPS request.
  6. +
+
+ +
+

Behind an external reverse proxy (proxy manager)

+

In this mode your upstream proxy terminates TLS; Clusev issues no certificate of its own.

+ +

1. In the panel: System → enter the domain → TLS termination to "External reverse proxy" → save → restart the stack.

+ +

2. In the proxy manager: create a new host/entry with these values:

+
Incoming domain:   panel.<your-domain>
+Target / backend:  http://<clusev-server-ip>:80        (HTTP, not HTTPS)
+Forward:           Host header  +  X-Forwarded-Proto: https
+WebSocket:         enable  (for realtime: /app/*  and  /apps/*)
+

Important: the target is HTTP on port 80 of the Clusev server, and the proxy must forward X-Forwarded-Proto: https and WebSocket upgrades — otherwise assets/login or the live connection stay blank.

+ +

3. On the Clusev server (`.env`): mark the proxy address as trusted — otherwise the `Secure` cookie and the real visitor IP in the audit log are not correct:

+
TRUSTED_PROXY_CIDR=<proxy-ip>/32
+
+# then apply once:
+sudo ./update.sh
+ +

4. Firewall: secure the Clusev server's HTTP port (80) so it is reachable only from the proxy.

+ +

Note: over the domain (HTTPS) everything works including security keys. The bare-IP path (http://<server-ip>) stays reachable for recovery — the limits there are covered under "Security & 2FA".

+
diff --git a/tests/Feature/HelpPageTest.php b/tests/Feature/HelpPageTest.php index 0b4db15..d2edd92 100644 --- a/tests/Feature/HelpPageTest.php +++ b/tests/Feature/HelpPageTest.php @@ -36,4 +36,14 @@ class HelpPageTest extends TestCase $this->actAsAdmin(); Livewire::test(Index::class, ['topic' => 'bogus'])->assertSet('topic', 'overview'); } + + public function test_domain_tls_topic_has_the_reverse_proxy_guide(): void + { + $this->actAsAdmin(); + Livewire::test(Index::class) + ->set('topic', 'domain-tls') + ->assertSee('X-Forwarded-Proto') + ->assertSee('TRUSTED_PROXY_CIDR') + ->assertDontSee('Zoraxy'); // generic — no product names + } }