diff --git a/CHANGELOG.md b/CHANGELOG.md index 91e3810..74a21b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,18 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/). ## [Unveröffentlicht] +### Hinzugefügt + +### Geändert + +### Behoben + +### Entfernt + +### Sicherheit + +## [0.1.0] – 2026-10-12 + ### Hinzugefügt - Architektur- und Umsetzungsplan (`docs/architektur.md`) mit Prüfung der Proxmox-API 8.x/9.x und der Image-Quellen (#001) - Issues #001–#020 für die sechs Etappen und den Feldtest (#001) @@ -17,14 +29,11 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/). - Server-Verwaltung: Proxmox-Server anlegen, bearbeiten, löschen; Zertifikat ansehen und Fingerprint pinnen; Verbindung vor dem Speichern prüfen (#002) - Optionales SSH-Schlüsselpaar je Server mit Einzeiler zum Hinterlegen auf den Nodes (#002) - Server-Umschalter in der Seitenleiste, Serverliste auf der Übersicht (#002) +- Verbindungstest: Version, Cluster, Nodes, Storages, Bridges, VNets und die Rechte des Tokens; je Vorgang, ob er per API, per SSH oder gar nicht geht (#003) +- SSH zu den Nodes mit Host-Key-Pinning nach Bestätigung (#003) +- `docs/proxmox-rechte.md`: Rolle `ProxDeploy` für PVE 8 und 9 mit fertigen `pveum`-Befehlen (#003) - Proxmox-Client mit verständlichen Fehlern (Ursache + Hinweis, fehlendes Recht samt Pfad) und Warten auf Proxmox-Tasks (#002) -### Geändert - -### Behoben - -### Entfernt - ### Sicherheit - Geheimnisse werden mit AES-256-GCM verschlüsselt, Schlüssel aus `PROXDEPLOY_SCHLUESSEL` (#001) - Passwörter mit argon2id; Sperre nach zehn Fehlversuchen in 15 Minuten; Content-Security-Policy mit Nonce (#001) diff --git a/DEVLOG.md b/DEVLOG.md index f7bf2ae..f1912cc 100644 --- a/DEVLOG.md +++ b/DEVLOG.md @@ -2,7 +2,7 @@ ## Zeitübersicht -**Gesamt:** 1 h 01 min (laufende Sitzung) +**Gesamt:** 1 h 15 min (laufende Sitzung) Zeiten stammen aus den Git-Commit-Zeitstempeln je Issue; Wartezeit auf Rückmeldungen ist enthalten. @@ -10,10 +10,11 @@ Zeiten stammen aus den Git-Commit-Zeitstempeln je Issue; Wartezeit auf Rückmeld |---|---| | #001 Projekt-Setup | 0 h 50 min | | #002 Server-Verwaltung | 0 h 11 min | +| #003 Verbindungstest | 0 h 25 min | | Meilenstein | Zeit | |---|---| -| v0.1.0 | – | +| v0.1.0 | 1 h 15 min | **abgeschlossen** --- @@ -28,6 +29,9 @@ Zeiten stammen aus den Git-Commit-Zeitstempeln je Issue; Wartezeit auf Rückmeld - Image-URLs, Prüfsummen-Dateien, LXC-Template-Namen, Docker- und Zabbix-Repos per Abruf geprüft - Git-Repository (`main`), CHANGELOG, DEVLOG, Architekturplan und 20 Issues angelegt - Plan freigegeben: Ubuntu 26.04 dazu, Templates mit UEFI, Template-VMID = nächste freie im Template-Bereich, Namensabbildung bestätigt +- #003 abgeschlossen: Verbindungstest mit Fähigkeitserkennung und SSH-Host-Key-Pinning; 127 Tests +- Feldtest auf dem Testhost `pve-demo` (PVE 9.2.2): Rolle/Token nach Doku per SSH angelegt, Fingerprint und Host-Key gegen den Node verglichen, Test mit und ohne SSH – alles wie erwartet +- Meilenstein v0.1.0 abgeschlossen, getaggt und nach Gitea gepusht - #002 abgeschlossen: Server-Verwaltung mit Fingerprint-Pinning, Proxmox-Client, Proxmox-Mock (HTTPS, selbst signiert); 99 Tests, 10 Playwright-Abläufe - Testhost 10.0.10.228 von Florian bereitgestellt (Installation läuft) - #001 abgeschlossen: Grundgerüst mit Anmeldung, Seitenleiste, beiden Themes; 60 Tests, 8 Playwright-Abläufe (Desktop + 390 px) @@ -43,4 +47,5 @@ Zeiten stammen aus den Git-Commit-Zeitstempeln je Issue; Wartezeit auf Rückmeld - **Sitzungsgeheimnis und Datenschlüssel getrennt** (`SITZUNG_GEHEIMNIS`, `PROXDEPLOY_SCHLUESSEL`): ein Tausch des Sitzungsgeheimnisses meldet nur alle ab, der Datenschlüssel darf sich nie ändern. - **Amber und Rot im hellen Theme abgedunkelt** (`#8A5A00`, `#B91C1C`): die Originaltöne erreichen auf `#F4F6F8` keine 4,5:1. - **TLS-Pinning über einen eigenen undici-Connector** statt `rejectUnauthorized: false` + Nachprüfen: die Verbindung wird getrennt, bevor das Token gesendet wird. Sitzungs-Cache aus, sonst fehlt bei Wiederaufnahme das Zertifikat. +- **Zugang zum Testhost über einen eigenen SSH-Schlüssel** (`~/.ssh/proxdeploy-testhost`), nicht über das root-Passwort: Claude Code verweigert das Anlegen von Zugängen mit Passwort, und ein Schlüssel nur für diesen Host ist ohnehin der sauberere Weg. - **Deutsche Bezeichner** wie in ProxLedger und Laufzettel; YAML-Schlüssel im Katalog bleiben englisch (Vorgabe). diff --git a/docs/issues/003-verbindungstest.md b/docs/issues/003-verbindungstest.md index 3dcc960..b2f9b4b 100644 --- a/docs/issues/003-verbindungstest.md +++ b/docs/issues/003-verbindungstest.md @@ -1,25 +1,32 @@ # #003 Verbindungstest und Fähigkeitserkennung -**Status:** offen +**Status:** erledigt **Meilenstein:** v0.1.0 **Labels:** feature, proxmox -**Geschätzt:** 6 h **Tatsächlich:** – +**Geschätzt:** 6 h **Tatsächlich:** 0 h 25 min ## Ziel Button „Verbindung testen“ zeigt Version, Cluster/Nodes, Storages, Bridges/VLANs und was per API bzw. nur per SSH geht. ## Aufgaben -- [ ] `/version`, `/cluster/status`, `/cluster/resources`, `/nodes/{n}/storage`, `/nodes/{n}/network`, SDN-VNets -- [ ] Rechte über `/access/permissions` gegen Rolle (8.x/9.x-Variante) abgleichen, fehlende einzeln nennen -- [ ] Fähigkeiten: download-url import (≥ 8.4), import-from per Volume, Snippets-Storage, SSH erreichbar -- [ ] Übersichtsseite mit Serverstatus und freien Ressourcen; Serverdetail mit Nodes/Storages/Bridges -- [ ] Proxmox-Mock für Tests (8.3, 8.4, 9.2 als Varianten) +- [x] `/version`, `/cluster/status`, `/nodes`, `/nodes/{n}/version|storage|network`, SDN-VNets +- [x] Rechte über `/access/permissions?path=…` gegen Rolle (8.x/9.x-Variante) abgleichen, fehlende einzeln nennen +- [x] Fähigkeiten: download-url import (≥ 8.4), import-from per Volume, Snippets-Storage, SSH erreichbar +- [x] SSH je Node mit Host-Key-Pinning (erst erkunden, dann bestätigen) +- [x] Übersichtsseite mit Serverstatus; Serverdetail mit Nodes/Storages/Bridges/Rechten/Fähigkeiten +- [x] Proxmox-Mock für Tests (8.3, 8.4, 9.2, Cluster) und SSH-Mock +- [x] `docs/proxmox-rechte.md` mit `pveum`-Befehlen; Test hält die Liste mit dem Code gleich ## Akzeptanzkriterien -- [ ] Gegen echten Proxmox geprüft (sobald Testumgebung da ist) -- [ ] Tests decken 8.3 (SSH nötig), 8.4 und 9.2 ab +- [x] Gegen echten Proxmox geprüft: Testhost `pve-demo` (10.0.10.228), PVE 9.2.2, am 2026-10-12 +- [x] Tests decken 8.3 (SSH nötig), 8.4 und 9.2 ab ## Abhängigkeiten #002 ## Notizen / Entscheidungen -– +- **Feldtest am 2026-10-12 auf PVE 9.2.2:** Rolle, Benutzer und Token genau nach `docs/proxmox-rechte.md` angelegt; alle Pflichtrechte erkannt, nur die vier optionalen fehlen. Fingerprint aus ProxDeploy = `pve-ssl.pem` laut `pvenode cert info`; SSH-Host-Key = `ssh-keygen -lf` auf dem Node. Mit SSH: Snippets, `pct exec` und erweiterte LXC-Features per SSH, Template-Bau per API. +- **`pvenode cert info` listet zuerst die Root-CA** – der Hinweis im Formular nennt deshalb ausdrücklich `pveproxy-ssl.pem` bzw. `pve-ssl.pem`. +- **Ein Host-Key lässt sich nur bestätigen, wenn der letzte Test ihn gesehen hat** – über die API kann niemand einen beliebigen Schlüssel unterschieben. +- **Fehlende Leserechte sind Warnungen, kein Abbruch:** der Bericht soll gerade bei unvollständiger Rolle helfen. +- **Statussymbole gezeichnet:** ◐ und ○ fehlen im Web-Subset von JetBrains Mono. +- Feld `Server.faehigkeiten` heißt jetzt `letzterTest` (Migration per RENAME, keine Daten verloren). diff --git a/docs/issues/README.md b/docs/issues/README.md index d75141f..75a0e51 100644 --- a/docs/issues/README.md +++ b/docs/issues/README.md @@ -6,7 +6,7 @@ Details und Architektur: [../architektur.md](../architektur.md). Zeiten werden a |---|---|---|---|---|---| | [#001](001-projekt-setup.md) | Projekt-Setup | erledigt | v0.1.0 | 4 h | 0 h 50 min | | [#002](002-verschluesselung-server.md) | Server-Verwaltung und Verschlüsselung | erledigt | v0.1.0 | 6 h | 0 h 11 min | -| [#003](003-verbindungstest.md) | Verbindungstest und Fähigkeitserkennung | offen | v0.1.0 | 6 h | – | +| [#003](003-verbindungstest.md) | Verbindungstest und Fähigkeitserkennung | erledigt | v0.1.0 | 6 h | 0 h 25 min | | [#004](004-katalog.md) | Katalog: Distributionen und Profile als Daten | offen | v0.2.0 | 5 h | – | | [#005](005-adapter-profile.md) | Adapter debian und Profil-Engine | offen | v0.2.0 | 6 h | – | | [#006](006-auftraege-sse.md) | Aufträge, Phasen, worker und Live-Fortschritt | offen | v0.2.0 | 8 h | – | diff --git a/package.json b/package.json index afa8e25..a7455fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "proxdeploy", - "version": "0.1.0-dev", + "version": "0.1.0", "private": true, "type": "module", "description": "VMs und LXC-Container auf Proxmox VE ausrollen, per Web oder CLI", diff --git a/src/app/(app)/server/[name]/verbindungsbericht.tsx b/src/app/(app)/server/[name]/verbindungsbericht.tsx index 50ebaac..5978e6b 100644 --- a/src/app/(app)/server/[name]/verbindungsbericht.tsx +++ b/src/app/(app)/server/[name]/verbindungsbericht.tsx @@ -245,7 +245,7 @@ export function Verbindungsbericht({

SSH

{knoten.ssh.zustand === "ok" ? ( - Verbunden als {knoten.ssh.host} · Host-Key bestätigt + Verbunden mit {knoten.ssh.host} · Host-Key bestätigt ) : knoten.ssh.zustand === "nicht_bestaetigt" ? (
diff --git a/src/app/(app)/server/server-formular.tsx b/src/app/(app)/server/server-formular.tsx index 2874bd0..e346929 100644 --- a/src/app/(app)/server/server-formular.tsx +++ b/src/app/(app)/server/server-formular.tsx @@ -219,8 +219,9 @@ export function ServerFormular({ server }: { server?: ServerSicht }) { SHA-256-Fingerprint {zertifikat.fingerabdruck}

- Zum Vergleichen auf dem Node: pvenode cert info oder in - der Proxmox-Oberfläche unter Node → System → Zertifikate. + Zum Vergleichen auf dem Node: pvenode cert info – + maßgeblich ist pveproxy-ssl.pem, falls vorhanden, sonst{" "} + pve-ssl.pem (nicht die Root-CA).