diff --git a/docs/AUDIT_2026-05-25_TODO.md b/docs/AUDIT_2026-05-25_TODO.md index 1657e3f..4e9b205 100644 --- a/docs/AUDIT_2026-05-25_TODO.md +++ b/docs/AUDIT_2026-05-25_TODO.md @@ -11,7 +11,7 @@ in `docs/RESTORE_MATRIX.md` ergaenzt. | Prioritaet | Punkt | Naechster Schritt | |---|---|---| -| P1 | DR-Workstation Bare-Metal-Kit: WSL2 + Borg-Client installieren | Hetzner-DR-SSH-Key ist 2026-06-03 erledigt und offline gesichert. Verbleibend: WSL2 auf dem Gaming-PC einrichten (`wsl --install -d Ubuntu`), `sudo apt install borgbackup` und ein erster Smoke `borg list ssh://u565255@u565255.your-storagebox.de/./hetzner_borg_appdata_critical` mit dem offline gesicherten Key + Passphrase. Bestandteile dokumentiert in `docs/EXTERNAL_DEPENDENCIES.md` Abschnitt "DR-Workstation Bare-Metal-Kit" | +| P1 | DR-Workstation Bare-Metal-Kit: Borg-Client + Hetzner-Smoke abschliessen | Readiness-Check 2026-06-06: WSL2 Ubuntu 24.04 ist vorhanden, SSH/Git sind vorhanden, Gitea-SSH-Smoke aus WSL ist erfolgreich, `~/dr-smoke.sh` wurde bereitgestellt. Verbleibend: Operator muss in Ubuntu per `sudo apt install borgbackup openssh-client` den Borg-Client installieren, den offline gesicherten Hetzner-DR-Key als Arbeitskopie nach `~/.ssh/dr-hetzner` legen und den Borg-Smoke fahren. Beleg: `docs/audit/dr-workstation-readiness-2026-06-06.md` | | P2 | Family-Onboarding praktisch starten | Fokus: Vaultwarden als Passwortbasis, Immich-Mobile-Backup auf jedem Handy, Mealie mit erstem Rezept/Einkaufsliste; Ablauf steht in `docs/FAMILY_ONBOARDING.md` | ## Restore-Audit Backlog (Stand 2026-06-03) diff --git a/docs/DR_WORKSTATION_SETUP.md b/docs/DR_WORKSTATION_SETUP.md index 2d9087f..ca5692b 100644 --- a/docs/DR_WORKSTATION_SETUP.md +++ b/docs/DR_WORKSTATION_SETUP.md @@ -115,6 +115,11 @@ Erwartet: HEAD und mindestens ein `refs/heads/master`-Eintrag. Damit der "ich pruefe das vierteljaehrlich"-Schritt zur Routine wird, ein kleines Skript ins WSL-Home: +Stand 2026-06-06: Das Skript liegt zusaetzlich versioniert unter +`ops/maintenance/dr-workstation-smoke.sh` und wurde auf `baerchen` bereits nach +`~/dr-smoke.sh` in die Ubuntu-WSL kopiert. Es kann nach Borg-Installation und +Ablage der DR-Keys direkt mit `bash ~/dr-smoke.sh` gestartet werden. + ```bash cat > ~/dr-smoke.sh <<'EOF' #!/bin/bash diff --git a/docs/EXTERNAL_DEPENDENCIES.md b/docs/EXTERNAL_DEPENDENCIES.md index 6907a20..708a927 100644 --- a/docs/EXTERNAL_DEPENDENCIES.md +++ b/docs/EXTERNAL_DEPENDENCIES.md @@ -107,3 +107,4 @@ Operative Regel: Die DR-Workstation wird nicht als Test-/Spiel-PC betrachtet. WS | 2026-06-03 | KOMODO_*-Notiz offline gesichert (Operator-Bestaetigung im DR-Tabletop-Followup). Quelle bleibt host-seitige `.env` (`/mnt/user/services/stacks/komodo/.env`) bzw. Drift-Recovery-Kopie vom 2026-05-04. Bare-Metal-Komodo-Bootstrap ist damit ohne Vaultwarden moeglich. | Restliche P1-Operator-Aufgaben: GitHub-Read-PAT, DR-Workstation-Setup, Nextcloud-Restore-Test | | 2026-06-03 | GitHub-Mirror Read-Only Deploy-Key `DR Read-Only 2026-06-03` (ed25519, Passphrase-frei) erzeugt, in GitHub Repo Settings ohne Write-Access hinterlegt, Smoke `git ls-remote` erfolgreich (`d947c7f` matched master HEAD), Private-Key offline neben KOMODO_*-Notiz abgelegt, Arbeitsplatz-Kopie geloescht. | Restliche P1-Operator-Aufgaben: DR-Workstation-Setup, Nextcloud-Restore-Test | | 2026-06-03 | Hetzner Storage Box DR-SSH-Key `dr-hetzner-2026-06-03` (ed25519, Passphrase-frei) erzeugt, via `install-ssh-key` auf Storage Box `u565255.your-storagebox.de:23` autorisiert, passwortloser Login erfolgreich (Borg-Repos sichtbar), Private-Key offline neben KOMODO_*-Notiz und GitHub-Deploy-Key abgelegt, Arbeitsplatz-Kopie geloescht. Bare-Metal-Borg-Restore von der DR-Workstation ist damit moeglich, sobald WSL2 + Borg-Client installiert sind. | Restliche P1-Operator-Aufgaben: WSL2 + Borg-Client auf DR-Workstation installieren, Nextcloud-Restore-Test | +| 2026-06-06 | DR-Workstation teilweise produktiv: WSL2 Ubuntu 24.04 vorhanden, SSH/Git in WSL vorhanden, interner Gitea-SSH-Smoke erfolgreich, `ops/maintenance/dr-workstation-smoke.sh` nach `~/dr-smoke.sh` kopiert. Readiness-Beleg: `docs/audit/dr-workstation-readiness-2026-06-06.md`. | Verbleibend: `borgbackup` per sudo in WSL installieren, offline gesicherten Hetzner-DR-Key nach `~/.ssh/dr-hetzner` legen, Borg-Smoke mit Passphrase fahren | diff --git a/docs/audit/dr-workstation-readiness-2026-06-06.md b/docs/audit/dr-workstation-readiness-2026-06-06.md new file mode 100644 index 0000000..d4694ba --- /dev/null +++ b/docs/audit/dr-workstation-readiness-2026-06-06.md @@ -0,0 +1,126 @@ +# DR-Workstation Readiness - 2026-06-06 + +Automatisch erzeugter lokaler Readiness-Check fuer den Operator-PC. Es wurden keine Secret-Werte, Passphrases oder Private-Key-Inhalte ausgegeben. + +## Zusammenfassung + +| Check | Ergebnis | +|---|---| +| WSL2 Ubuntu | vorhanden (`Ubuntu 24.04`, WSL Version 2) | +| SSH/Git in WSL | vorhanden | +| Gitea-SSH-Smoke mit vorhandenem WSL-Key | ok | +| Borg Client | fehlt | +| Hetzner Storage Box mit vorhandenem WSL-Key | nicht ok / separater DR-Key noetig | +| `~/dr-smoke.sh` | vorhanden | +| WSL sudo ohne Passwortprompt | nein, Operator muss Passwort eingeben | + +## Bewertung + +- Der lokale WSL2-/Ubuntu-Unterbau ist vorhanden. +- Der vorhandene WSL-Key kann das interne Gitea erreichen. +- Der vorhandene WSL-Key ist nicht der Hetzner-DR-Key fuer die Storage Box. +- `borgbackup` ist noch nicht installiert. +- Der vollstaendige Bare-Metal-DR-Smoke ist deshalb noch nicht abgeschlossen. + +## Naechste Operator-Schritte + +In Ubuntu ausfuehren: + +```bash +sudo apt update +sudo apt install -y borgbackup openssh-client +borg --version +``` + +Danach den offline gesicherten Hetzner-DR-Key als Arbeitskopie nach `~/.ssh/dr-hetzner` legen und `chmod 600 ~/.ssh/dr-hetzner` setzen. Anschliessend den Smoke aus `docs/DR_WORKSTATION_SETUP.md` Schritt 3-6 fahren. + +## Rohchecks + +### wsl_status + +- ExitCode: `0` + +```text +Standarddistribution: Ubuntu + +Standardversion: 2 + + +``` + +### wsl_list + +- ExitCode: `0` + +```text + NAME STATE VERSION + +* Ubuntu Stopped 2 + + docker-desktop Stopped 2 + + +``` + +### ubuntu_os + +- ExitCode: `0` + +```text +Distributor ID: Ubuntu +Description: Ubuntu 24.04.4 LTS +Release: 24.04 +Codename: noble +6.6.114.1-microsoft-standard-WSL2 +``` + +### tools + +- ExitCode: `0` + +```text +/usr/bin/ssh +OpenSSH_9.6p1 Ubuntu-3ubuntu13.15, OpenSSL 3.0.13 30 Jan 2024 +/usr/bin/git +git version 2.43.0 +``` + +### sudo + +- ExitCode: `0` + +```text +sudo-password-needed +``` + +### wsl_ssh_files + +- ExitCode: `0` + +```text +total 32 +drwx------ 2 michi michi 4096 Jun 4 12:20 . +drwxr-x--- 5 michi michi 4096 Jun 6 08:37 .. +-rw------- 1 michi michi 411 Apr 4 19:29 id_ed25519 +-rw-r--r-- 1 michi michi 97 Apr 4 19:29 id_ed25519.pub +-rw------- 1 michi michi 4719 Jun 4 12:20 known_hosts +-rw------- 1 michi michi 3013 Apr 20 20:13 known_hosts.old +-rw------- 1 michi michi 3858 Apr 24 08:27 known_hosts.pre-port222-20260604-122031.bak +-rwxr-xr-x 1 michi michi 1311 Jun 6 08:37 /home/michi/dr-smoke.sh +``` + +### gitea_ssh_smoke + +- ExitCode: `0` + +```text +0ef98a23e12886bc58a597d4bc4153108495f9e7 HEAD +``` + +### hetzner_ssh_smoke + +- ExitCode: `0` + +```text +u565255@u565255.your-storagebox.de: Permission denied (publickey,password). +``` diff --git a/ops/maintenance/check-dr-workstation-readiness.ps1 b/ops/maintenance/check-dr-workstation-readiness.ps1 new file mode 100644 index 0000000..9921034 --- /dev/null +++ b/ops/maintenance/check-dr-workstation-readiness.ps1 @@ -0,0 +1,97 @@ +param( + [string]$ReportPath = "G:\Gitea_Clone\homelab-infra\docs\audit\dr-workstation-readiness-2026-06-06.md" +) + +$ErrorActionPreference = "Stop" + +function Invoke-Capture { + param([string]$Command) + + $output = & cmd.exe /c $Command 2>&1 + [pscustomobject]@{ + Command = $Command + ExitCode = $LASTEXITCODE + Output = ($output | ForEach-Object { ([string]$_).Replace("`0", "") }) + } +} + +function Invoke-WslCapture { + param([string]$Bash) + Invoke-Capture -Command ('wsl -d Ubuntu -- bash -lc ' + '"' + ($Bash.Replace('"', '\"')) + '"') +} + +$checks = [ordered]@{} +$checks["wsl_status"] = Invoke-Capture -Command "wsl --status" +$checks["wsl_list"] = Invoke-Capture -Command "wsl --list --verbose" +$checks["ubuntu_os"] = Invoke-WslCapture -Bash "lsb_release -a 2>/dev/null || cat /etc/os-release; uname -r" +$checks["tools"] = Invoke-WslCapture -Bash "command -v borg || true; borg --version 2>/dev/null || true; command -v ssh || true; ssh -V 2>&1 || true; command -v git || true; git --version 2>/dev/null || true" +$checks["sudo"] = Invoke-WslCapture -Bash "sudo -n true >/dev/null 2>&1 && echo sudo-noprompt-ok || echo sudo-password-needed" +$checks["wsl_ssh_files"] = Invoke-WslCapture -Bash "ls -la ~/.ssh 2>/dev/null || true; test -f ~/dr-smoke.sh && ls -la ~/dr-smoke.sh || true" +$checks["gitea_ssh_smoke"] = Invoke-WslCapture -Bash "GIT_SSH_COMMAND='ssh -i ~/.ssh/id_ed25519 -o BatchMode=yes -o IdentitiesOnly=yes -o ConnectTimeout=8' git ls-remote ssh://git@192.168.178.58:222/Micha/homelab-infra.git HEAD 2>&1 | sed -n '1,5p'" +$checks["hetzner_ssh_smoke"] = Invoke-WslCapture -Bash "ssh -i ~/.ssh/id_ed25519 -o BatchMode=yes -o IdentitiesOnly=yes -o ConnectTimeout=8 -p 23 u565255@u565255.your-storagebox.de 'ls' 2>&1 | sed -n '1,10p'" + +$borgInstalled = ($checks["tools"].Output -match "borg \d") +$giteaOk = ($checks["gitea_ssh_smoke"].Output -match "HEAD") +$hetznerOk = -not ($checks["hetzner_ssh_smoke"].Output -match "Permission denied|Connection refused|Could not") +$sudoNeedsPassword = ($checks["sudo"].Output -match "sudo-password-needed") +$drSmokeExists = ($checks["wsl_ssh_files"].Output -match "dr-smoke.sh") + +$lines = @() +$lines += "# DR-Workstation Readiness - 2026-06-06" +$lines += "" +$lines += "Automatisch erzeugter lokaler Readiness-Check fuer den Operator-PC. Es wurden keine Secret-Werte, Passphrases oder Private-Key-Inhalte ausgegeben." +$lines += "" +$lines += "## Zusammenfassung" +$lines += "" +$lines += "| Check | Ergebnis |" +$lines += "|---|---|" +$lines += '| WSL2 Ubuntu | vorhanden (`Ubuntu 24.04`, WSL Version 2) |' +$lines += "| SSH/Git in WSL | vorhanden |" +$lines += "| Gitea-SSH-Smoke mit vorhandenem WSL-Key | " + ($(if ($giteaOk) { "ok" } else { "nicht ok" })) + " |" +$lines += "| Borg Client | " + ($(if ($borgInstalled) { "installiert" } else { "fehlt" })) + " |" +$lines += "| Hetzner Storage Box mit vorhandenem WSL-Key | " + ($(if ($hetznerOk) { "ok" } else { "nicht ok / separater DR-Key noetig" })) + " |" +$lines += '| `~/dr-smoke.sh` | ' + ($(if ($drSmokeExists) { "vorhanden" } else { "fehlt" })) + ' |' +$lines += "| WSL sudo ohne Passwortprompt | " + ($(if ($sudoNeedsPassword) { "nein, Operator muss Passwort eingeben" } else { "ja" })) + " |" +$lines += "" +$lines += "## Bewertung" +$lines += "" +$lines += "- Der lokale WSL2-/Ubuntu-Unterbau ist vorhanden." +$lines += "- Der vorhandene WSL-Key kann das interne Gitea erreichen." +$lines += "- Der vorhandene WSL-Key ist nicht der Hetzner-DR-Key fuer die Storage Box." +$lines += '- `borgbackup` ist noch nicht installiert.' +$lines += "- Der vollstaendige Bare-Metal-DR-Smoke ist deshalb noch nicht abgeschlossen." +$lines += "" +$lines += "## Naechste Operator-Schritte" +$lines += "" +$lines += "In Ubuntu ausfuehren:" +$lines += "" +$lines += '```bash' +$lines += "sudo apt update" +$lines += "sudo apt install -y borgbackup openssh-client" +$lines += "borg --version" +$lines += '```' +$lines += "" +$lines += 'Danach den offline gesicherten Hetzner-DR-Key als Arbeitskopie nach `~/.ssh/dr-hetzner` legen und `chmod 600 ~/.ssh/dr-hetzner` setzen. Anschliessend den Smoke aus `docs/DR_WORKSTATION_SETUP.md` Schritt 3-6 fahren.' +$lines += "" +$lines += "## Rohchecks" +$lines += "" +foreach ($name in $checks.Keys) { + $check = $checks[$name] + $lines += "### $name" + $lines += "" + $lines += '- ExitCode: `' + $check.ExitCode + '`' + $lines += "" + $lines += '```text' + $lines += ($check.Output | ForEach-Object { + $_ -replace ([regex]::Escape($env:USERPROFILE)), '%USERPROFILE%' + }) + $lines += '```' + $lines += "" +} + +New-Item -ItemType Directory -Force -Path (Split-Path -Parent $ReportPath) | Out-Null +while ($lines.Count -gt 0 -and $lines[-1] -eq "") { + $lines = $lines[0..($lines.Count - 2)] +} +$lines -join "`r`n" | Set-Content -LiteralPath $ReportPath -Encoding UTF8 +Write-Host "Report written: $ReportPath" diff --git a/ops/maintenance/dr-workstation-smoke.sh b/ops/maintenance/dr-workstation-smoke.sh new file mode 100755 index 0000000..160dd62 --- /dev/null +++ b/ops/maintenance/dr-workstation-smoke.sh @@ -0,0 +1,41 @@ +#!/bin/bash +# DR-Workstation Quartals-Smoke +# +# Prueft Git-Read, Hetzner-SSH und Borg-Repo-Erreichbarkeit vom Operator-PC. +# Speichert keine Passphrase. Borg fragt interaktiv nach der Repo-Passphrase. +set -euo pipefail + +GITHUB_KEY="${GITHUB_KEY:-$HOME/.ssh/dr-readonly}" +HETZNER_KEY="${HETZNER_KEY:-$HOME/.ssh/dr-hetzner}" +GITHUB_REPO="${GITHUB_REPO:-git@github.com:michaelkaleschke-spec/homelab-infra.git}" +BORG_REPO="${BORG_REPO:-ssh://u565255@u565255.your-storagebox.de/./hetzner_borg_appdata_critical}" + +echo "=== Tooling ===" +command -v ssh +command -v git +command -v borg +borg --version +echo + +echo "=== Key files ===" +test -r "$GITHUB_KEY" || { echo "Missing GitHub key: $GITHUB_KEY" >&2; exit 1; } +test -r "$HETZNER_KEY" || { echo "Missing Hetzner key: $HETZNER_KEY" >&2; exit 1; } +ls -l "$GITHUB_KEY" "$HETZNER_KEY" +echo + +echo "=== GitHub Deploy-Key ===" +GIT_SSH_COMMAND="ssh -i $GITHUB_KEY -o IdentitiesOnly=yes -o BatchMode=yes" \ + git ls-remote "$GITHUB_REPO" HEAD +echo + +echo "=== Hetzner SSH-Login ===" +ssh -i "$HETZNER_KEY" -o IdentitiesOnly=yes -o BatchMode=yes -p 23 \ + u565255@u565255.your-storagebox.de "ls" | head -5 +echo + +echo "=== Borg-Repo ===" +export BORG_RSH="ssh -i $HETZNER_KEY -o IdentitiesOnly=yes -p 23" +borg info "$BORG_REPO" | head -12 +echo + +echo "DR-Smoke OK ($(date '+%F %T'))"