mirror of
https://gitlab.kube.huskypup.net/Scooby/Homelabv4.git
synced 2026-08-20 23:16:49 +00:00
Fix vault-restore: authenticate raft snapshot restore with a real token
raft snapshot restore is a privileged operation - unsealing alone isn't enough, it needs an authenticated token. Missed this on first pass, caught live: 'Code: 403. Errors: * permission denied'. First run: uses the throwaway init's own fresh root token. Steady state (already restored at least once): uses a copy of home's real root token, which becomes valid on this Vault the moment the first restore completes (its auth data becomes byte-for-byte home's as of that snapshot). Stored the same way as the unseal key - kubectl directly on the VPS, not git. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
62751f7d75
commit
e2bdab8940
@@ -71,11 +71,25 @@ data:
|
|||||||
# the chart's default "vault-0".
|
# the chart's default "vault-0".
|
||||||
VAULT_POD="vps-vault-0"
|
VAULT_POD="vps-vault-0"
|
||||||
UNSEAL_KEY="$(kubectl -n vault get secret vault-unseal-key -o jsonpath='{.data.key}' | base64 -d)"
|
UNSEAL_KEY="$(kubectl -n vault get secret vault-unseal-key -o jsonpath='{.data.key}' | base64 -d)"
|
||||||
|
# Home's real root token - after the first successful restore, this
|
||||||
|
# Vault's auth data is byte-for-byte home's (as of that snapshot), so
|
||||||
|
# home's root token is valid here too. Needed to authenticate
|
||||||
|
# `raft snapshot restore`, which is a privileged operation - unseal
|
||||||
|
# alone isn't enough. Stored the same way as the unseal key (kubectl,
|
||||||
|
# not git):
|
||||||
|
# kubectl -n vault create secret generic vault-root-token \
|
||||||
|
# --from-literal=token=<home's VAULT_ROOT_TOKEN>
|
||||||
|
HOME_ROOT_TOKEN="$(kubectl -n vault get secret vault-root-token -o jsonpath='{.data.token}' | base64 -d)"
|
||||||
|
RESTORE_TOKEN=""
|
||||||
|
|
||||||
vault_exec() {
|
vault_exec() {
|
||||||
kubectl -n vault exec -i "$VAULT_POD" -- env VAULT_ADDR=http://127.0.0.1:8200 vault "$@"
|
kubectl -n vault exec -i "$VAULT_POD" -- env VAULT_ADDR=http://127.0.0.1:8200 vault "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vault_exec_auth() {
|
||||||
|
kubectl -n vault exec -i "$VAULT_POD" -- env VAULT_ADDR=http://127.0.0.1:8200 VAULT_TOKEN="$RESTORE_TOKEN" vault "$@"
|
||||||
|
}
|
||||||
|
|
||||||
echo "==> Checking Vault status..."
|
echo "==> Checking Vault status..."
|
||||||
STATUS_JSON="$(vault_exec status -format=json 2>&1 || true)"
|
STATUS_JSON="$(vault_exec status -format=json 2>&1 || true)"
|
||||||
INITIALIZED="$(echo "$STATUS_JSON" | jq -r '.initialized // empty' 2>/dev/null || echo "")"
|
INITIALIZED="$(echo "$STATUS_JSON" | jq -r '.initialized // empty' 2>/dev/null || echo "")"
|
||||||
@@ -85,14 +99,20 @@ data:
|
|||||||
echo "==> First run: initializing with a throwaway single-key seal..."
|
echo "==> First run: initializing with a throwaway single-key seal..."
|
||||||
INIT_JSON="$(vault_exec operator init -key-shares=1 -key-threshold=1 -format=json)"
|
INIT_JSON="$(vault_exec operator init -key-shares=1 -key-threshold=1 -format=json)"
|
||||||
THROWAWAY_KEY="$(echo "$INIT_JSON" | jq -r '.unseal_keys_b64[0]')"
|
THROWAWAY_KEY="$(echo "$INIT_JSON" | jq -r '.unseal_keys_b64[0]')"
|
||||||
|
RESTORE_TOKEN="$(echo "$INIT_JSON" | jq -r '.root_token')"
|
||||||
echo "==> Unsealing with throwaway key for first restore..."
|
echo "==> Unsealing with throwaway key for first restore..."
|
||||||
vault_exec operator unseal "$THROWAWAY_KEY" >/dev/null
|
vault_exec operator unseal "$THROWAWAY_KEY" >/dev/null
|
||||||
unset THROWAWAY_KEY INIT_JSON
|
unset THROWAWAY_KEY INIT_JSON
|
||||||
elif [ "$SEALED" = "true" ]; then
|
|
||||||
echo "==> Sealed - unsealing with the stored home unseal key..."
|
|
||||||
vault_exec operator unseal "$UNSEAL_KEY" >/dev/null
|
|
||||||
else
|
else
|
||||||
echo "==> Already unsealed."
|
# Already restored at least once before - home's root token is valid
|
||||||
|
# here regardless of seal state, since it's restored FROM home.
|
||||||
|
RESTORE_TOKEN="$HOME_ROOT_TOKEN"
|
||||||
|
if [ "$SEALED" = "true" ]; then
|
||||||
|
echo "==> Sealed - unsealing with the stored home unseal key..."
|
||||||
|
vault_exec operator unseal "$UNSEAL_KEY" >/dev/null
|
||||||
|
else
|
||||||
|
echo "==> Already unsealed."
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "==> Installing mc (MinIO client)..."
|
echo "==> Installing mc (MinIO client)..."
|
||||||
@@ -117,8 +137,7 @@ data:
|
|||||||
kubectl -n vault cp "/tmp/${LATEST}" "${VAULT_POD}:/tmp/${LATEST}"
|
kubectl -n vault cp "/tmp/${LATEST}" "${VAULT_POD}:/tmp/${LATEST}"
|
||||||
|
|
||||||
echo "==> Restoring raft snapshot (this replaces all data + the keyring)..."
|
echo "==> Restoring raft snapshot (this replaces all data + the keyring)..."
|
||||||
kubectl -n vault exec -i "$VAULT_POD" -- env VAULT_ADDR=http://127.0.0.1:8200 \
|
vault_exec_auth operator raft snapshot restore -force "/tmp/${LATEST}"
|
||||||
vault operator raft snapshot restore -force "/tmp/${LATEST}"
|
|
||||||
kubectl -n vault exec "$VAULT_POD" -- rm -f "/tmp/${LATEST}"
|
kubectl -n vault exec "$VAULT_POD" -- rm -f "/tmp/${LATEST}"
|
||||||
|
|
||||||
echo "==> Restarting Vault to fully reload post-restore state..."
|
echo "==> Restarting Vault to fully reload post-restore state..."
|
||||||
|
|||||||
Reference in New Issue
Block a user