Domain-Check für DNS, Webserver und Zertifikat #7

Closed
opened 2026-08-20 23:21:15 +00:00 by florian.wilde · 2 comments
Owner

Angelegt aus QR Code Generator in Nebula.

_Angelegt aus [QR Code Generator](https://nebula.wilde-ste.de/projects/cmss12yq702p6mm01ctlfe6nz) in Nebula._
florian.wilde added the in-arbeit label 2026-08-21 00:54:22 +00:00
florian.wilde started working 2026-08-21 00:54:32 +00:00
florian.wilde worked for 12 minutes 2026-08-21 01:07:01 +00:00
florian.wilde added zu-testen and removed in-arbeit labels 2026-08-21 01:07:35 +00:00
Author
Owner

✅ Umsetzung abgeschlossen — bereit zum Testen.

Das Issue hatte keinen Beschreibungstext; im Chat habe ich vorab abgestimmt, dass die Prüfung Ende zu Ende gehen soll — also nicht bloß DNS, Webserver und Zertifikat einzeln melden, sondern feststellen, ob die Domain tatsächlich bei dieser Installation ankommt.

Was geändert wurde

  • Auf Verwaltung → Domains steht bei jedem Eintrag ein Knopf Prüfen. Darunter erscheint ein Bericht mit vier Zeilen:

    Schritt Beispiel
    DNS löst auf 203.0.113.10
    Zertifikat gültig bis 27.10.2026, ausgestellt von SSL Corporation
    Erreichbar HTTP 200 nach 84 ms
    Ziel diese Installation
  • Der letzte Schritt ist der eigentliche Wert. Die Anwendung ruft unter der Domain eine eigene Route auf und lässt sich einen HMAC über eine frische Zufallszahl zurückgeben. Das Geheimnis dafür entsteht beim ersten Check und verlässt den Server nie — so unterscheidet sich „zeigt irgendwohin“ von „zeigt hierher“.

  • Sprechende Fehlermeldungen statt Codes: abgelaufen, selbst ausgestellt, falscher Name, Zwischenzertifikat fehlt, Port 443 nimmt nichts an, „es antwortet etwas, aber nicht diese Anwendung“.

  • Läuft ein Zertifikat in ≤ 14 Tagen ab, gilt der Schritt als Warnung statt als Erfolg.

  • Scheitert schon DNS, fallen die drei Folgeschritte aus — dreimal dieselbe Meldung hätte die eine wichtige verdeckt.

Grenze der Aussage — steht so auch unter jedem Bericht: Der Aufruf startet dort, wo der Container läuft. Bei internem DNS oder Hairpin-NAT kann er scheitern, obwohl von außen alles stimmt; umgekehrt beweist ein Erfolg von innen nicht, dass die Domain von außen erreichbar ist.

Migration: 20260821010000_domain_check — eine Spalte checkSecret (leer, füllt sich beim ersten Check).

Geänderte Dateien

  • src/lib/domain-check.ts (neu)
  • src/app/api/domain-check/route.ts (neu)
  • src/app/api/admin/domains/[id]/check/route.ts (neu)
  • src/components/domain-bericht.tsx (neu)
  • src/components/domain-admin.tsx
  • prisma/schema.prisma + Migration
  • README.md, docs/sicherheit.md

So testest du es

  1. git switch feat/7-domain-check
  2. docker compose up -d --build app (die Migration läuft beim Start mit)
  3. Verwaltung → Domains öffnen, bei einem Eintrag auf Prüfen klicken.
  4. Erwartet bei einer richtig eingerichteten Domain: vier grüne Zeilen und „Die Domain führt hierher.“
  5. Gegenprobe: eine Domain registrieren, die es nicht gibt (z. B. gibt-es-nicht.invalid) → DNS meldet den fehlenden A-Eintrag, der Rest fällt aus.
  6. Zweite Gegenprobe: example.com registrieren → DNS und Zertifikat in Ordnung, aber „Es antwortet zwar etwas, aber nicht diese Anwendung“.

Geprüft mit einer eigenen Testreihe: 38 von 38 — Beweis-Route samt Fehlformen, alle drei Fälle oben, Oberfläche, Handy-Breite, keine Konsolenfehler.

Aufgewendete Zeit: 00:12
Pull Request: #15

Nach Freigabe: /issue-freigabe 7


Am Rande aufgefallen (kein eigenes Issue angelegt):

  • Die Kurzhilfe aus #4 nennt unter „Nachprüfen“ noch einen curl-Befehl. Sobald beide Zweige in main sind, gehört dort stattdessen ein Verweis auf diesen Knopf. Kleiner Handgriff, den ich gern nachziehe.
  • src/app/api/codes/route.ts mischt in einer Fehlermeldung ein typografisches „ mit einem geraden " — rein kosmetisch.
✅ **Umsetzung abgeschlossen — bereit zum Testen.** <!-- claude-status branch: feat/7-domain-check pr: 15 zeit_sekunden: 749 --> Das Issue hatte keinen Beschreibungstext; im Chat habe ich vorab abgestimmt, dass die Prüfung **Ende zu Ende** gehen soll — also nicht bloß DNS, Webserver und Zertifikat einzeln melden, sondern feststellen, ob die Domain tatsächlich bei dieser Installation ankommt. **Was geändert wurde** - Auf **Verwaltung → Domains** steht bei jedem Eintrag ein Knopf **Prüfen**. Darunter erscheint ein Bericht mit vier Zeilen: | Schritt | Beispiel | | --- | --- | | DNS | `löst auf 203.0.113.10` | | Zertifikat | `gültig bis 27.10.2026, ausgestellt von SSL Corporation` | | Erreichbar | `HTTP 200 nach 84 ms` | | Ziel | `diese Installation` | - Der letzte Schritt ist der eigentliche Wert. Die Anwendung ruft unter der Domain eine eigene Route auf und lässt sich einen HMAC über eine frische Zufallszahl zurückgeben. Das Geheimnis dafür entsteht beim ersten Check und verlässt den Server nie — so unterscheidet sich „zeigt irgendwohin“ von „zeigt hierher“. - Sprechende Fehlermeldungen statt Codes: abgelaufen, selbst ausgestellt, falscher Name, Zwischenzertifikat fehlt, Port 443 nimmt nichts an, „es antwortet etwas, aber nicht diese Anwendung“. - Läuft ein Zertifikat in ≤ 14 Tagen ab, gilt der Schritt als Warnung statt als Erfolg. - Scheitert schon DNS, fallen die drei Folgeschritte aus — dreimal dieselbe Meldung hätte die eine wichtige verdeckt. **Grenze der Aussage** — steht so auch unter jedem Bericht: Der Aufruf startet dort, wo der Container läuft. Bei internem DNS oder Hairpin-NAT kann er scheitern, obwohl von außen alles stimmt; umgekehrt beweist ein Erfolg von innen nicht, dass die Domain von außen erreichbar ist. **Migration:** `20260821010000_domain_check` — eine Spalte `checkSecret` (leer, füllt sich beim ersten Check). **Geänderte Dateien** - `src/lib/domain-check.ts` (neu) - `src/app/api/domain-check/route.ts` (neu) - `src/app/api/admin/domains/[id]/check/route.ts` (neu) - `src/components/domain-bericht.tsx` (neu) - `src/components/domain-admin.tsx` - `prisma/schema.prisma` + Migration - `README.md`, `docs/sicherheit.md` **So testest du es** 1. `git switch feat/7-domain-check` 2. `docker compose up -d --build app` (die Migration läuft beim Start mit) 3. **Verwaltung → Domains** öffnen, bei einem Eintrag auf **Prüfen** klicken. 4. Erwartet bei einer richtig eingerichteten Domain: vier grüne Zeilen und „Die Domain führt hierher.“ 5. Gegenprobe: eine Domain registrieren, die es nicht gibt (z. B. `gibt-es-nicht.invalid`) → DNS meldet den fehlenden A-Eintrag, der Rest fällt aus. 6. Zweite Gegenprobe: `example.com` registrieren → DNS und Zertifikat in Ordnung, aber „Es antwortet zwar etwas, aber nicht diese Anwendung“. Geprüft mit einer eigenen Testreihe: **38 von 38** — Beweis-Route samt Fehlformen, alle drei Fälle oben, Oberfläche, Handy-Breite, keine Konsolenfehler. **Aufgewendete Zeit:** 00:12 **Pull Request:** #15 Nach Freigabe: `/issue-freigabe 7` --- **Am Rande aufgefallen** (kein eigenes Issue angelegt): - Die Kurzhilfe aus #4 nennt unter „Nachprüfen“ noch einen `curl`-Befehl. Sobald beide Zweige in `main` sind, gehört dort stattdessen ein Verweis auf diesen Knopf. Kleiner Handgriff, den ich gern nachziehe. - `src/app/api/codes/route.ts` mischt in einer Fehlermeldung ein typografisches „ mit einem geraden " — rein kosmetisch.
Author
Owner

🚀 Freigegeben und nach main übernommen.

  • Merge-Commit: 43a0504
  • Pull Request: #15 (gemergt)
  • Gesamtaufwand: 00:12

Konflikt mit #4, aufgelöst. Beide Zweige haben src/components/domain-admin.tsx angefasst — #4 den Kurzhilfe-Knopf, #7 den Prüfen-Knopf. Betroffen war am Ende nur der Importblock; beide Seiten wurden übernommen, keine Zeile der jeweils anderen geändert. Zusammengeführt per git merge main in den Zweig, nicht per Rebase — ein geteilter Zweig soll keinen Force-Push sehen.

Danach zur Sicherheit beide Testreihen nebeneinander laufen lassen: Kurzhilfe 24 von 24, Domain-Check 38 von 38. Typprüfung und Linter auf main: grün.

Issue wird geschlossen.

🚀 **Freigegeben und nach `main` übernommen.** <!-- claude-status merge: 43a0504 pr: 15 zeit_sekunden: 749 --> - Merge-Commit: `43a0504` - Pull Request: #15 (gemergt) - Gesamtaufwand: 00:12 **Konflikt mit #4, aufgelöst.** Beide Zweige haben `src/components/domain-admin.tsx` angefasst — #4 den Kurzhilfe-Knopf, #7 den Prüfen-Knopf. Betroffen war am Ende nur der Importblock; beide Seiten wurden übernommen, keine Zeile der jeweils anderen geändert. Zusammengeführt per `git merge main` in den Zweig, nicht per Rebase — ein geteilter Zweig soll keinen Force-Push sehen. Danach zur Sicherheit beide Testreihen nebeneinander laufen lassen: Kurzhilfe **24 von 24**, Domain-Check **38 von 38**. Typprüfung und Linter auf `main`: grün. Issue wird geschlossen.
florian.wilde removed the zu-testen label 2026-08-21 08:54:19 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Total Time Spent: 12 minutes
florian.wilde
12 minutes
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: florian.wilde/qrcode-generator#7