main
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f8c839a163 |
feat(openbao): pin 2.6.2, and correct the mlock and recovery-path claims
2.5.5 was two releases behind. Verified against the openbao/openbao source at
tag v2.6.2 that the bump is safe for an existing vault: raft's on-disk format
is unchanged (identical bbolt / hashicorp-raft / raft-boltdb pins,
byte-identical physical/raft/types.proto), snapshots restore in both
directions, and every stanza this config.hcl uses still parses -- the config
parser only moved import paths and the listener diff is additive.
Three corrections that came out of that check.
deploy.sh's printed crash-loop recovery command was already broken by 2.6.0.
That release adds `USER openbao` to the alpine image, so the container no
longer starts as root; the `docker run ... --entrypoint sh ... chown` it tells
the operator to run now executes as uid 100 and fails. Added `--user 0:0`, and
dropped the stale 2.5.5 literal from the same string. The detection logic
itself is unaffected -- `id -u openbao` still reads /etc/passwd and still
returns 100, verified by extracting the passwd layer from both published
images -- so
|
||
|
|
dc9761a668 |
feat(openbao): serve the web UI, so init/unseal can happen in a browser
config.hcl shipped `ui = false`, so there was no UI to reach even with working connectivity. That forces init and unseal through `docker compose exec`, which puts the unseal keys and root token into a server shell's history and scrollback -- the one place they should never be. Make it a substitution point driven by OPENBAO_UI, default on. This adds no exposure: the UI is served on the same listener, and anything that can reach :8200 can already do everything through the API. What it changes is where the unseal material is displayed -- the operator's browser instead of the host. Rendering config.hcl rather than copying it needed three things to be right: - Precedence. OPENBAO_UI passed to a run wins; otherwise the value .env already deploys applies; otherwise the default. Without that, `OPENBAO_UI=0 bash deploy.sh` against an existing node would report success and change nothing. Env-presence is captured before the ":=" default, so an explicit 0 is distinguishable from "not mentioned" and a re-run cannot silently re-enable the UI. A value passed this run is written back to .env. - Reload. A bind-mounted file's CONTENTS are not part of the compose config hash, so `up -d` leaves a changed config.hcl unloaded -- the same trap fixed in copyparty ( |
||
|
|
0812f345a8 |
fix(openbao): sanity-audit fixes — 4 blockers + hardening
A multi-agent sanity audit of the freshly-merged deployment found four end-to-end blockers (and several smaller issues); all fixed here. HIGH (were blocking): - deploy.sh never called install_docker(), so `docker compose pull` hit command-not-found on any host without Docker. Now called before the compose steps. - The container's server process runs as the image's own (often non-root) user but the mounted config/TLS were root-owned 0640/0600 and the raft volume root-owned -> vault crash-looped, never binding :8200. deploy.sh now detects the image UID after pull and aligns ownership of config.hcl, ./tls and the data volume (a no-op when the image runs as root); config.hcl is installed 0644 (holds no secrets). - Docs told operators to set the daemon key `openbao_ca_cert`, but the Kanrisha daemon's key is `ca_cert` (config.go, mapstructure:"ca_cert"). The wrong key is fatal on strict unmarshal / leaves TLS unverified. Renamed in all 5 places (config.hcl, gen-tls.sh, deploy.sh x2, README). - DR backup used `docker compose cp openbao:… -`, which emits a TAR stream, so the age-encrypted snapshot was tar-wrapped and would not restore. Switched to `docker compose exec -T openbao cat` for the raw bytes, wrote the snapshot to a scratch path (not the live raft dir), and documented the matching restore. MEDIUM: - Swap detection used `swapon --show` (absent on BusyBox) and `\s` (GNU-only) -> silently no-op on Alpine, leaving swap on. Now uses /proc/swaps and [[:space:]] so mlock hardening actually holds on musl. - A Docker-published port bypasses the host INPUT firewall, so the source rule was illusory. deploy.sh now narrows OPENBAO_BIND to OPENBAO_ADDR when it is an IP, the compose/README/.env comments state the reality, and a new Exposure section + an init-immediately warning were added. - Fixed broken ../kanrisha/ and deployments/kanrisha/ links (separate repo). LOW: - OPENBAO_TLS_SANS is now honored (folded into the SAN list from the env). - .gitignore excludes *.snap / *.snap.age. - Bootstrap note clarifies bootstrap.sh needs the `bao` CLI (run it from the Kanrisha host/workstation, not this Docker-only vault host). - README multi-OS count corrected (eight stacks) + automations.sh header lists openbao. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
2efc9dbffb |
feat(openbao): hardened same-LAN tape-encryption key store for Kanrisha
A dedicated OpenBao deployment, kept OFF the Kanrisha tape host so a compromise of the tape node can't reach the vault. - Native TLS on the listener (self-signed by default via gen-tls.sh, or a CA-signed cert from a Smallstep CA over ACME) — no Caddy/Let's Encrypt; reached over the LAN, not the public internet. - Integrated raft storage (clean snapshot-based DR). - mlock on (cap_add IPC_LOCK + memlock unlimited + host swapoff in deploy.sh). - Manual unseal by default; optional PKCS#11 HSM auto-unseal. - deploy.sh: Docker install (Alpine/Debian/Alma), self-signed cert, .env seed, swapoff, firewall 8200/tcp, compose up; then prints init/unseal + the KV-v2 + AppRole bootstrap for Kanrisha + the raft-snapshot DR flow. Self-contained (config payload embedded by build.sh). - Registered in automations.sh + the README deployment table. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |