8 Commits

Author SHA1 Message Date
d3c7d2445f Audit-Log einrichten: deklarativ, mit Rotation und haltbarem Pfad
Bis jetzt gab es kein Audit-Device - also keinerlei Aufzeichnung, wer welches
Geheimnis gelesen hat. Bei der Fehlersuche an der Identitaet "claude" am
2026-10-03 haette ein Blick ins Audit-Log die Ursache sofort gezeigt, weil die
beim Login vergebenen Policies darin stehen.

Deklarativ in openbao.hcl statt per `bao audit enable`: OpenBAO 2.x lehnt den
API-Weg ausdruecklich ab ("cannot enable audit device via API; use declarative,
config-based audit device management instead") - anders als Vault. Der Block
wird bei Neustart und bei SIGHUP uebernommen, der Reload lief daher ohne
Ausfall und ohne Entsiegeln.

log_raw bleibt auf dem Standard false: sensible Werte werden gehasht. Im Log
steht nachgeprueft ein HMAC statt des client_token, dazu Operation, Pfad,
display_name, policies und entity_id.

Dazu zwei Dinge, die das betriebssicher machen:
- /openbao/logs war ein ANONYMES Volume aus dem Image, nicht in der compose
  deklariert. Es haette ein `docker compose down -v` nicht ueberlebt. Jetzt ein
  Bind-Mount auf ./logs (uid 100 = openbao im Container). Der Pfad im Container
  bleibt gleich, der audit-Block muss dafuer nicht angepasst werden. Greift beim
  naechsten `docker compose up -d openbao`.
- logrotate: taeglich, 30 Generationen, zusaetzlich maxsize 100M. Das ist
  Pflicht, nicht Komfort - Audit-Devices sind blockierend, bei voller Platte
  weist OpenBAO Anfragen ab. SIGHUP im postrotate statt copytruncate, damit
  keine Zeilen verloren gehen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FXUoNtUh1qEdZXSzQeSos4
2026-10-03 10:54:58 +02:00
14275a5627 Auto-Unseal beim Boot und internes Zertifikat fuer gitea.famfi.home
Beim ersten Neustart seit 106 Tagen (2026-09-20) zeigte sich: der Unsealer kommt
versiegelt hoch, die Hauptinstanz startet daraufhin endlos neu und nichts kann mehr
Secrets lesen - Backups, Traefik-Zertifikate, Skripte. Bisher musste das jemand
von Hand entsiegeln.

- scripts/unseal-unsealer.sh + systemd/openbao-auto-unseal.service: entsiegelt die
  Sidecar nach docker.service, startet die Hauptinstanz nach und schreibt die Metrik
  openbao_unsealer_unsealed (cp1 alarmiert darauf). Idempotent.
  Zwei Fallstricke, die das Skript umgeht: `bao operator unseal -` (Schluessel ueber
  stdin) wird abgelehnt, und `bao status` liefert Exit 2 bei versiegelt - was trotzdem
  heisst, dass der Container antwortet.
  Der Schluessel liegt in /etc/openbao-unsealer.key (root, 0400), nicht im Repo.
- scripts/renew-gitea-cert.sh + systemd/gitea-cert-renew.*: gitea.famfi.home bekommt
  ein Zertifikat aus der eigenen PKI (90 Tage, Erneuerung ab 21 Tagen Restlaufzeit),
  Aufbau wie bei renew-openbao-cert.sh.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-26 09:25:44 +02:00
fef9e7f1ae Renew the transit seal token so auto-unseal survives a reboot
The main node's transit seal token (config/seal.hcl) lives on the unsealer
and was never renewed. It lapsed, and after the 2026-09-17 reboot main
crash-looped with 403 on transit/encrypt/autounseal even once the unsealer
was unsealed. renew-app-tokens.sh now parses it out of seal.hcl and renews
it via the same docker-exec path as the unsealer backup token.

Also widen .gitignore to config/seal.hcl* so timestamped backups of the
file (which contain the token) cannot be committed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-18 10:10:18 +02:00
63f864b68b gitignore: cover *-credentials.txt (operator login creds)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-01 10:04:13 +02:00
af31208251 Add prepare-host.sh: one-command SSH host onboarding
Generalize the .26 rollout into a reusable template:
- authorize the host principal on ssh/roles/host (allowlist, merged)
- sign the host certificate (ssh/sign/host)
- emit a self-contained installer (user-CA TrustedUserCAKeys + HostCertificate)
  to artifacts/, additive and lockout-safe
- add @cert-authority for the host to the client's known_hosts
Needs no SSH access to the target (ssh-keyscan). README updated.

Also gitignore .claude/ (local harness settings).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 10:53:32 +02:00
5a111b7a20 Add SSH CA integration: signed user + host certs, ssh-login helper
Turn the ssh/ engine into an SSH CA for cert-based access:

- ssh/ roles: "user" (8h user certs, principal-restricted) and "host"
  (long-lived host certs); mount max-lease-ttl raised for host certs
- scripts/ssh-login.sh: sign a fresh user cert via a scoped ssh/sign/user
  token (API, no bao binary) and connect — no authorized_keys on targets
- ca/openbao-ssh-ca.pub: the SSH CA public key (for TrustedUserCAKeys and
  client @cert-authority trust)
- README: usage, host onboarding, client trust
- gitignore generated per-host artifacts/

First host wired + verified end-to-end: 192.168.0.26 (pifour) — lutz cert
login and host-cert verification both confirmed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 14:55:01 +02:00
14f46e1082 Add unsealer, internal CA/TLS, auto-unseal, and automated cert+backup
Build out the home-lab OpenBAO deployment beyond the basic node:

- docker-compose: add openbao-unsealer sidecar; main node now transit
  auto-unseals against it (seal config kept in gitignored config/seal.hcl)
- policies/admin.hcl: non-root admin policy; per-engine rules for
  ssh/pki/pki_int/totp/transit
- Internal two-tier CA (pki/ root + pki_int/ intermediate) issues the
  openbao.famfi.home leaf Traefik serves; root CA published under ca/
- scripts/ + systemd/: daily cert renewal and Raft snapshot backups
  (both instances), with scoped tokens stored outside the repo
- README: full runbook (auto-unseal, PKI, renewal, backups, DR/restore)

Secrets (init/unsealer keys, tokens, seal stanza) stay gitignored.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 14:28:49 +02:00
95e1b676e2 Initial Commit 2026-06-28 13:41:17 +02:00