From 0812f345a853a1bbb8ae2ef616bcb9bec87b5227 Mon Sep 17 00:00:00 2001 From: William Gill Date: Wed, 8 Jul 2026 19:11:37 -0500 Subject: [PATCH] =?UTF-8?q?fix(openbao):=20sanity-audit=20fixes=20?= =?UTF-8?q?=E2=80=94=204=20blockers=20+=20hardening?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- README.md | 6 +- automations.sh | 4 +- deployments/openbao/.env.example | 19 ++- deployments/openbao/.gitignore | 5 +- deployments/openbao/README.md | 76 ++++++--- deployments/openbao/config.hcl | 2 +- deployments/openbao/deploy.sh | 204 ++++++++++++++++--------- deployments/openbao/docker-compose.yml | 10 +- deployments/openbao/gen-tls.sh | 2 +- 9 files changed, 216 insertions(+), 112 deletions(-) diff --git a/README.md b/README.md index d624df5..f338a18 100644 --- a/README.md +++ b/README.md @@ -110,7 +110,7 @@ deployments// # one folder per stack | [`squid`](deployments/squid/) | SSL-bump caching forward proxy — static-content cache + TLS interception via a local CA. **The exception: a forward proxy, not a Caddy/LE site.** | — | | [`copyparty`](deployments/copyparty/) | Portable file server — web UI/WebDAV behind Caddy, plus direct **SFTP** + **FTPS**. Ships a security-notices-aware updater. | — | | [`simplex`](deployments/simplex/) | SimpleX SMP + XFTP relay with Tor hidden services + encrypted backups. | globals/age-pubkey.txt | -| [`openbao`](deployments/openbao/) | Hardened tape-encryption key store for [Kanrisha](deployments/kanrisha/). **Exception: native TLS on the LAN, no Caddy/LE.** raft storage, mlock, self-signed or Smallstep-ACME cert, manual/HSM unseal. | globals/age-pubkey.txt (backups) | +| [`openbao`](deployments/openbao/) | Hardened tape-encryption key store for **Kanrisha** (the LTO tape-archive system — separate repo/host). **Exception: native TLS on the LAN, no Caddy/LE.** raft storage, mlock, self-signed or Smallstep-ACME cert, manual/HSM unseal. | globals/age-pubkey.txt (backups) | ## Conventions @@ -145,8 +145,8 @@ instance user-data, and the host configures itself on first boot. ## Multi-OS notes The host-provisioning scripts (`setup-host`, `harden-ssh`, `harden-jumphost`, -`sshuser`) and the six Docker stacks (pocket-id, beszel, headscale, webfinger, -squid, copyparty) run on Alpine, Debian, and Alma. Distro differences live in +`sshuser`) and the eight Docker stacks (pocket-id, beszel, headscale, webfinger, +squid, copyparty, simplex, openbao) run on Alpine, Debian, and Alma. Distro differences live in [`scripts/oslib.sh`](scripts/oslib.sh) — package manager (`apk`/`apt`/`dnf`), init system (OpenRC/systemd), sshd service name, the per-distro `sftp-server` path, hostname, boot hooks, and the sshguard log source/backend. diff --git a/automations.sh b/automations.sh index d0e3244..c939c5f 100644 --- a/automations.sh +++ b/automations.sh @@ -14,8 +14,8 @@ # It opens a Gum wizard (auto-installed) that lets you: # • Mode: deploy on THIS host, or build deploy.sh artifacts locally. # • Pick any deployment (pocket-id, beszel, headscale, webfinger, squid, -# copyparty, simplex) or any generic script (harden-ssh, harden-jumphost, -# sshuser, auto-update). +# copyparty, simplex, openbao) or any generic script (setup-host, harden-ssh, +# harden-jumphost, sshuser, auto-update). # Shared defaults come from globals/ (see globals/README.md). # # Non-interactive: set SKIP_PROMPTS=1 plus the needed vars and pipe the menu diff --git a/deployments/openbao/.env.example b/deployments/openbao/.env.example index 72e3c92..75ebe12 100644 --- a/deployments/openbao/.env.example +++ b/deployments/openbao/.env.example @@ -8,16 +8,21 @@ # [encryption.openbao].address at (https://${OPENBAO_ADDR}:8200). OPENBAO_ADDR=10.0.0.10 -# Interface the published API port binds to on the host. Default is all -# interfaces; set the LAN IP to avoid listening anywhere else. +# Interface the published API port binds to on the host. Leave blank/all and +# deploy.sh narrows it to OPENBAO_ADDR when that is an IP; set it explicitly to +# pin a specific LAN IP. (A published port bypasses the host INPUT firewall — see +# the README — so this bind is the main interface restriction.) OPENBAO_BIND=0.0.0.0 # ─── TLS ──────────────────────────────────────────────────────────────────── -# Comma-separated SANs for the self-signed cert deploy.sh generates. Include -# EVERY name/IP the tape host might use (deploy.sh appends OPENBAO_ADDR + the -# loopback for you). To use a CA-signed cert instead (e.g. Smallstep over ACME), -# drop tls.crt + tls.key into ./tls and these are ignored — see the README. -OPENBAO_TLS_SANS=DNS:localhost,IP:127.0.0.1 +# EXTRA SANs for the self-signed cert, beyond OPENBAO_ADDR + loopback (which +# deploy.sh always includes). This is read from the ENVIRONMENT at deploy time, +# so to add names export it before running deploy.sh, e.g. +# OPENBAO_TLS_SANS=DNS:vault.lan,IP:10.0.0.11 bash deploy.sh +# (deploy.sh records the final SAN list back into this .env for reference.) To +# use a CA-signed cert instead (e.g. Smallstep over ACME), drop tls.crt + tls.key +# into ./tls and this is ignored — see the README. +OPENBAO_TLS_SANS= OPENBAO_TLS_DAYS=825 # ─── Image tag ────────────────────────────────────────────────────────────── diff --git a/deployments/openbao/.gitignore b/deployments/openbao/.gitignore index 74dc083..ec5dcfe 100644 --- a/deployments/openbao/.gitignore +++ b/deployments/openbao/.gitignore @@ -1,3 +1,6 @@ -# Never commit generated TLS material (the listener key) or a populated .env. +# Never commit generated TLS material (the listener key), a populated .env, or +# raft snapshot backups (they contain vault data). /tls/ .env +*.snap +*.snap.age diff --git a/deployments/openbao/README.md b/deployments/openbao/README.md index 0b2d572..3c02f08 100644 --- a/deployments/openbao/README.md +++ b/deployments/openbao/README.md @@ -1,9 +1,10 @@ # openbao Hardened [OpenBao](https://openbao.org) — the tape-encryption key store for -[Kanrisha](../kanrisha/). Deliberately **separate from the tape host**: a -compromise of the tape node must not reach the vault, and OpenBao's -mlock/TLS/unseal lifecycle is cleaner on its own box. +**Kanrisha** (the LTO tape-archive system; separate repo, separate host). +Deliberately **separate from the tape host**: a compromise of the tape node must +not reach the vault, and OpenBao's mlock/TLS/unseal lifecycle is cleaner on its +own box. Unlike the other stacks here there is **no Caddy / Let's Encrypt** — a secrets store terminates TLS itself and is reached over the **LAN**, not the public @@ -24,8 +25,8 @@ internet. | Variable | Notes | |----------|-------| | `OPENBAO_ADDR` | IP/DNS the Kanrisha tape host uses to reach this vault (goes in the cert SAN; you point the daemon at `https://$OPENBAO_ADDR:8200`). | -| `OPENBAO_BIND` | Host interface the API binds to. Default all; set the LAN IP to narrow it. | -| `OPENBAO_TLS_SANS` | Extra SANs for the self-signed cert (deploy.sh adds `OPENBAO_ADDR` + loopback). | +| `OPENBAO_BIND` | Host interface the API publishes on. Left at the default, deploy.sh narrows it to `OPENBAO_ADDR` when that is an IP (a published port bypasses the INPUT firewall, so this bind is the real restriction — see [Exposure](#exposure)). | +| `OPENBAO_TLS_SANS` | **Extra** SANs beyond `OPENBAO_ADDR` + loopback (which deploy.sh always adds). Read from the environment at deploy time — `export` it before running deploy.sh. | | `OPENBAO_TAG` | OpenBao image tag (pin it). | | `OPENBAO_HSM_PIN` | Only for PKCS#11 auto-unseal. Leave blank for manual unseal. | @@ -40,8 +41,11 @@ OPENBAO_ADDR=10.0.0.10 SKIP_PROMPTS=1 bash deployments/openbao/deploy.sh ``` `deploy.sh` installs Docker, generates a self-signed TLS cert (if none present), -seeds `.env`, disables swap (for mlock), firewalls `8200/tcp`, and brings the -stack up. OpenBao starts **sealed** — initialise + unseal once: +seeds `.env`, disables swap (for mlock), narrows the API bind to the LAN IP, +opens `8200/tcp`, aligns file/volume ownership to the container's UID, and brings +the stack up. OpenBao starts **sealed** — initialise + unseal once (do this +immediately; an uninitialised vault reachable on the LAN can be init'd by anyone +who connects): ```bash docker compose exec -e BAO_ADDR=https://127.0.0.1:8200 openbao \ @@ -57,7 +61,7 @@ your backup recipient (`globals/age-pubkey.txt`), never on this host. - **Self-signed (default):** `deploy.sh` runs [`gen-tls.sh`](gen-tls.sh) to create `./tls/tls.{crt,key}` with `OPENBAO_ADDR` in the SAN. Hand `tls.crt` to - the Kanrisha daemon as `[encryption.openbao].openbao_ca_cert`. + the Kanrisha daemon as `[encryption.openbao].ca_cert`. - **Smallstep CA over ACME (option):** issue a cert from your `step-ca` and drop it in `./tls` instead — `gen-tls.sh` then no-ops. e.g. with the `step` client: @@ -67,7 +71,7 @@ your backup recipient (`globals/age-pubkey.txt`), never on this host. # renew on a timer: step ca renew --daemon ./tls/tls.crt ./tls/tls.key ``` - Give the Kanrisha daemon your Smallstep **root** as `openbao_ca_cert` (then it + Give the Kanrisha daemon your Smallstep **root** as `ca_cert` (then it trusts the vault without `-tls-skip-verify`). ## Auto-unseal (optional) @@ -79,10 +83,13 @@ device into the `openbao` service, and set `OPENBAO_HSM_PIN` in `.env`. ## Bootstrap for Kanrisha Once unsealed, enable KV v2 + AppRole and seed the domain key with the Kanrisha -bootstrap script (from the Kanrisha repo, `deploy/openbao/bootstrap.sh`): +bootstrap script (from the Kanrisha repo, `deploy/openbao/bootstrap.sh`). It calls +the `bao` CLI directly, so run it **from a host that has `bao`** (the Kanrisha +host or your workstation) pointed at this vault — this vault host only ships +Docker. Copy `tls.crt` to that host first and pass it as `BAO_CACERT`: ```bash -BAO_ADDR=https://$OPENBAO_ADDR:8200 BAO_CACERT=./tls/tls.crt \ +BAO_ADDR=https://$OPENBAO_ADDR:8200 BAO_CACERT=/path/to/openbao-ca.crt \ BAO_TOKEN= bash bootstrap.sh ``` @@ -91,19 +98,48 @@ It enables the `kanrisha-tape` KV-v2 mount (with **effectively-unlimited** policy, seeds the domain key, and prints the `[encryption.openbao]` block for the Kanrisha config. Point the daemon at `address = "https://$OPENBAO_ADDR:8200"`. +## Exposure + +This is a secrets store on the LAN, not a public service. Two things to know: + +- **A Docker-published port is DNAT'd and bypasses the host `INPUT` firewall.** A + source-restricting rule on `INPUT` does **not** gate `:8200`. The real interface + restriction is the publish bind: `deploy.sh` defaults `OPENBAO_BIND` to + `OPENBAO_ADDR` when that is an IP, so the API listens only on that LAN IP. To + restrict by *source host*, use a `FORWARD`/`DOCKER-USER` rule or network + segmentation, not `INPUT`. +- **mTLS (optional):** to require the tape host to present a client cert, enable + the `tls_require_and_verify_client_cert` stanza in [`config.hcl`](config.hcl) + and issue the tape host a client cert from the same CA. + +And **initialise the vault immediately** after `deploy.sh` — an uninitialised +vault reachable on the LAN can be `bao operator init`'d by anyone who connects, +handing them the root token and unseal keys. + ## Backup / DR The vault is the sole recovery path for encrypted tapes — back it up: ```bash -# Consistent raft snapshot (safe while running): -docker compose exec -e BAO_ADDR=https://127.0.0.1:8200 openbao \ - bao operator raft snapshot save -tls-skip-verify /openbao/data/snapshot.snap -# then copy it off-box, age-encrypted: -docker compose cp openbao:/openbao/data/snapshot.snap - | \ - age -r "$(cat ../../globals/age-pubkey.txt)" > openbao-$(date +%F).snap.age +# Consistent raft snapshot (safe while running); write it to a scratch path, NOT +# into the live raft dir: +docker compose exec openbao \ + bao operator raft snapshot save -address=https://127.0.0.1:8200 -tls-skip-verify /tmp/openbao.snap +# then stream the RAW file off-box, age-encrypted. Use `exec -T ... cat`, not +# `compose cp openbao:… -` (which emits a TAR wrapper that won't restore): +docker compose exec -T openbao cat /tmp/openbao.snap | \ + age -r "$(cat /path/to/globals/age-pubkey.txt)" > "openbao-$(date +%F).snap.age" ``` -Restore: `bao operator raft snapshot restore`. Snapshots do **not** contain the -unseal keys — you still need those (and the root token) to unseal a restored -vault, which is why they are stored separately. +Restore (into a fresh, unsealed vault): decrypt, copy the raw `.snap` in, and +apply it: + +```bash +age -d -i ~/.age/key.txt openbao-DATE.snap.age > openbao.snap +docker compose cp openbao.snap openbao:/tmp/openbao.snap +docker compose exec openbao \ + bao operator raft snapshot restore -address=https://127.0.0.1:8200 -tls-skip-verify /tmp/openbao.snap +``` + +Snapshots do **not** contain the unseal keys or root token — you still need +those to unseal a restored vault, which is why they are stored separately. diff --git a/deployments/openbao/config.hcl b/deployments/openbao/config.hcl index d728637..178ff1a 100644 --- a/deployments/openbao/config.hcl +++ b/deployments/openbao/config.hcl @@ -14,7 +14,7 @@ storage "raft" { # TLS-terminating listener. tls.crt/tls.key are self-signed by deploy.sh on first # run, or a CA-signed pair you drop in ./tls (e.g. issued by your Smallstep CA # over ACME — see the README). The Kanrisha daemon trusts this via -# [encryption.openbao].openbao_ca_cert. +# [encryption.openbao].ca_cert. listener "tcp" { address = "0.0.0.0:8200" tls_cert_file = "/openbao/tls/tls.crt" diff --git a/deployments/openbao/deploy.sh b/deployments/openbao/deploy.sh index 9bf9589..b657b88 100644 --- a/deployments/openbao/deploy.sh +++ b/deployments/openbao/deploy.sh @@ -102,13 +102,18 @@ open_bao_port() { disable_swap() { [[ "$DISABLE_SWAP" == "1" ]] || { warn "DISABLE_SWAP=0 -- mlock will be best-effort."; return; } - if swapon --show 2>/dev/null | grep -q .; then + # Detect active swap via /proc/swaps (a header line + one line per device) so + # this works on musl/BusyBox too, where `swapon --show` does not exist. + if [[ -r /proc/swaps ]] && [[ "$(wc -l < /proc/swaps)" -gt 1 ]]; then log "Disabling swap (mlock keeps key material off disk)..." swapoff -a || warn "swapoff failed -- disable swap manually." + else + log "No active swap." fi # Persist: comment any swap lines in fstab so it stays off across reboots. - if [[ -f /etc/fstab ]] && grep -qE '^[^#].*\sswap\s' /etc/fstab; then - sed -i.bak -E 's|^([^#].*\sswap\s.*)$|# \1 # disabled for OpenBao mlock|' /etc/fstab + # [[:space:]] (not \s) so the match works under musl/BusyBox grep/sed. + if [[ -f /etc/fstab ]] && grep -qE '^[^#].*[[:space:]]swap[[:space:]]' /etc/fstab; then + sed -i.bak -E 's|^([^#].*[[:space:]]swap[[:space:]].*)$|# \1 # disabled for OpenBao mlock|' /etc/fstab log "Commented swap entries in /etc/fstab (backup: /etc/fstab.bak)." fi } @@ -147,13 +152,27 @@ prompt() { prompt OPENBAO_ADDR "LAN address the Kanrisha tape host reaches this vault at (IP or DNS)" [[ -n "$OPENBAO_ADDR" ]] || die "OPENBAO_ADDR is required." -# Build the cert SAN list: loopback + whatever OPENBAO_ADDR is (IP vs DNS). +# Build the cert SAN list: loopback + whatever OPENBAO_ADDR is (IP vs DNS) + +# any extra SANs the operator exported in OPENBAO_TLS_SANS. +ADDR_IS_IP=0 if [[ "$OPENBAO_ADDR" =~ ^[0-9.]+$ || "$OPENBAO_ADDR" == *:* ]]; then ADDR_SAN="IP:${OPENBAO_ADDR}" + ADDR_IS_IP=1 else ADDR_SAN="DNS:${OPENBAO_ADDR}" fi SANS="DNS:localhost,IP:127.0.0.1,${ADDR_SAN}" +[[ -n "${OPENBAO_TLS_SANS:-}" ]] && SANS="${SANS},${OPENBAO_TLS_SANS}" + +# A Docker-published port bypasses the host INPUT firewall, so the interface bind +# is the real restriction. If the operator left OPENBAO_BIND at the all-interfaces +# default and OPENBAO_ADDR is an IP, narrow the publish to just that LAN IP. +if [[ "$OPENBAO_BIND" == "0.0.0.0" && "$ADDR_IS_IP" == "1" ]]; then + OPENBAO_BIND="$OPENBAO_ADDR" + log "Binding the API to ${OPENBAO_BIND} only (set OPENBAO_BIND to override)." +elif [[ "$OPENBAO_BIND" == "0.0.0.0" ]]; then + warn "OPENBAO_BIND=0.0.0.0 and OPENBAO_ADDR is a DNS name -- API publishes on ALL interfaces. Set OPENBAO_BIND to a LAN IP to narrow it." +fi # ---------------------------------------------------------------------------- # Lay down the stack @@ -161,7 +180,9 @@ SANS="DNS:localhost,IP:127.0.0.1,${ADDR_SAN}" log "Setting up $STACK_DIR..." install -d -m 0750 "$STACK_DIR" install -m 0640 "$SCRIPT_DIR/docker-compose.yml" "$STACK_DIR/docker-compose.yml" -install -m 0640 "$SCRIPT_DIR/config.hcl" "$STACK_DIR/config.hcl" +# config.hcl holds no secrets and is read by the in-container server process +# (which may be a non-root user) over a read-only mount -- keep it world-readable. +install -m 0644 "$SCRIPT_DIR/config.hcl" "$STACK_DIR/config.hcl" install -m 0750 "$SCRIPT_DIR/gen-tls.sh" "$STACK_DIR/gen-tls.sh" ENV_FILE="$STACK_DIR/.env" @@ -196,9 +217,29 @@ if [[ "$FORCE" != "1" ]]; then [[ "${ans,,}" == "y" || "${ans,,}" == "yes" ]] || { warn "Aborted."; exit 0; } fi +install_docker + cd "$STACK_DIR" log "Pulling image..." docker compose pull + +# The OpenBao server process runs as the image's own user -- root in some image +# variants, a non-root service user in others -- and reads its config + TLS over +# read-only bind mounts and writes the raft data volume. So those must be owned by +# that UID. Detect it from the pulled image and align ownership; all of this is a +# harmless no-op when the image runs as root. +BAO_UID=$(docker compose run --rm --no-deps --entrypoint id openbao -u 2>/dev/null | tr -dc '0-9' || true) +BAO_UID=${BAO_UID:-0} +log "OpenBao container runs as UID ${BAO_UID}; aligning file/volume ownership." +chown -R "${BAO_UID}:${BAO_UID}" "$STACK_DIR/config.hcl" "$STACK_DIR/tls" +# tls.key stays private to that UID; config.hcl + tls.crt are non-secret. +chmod 0600 "$STACK_DIR/tls/tls.key" 2>/dev/null || true +# Raft data volume is created root-owned on first mount; make it writable by the +# server UID (a one-shot root container chowns the mounted volume in-place). +docker compose run --rm --no-deps --user 0:0 --entrypoint chown openbao \ + -R "${BAO_UID}:${BAO_UID}" /openbao/data 2>/dev/null || \ + warn "Could not pre-chown the raft data volume; if OpenBao fails to write storage, chown the openbao-data volume to UID ${BAO_UID}." + log "Starting OpenBao..." docker compose up -d --remove-orphans @@ -215,7 +256,11 @@ DEPLOYED (OpenBao starts SEALED -- finish setup below) Address: https://${OPENBAO_ADDR}:8200 Stack dir: ${STACK_DIR} TLS: ${STACK_DIR}/tls/tls.crt (give this to the Kanrisha daemon as - [encryption.openbao].openbao_ca_cert) + [encryption.openbao].ca_cert) + +>> Initialise NOW: an uninitialised vault reachable on the LAN can be init'd by + anyone who connects, capturing the root token + unseal keys. Do step 1 before + walking away. 1. Initialise + unseal (ONCE). Store the unseal keys + root token OUT OF BAND: docker compose exec -e BAO_ADDR=https://127.0.0.1:8200 openbao \\ @@ -223,18 +268,22 @@ TLS: ${STACK_DIR}/tls/tls.crt (give this to the Kanrisha daemon as docker compose exec -e BAO_ADDR=https://127.0.0.1:8200 openbao \\ bao operator unseal -tls-skip-verify # x3, three different keys -2. Bootstrap for Kanrisha (from the Kanrisha repo's deploy/openbao/bootstrap.sh): - BAO_ADDR=https://${OPENBAO_ADDR}:8200 BAO_CACERT=${STACK_DIR}/tls/tls.crt \\ +2. Bootstrap for Kanrisha. Run the Kanrisha repo's deploy/openbao/bootstrap.sh + from a host that HAS the 'bao' CLI (the Kanrisha host or your workstation -- + this vault host only ships Docker), pointed at this vault. Copy tls.crt there + first as the BAO_CACERT: + BAO_ADDR=https://${OPENBAO_ADDR}:8200 BAO_CACERT=/path/to/openbao-ca.crt \\ BAO_TOKEN= bash bootstrap.sh Then point the Kanrisha daemon at: [encryption.openbao] address = "https://${OPENBAO_ADDR}:8200" - openbao_ca_cert = "/etc/kanrisha/openbao-ca.crt" # = tls.crt above + ca_cert = "/etc/kanrisha/openbao-ca.crt" # = tls.crt above 3. Back it up (this vault is the sole recovery path for encrypted tapes): - docker compose exec -e BAO_ADDR=https://127.0.0.1:8200 openbao \\ - bao operator raft snapshot save -tls-skip-verify /openbao/data/snap.snap - ...copy it off-box, age-encrypted. See the README for the full DR flow. + docker compose exec openbao \\ + bao operator raft snapshot save -address=https://127.0.0.1:8200 -tls-skip-verify /tmp/openbao.snap + docker compose exec -T openbao cat /tmp/openbao.snap > ${STACK_DIR}/openbao.snap + ...then age-encrypt + copy it off-box. See the README for the full DR flow. Manage: docker compose logs -f @@ -250,66 +299,71 @@ EOF # __ARCHIVE_BELOW__ is the embedded tar.gz payload (base64), added by build.sh. exit 0 __ARCHIVE_BELOW__ -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 -pZZaaqmlllpqqaWWWmr5/5N/AAPPvDEAUAAA +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 +Oym9JwC6CAgptd9aab0Tha4Q6paSMpeYkMkVlXfH2hmyLkOxXcbr0NmC+q152GrZ1xLk3EmFUuuI +fugh2vaSJULz3g/fDOhPf6L3jzZQDmYjmSNuB2364Zu9F4b04AUJph4fn0xHdOHsHTx/XNGS/If1 +RV4qhAkwF+CnARcllttIEECww1s9PjvtioEVqa0eV5Vpyd7wC0xnDknqEPqeFARY9tptlRtHikHO +w0H/f8lJ1D1blPIhKXwBUMP3WeblXozzzvxlfqeGWR7GCge5G5AAbE2/BycdHo/sd0tyzmafiNgR +zUUnFKRtJuvl9R8AOo4nRzY7wSgcXT1gMj8DpB5FxcSL1dHX71kfWaf8BVARPe/3txYtH+zvb63c +am0L76X1ksGGVEpvKJ7K6lD70Vximekh2Q3VrJP7+HAfgsezXnK9pb6rMkPYToA9/bElfykJhp8y +r3vquXPp0bvQ93936GraEzQG8q568GIkjf+qNT5b/x08X+M/xomDwcHzgwb/fYkGKJVmK/YarAmC +cCR5DBOXTEWlyvizkK9UyLBlJrkpIiWiQBStuAaxrvxpyXhloC1HwXOU5UAuBr7gdzoVwJOBjAs5 +RtnyHoNAOJoSF3I0DU0Km6XZ0rxiFtVdVwW4MHBpKhdhxKDmqTL+L/bHlSEboDv8Aj4noCTiKw9d +49NHk8vT6atR7d7MUl6Rr+N1Vf9Ok9ZOWSpyaSoSMe8yty6eMFJA1syvw82llvuFV0hhNkuBhT9V +KS2RBMZ2fun9Yddt1TuPKpzKgjstLwkYyVb3AkYXp+ZuANKSQM5XL9vRmeJLEtdAvrc9aJ+teaz1 +z7ze1xK7PvZqu+ATcj2OX2q/kBoZhqqHLAr9sIjYGvjyDkI1sp1M+Yx17K0Ilzoj2rrA8LmrCmWV +2grE1u+lM7XpRGhYb9A21q1uT9RvNrjdVv2l+5GtP29agJSJ/92K/LQ2Mf6/q8uRoKMqwdzW4l2o +8CoFEzeE/R1FaZpd83uYzv0i9BcbWmKqsSVA1l37+shc6wrWhfTx5Denl+eT1+PJFWu7ISDvazmt +NWkp14/ZTrVchslFn67VnF/wwN0l7OWqhU0KJ4nZdlp09Mm0bmCyyooIY/b1Ufj1Vm4NfB7y64Iy +XyQ5vc1pw9Ipp1xxnqschq3cLl2xupt69VZeXSa+Jr9eJ9TrbHp3K5Mu82jO+HlV81anSpz57yYB +X4KPvLtZu4qKIa3tFPAIGeCmxp/ybTK4xJv/Yr3HgS74fagIJsvTYOnz/QYrb11jzOjlkVyM2+TB +RwviL8rrPsx1Www3Y7pPwyouDfNtGb7c8tnbMh+/JWMyT7kHN+WKqylM98qytDa1a3OfbKtCDYM9 +L+/TSDpuQ4IoW+1VbbJkhFLW2DlMliX21lZh+6hJaZrWtKY1rWlNa1rTmta0pjWtaU1rWtOa1rSm +Na1pTWta05rWtKY1rWlNa1rTmvZf1v4G3yMW1ABQAAA= diff --git a/deployments/openbao/docker-compose.yml b/deployments/openbao/docker-compose.yml index 333ee0b..8cd10b8 100644 --- a/deployments/openbao/docker-compose.yml +++ b/deployments/openbao/docker-compose.yml @@ -26,8 +26,14 @@ services: ulimits: memlock: -1 ports: - # Native-TLS API. Bind to the LAN IP (OPENBAO_BIND) to avoid exposing it on - # every interface; firewall it to the tape host (deploy.sh does this). + # Native-TLS API. Publish on the LAN IP only (OPENBAO_BIND) so it is not + # exposed on unrelated interfaces. NOTE: a Docker-published port is DNAT'd + # and bypasses the host INPUT firewall, so a source restriction there does + # NOT gate it — narrow access with OPENBAO_BIND + the optional mTLS + # (tls_require_and_verify_client_cert) stanza in config.hcl, and initialise + # the vault immediately (an uninitialised vault can be init'd by anyone who + # can reach it). deploy.sh defaults OPENBAO_BIND to OPENBAO_ADDR when it is + # an IP. - "${OPENBAO_BIND:-0.0.0.0}:8200:8200" volumes: - ./config.hcl:/openbao/config/config.hcl:ro diff --git a/deployments/openbao/gen-tls.sh b/deployments/openbao/gen-tls.sh index cbfc773..03e723d 100644 --- a/deployments/openbao/gen-tls.sh +++ b/deployments/openbao/gen-tls.sh @@ -36,4 +36,4 @@ chmod 644 "$DIR/tls.crt" echo "[gen-tls] Generated self-signed OpenBao cert in $DIR" echo "[gen-tls] SANs: ${SANS} validity: ${DAYS}d" echo "[gen-tls] Give $DIR/tls.crt to the Kanrisha daemon as" -echo "[gen-tls] [encryption.openbao].openbao_ca_cert (so it trusts this listener)." +echo "[gen-tls] [encryption.openbao].ca_cert (so it trusts this listener)."