Files
server_cloud_ladkau_de/scripts/check-vault.sh
T
ml f53ccbab4a Add public download server at dl.ladkau.de and improve vault validation
- New dl role — nginx serves files publicly over HTTPS with directory
  listing; atmoz/sftp on port 2223 for key-only uploads; both containers
  share /opt/dl/files volume
- check-vault.sh gains a third tier: optional secrets are validated when
  present — vaultwarden_sso_client_secret must be non-empty,
  dl_sftp_authorized_keys must begin with a recognised SSH public key prefix
- dl.ladkau.de added to DNS table, check-services.sh, and status dashboard
- Configuration runbook section 7: deploy key generation, Gitea Actions
  scp workflow example, and SFTP client connection settings
- Provisioning runbook documents the three-tier vault validation behaviour
2026-06-28 16:20:47 +02:00

97 lines
3.0 KiB
Bash
Executable File

#!/usr/bin/env bash
# Decrypts ansible/group_vars/vault.yml and checks all required secrets are present
# and non-empty, and validates optional secrets when they are present.
# Exits non-zero if any check fails.
# Usage: bash scripts/check-vault.sh
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
VAULT_FILE="${REPO_ROOT}/ansible/group_vars/all/vault.yml"
if [ ! -f "${VAULT_FILE}" ]; then
echo "ERROR: vault file not found at ${VAULT_FILE}" >&2
echo " Create it with: ansible-vault create ansible/group_vars/all/vault.yml" >&2
exit 1
fi
if ! command -v ansible-vault &>/dev/null; then
echo "ERROR: ansible-vault not found — install with: pip install ansible" >&2
exit 1
fi
echo "==> Decrypting vault (you will be prompted for the vault password)"
VAULT_CONTENT=$(ansible-vault view "${VAULT_FILE}")
echo "${VAULT_CONTENT}" | python3 - <<'PYEOF'
import sys, yaml
data = yaml.safe_load(sys.stdin.read())
# Required non-empty scalar strings
required_scalars = [
"gitea_db_password",
"gitea_secret_key",
"gitea_internal_token",
"keycloak_db_password",
"keycloak_admin_password",
"nextcloud_db_password",
"nextcloud_admin_password",
"roundcube_db_password",
"roundcube_des_key",
"vaultwarden_admin_token",
"dl_sftp_authorized_keys",
]
# Required non-empty lists (must contain at least one entry)
required_lists = [
"traefik_dashboard_users",
"registry_users",
"dovecot_users",
]
# Optional scalars: validated only when present — (key, validator_fn, hint)
SSH_KEY_PREFIXES = ("ssh-rsa", "ssh-ed25519", "ssh-ecdsa", "ecdsa-sha2-", "sk-ssh-")
def is_nonempty(val):
return bool(str(val).strip())
def is_ssh_pubkey(val):
return any(str(val).strip().startswith(p) for p in SSH_KEY_PREFIXES)
optional_scalars = [
("vaultwarden_sso_client_secret", is_nonempty, "must be a non-empty string"),
("dl_sftp_authorized_keys", is_ssh_pubkey, "must be a valid SSH public key (ssh-ed25519 / ssh-rsa / ecdsa-sha2-*)"),
]
errors = []
for key in required_scalars:
val = data.get(key, "")
if not val or str(val).strip() in ("", '""', "''"):
errors.append(f"{key}: missing or empty (required)")
for key in required_lists:
val = data.get(key)
if not isinstance(val, list) or len(val) == 0:
errors.append(f"{key}: missing or empty list (required)")
for key, validator, hint in optional_scalars:
if key in data:
val = data[key]
if not val or not validator(str(val).strip()):
errors.append(f"{key}: present but invalid — {hint}")
if errors:
print("", file=sys.stderr)
print("ERROR: vault.yml has the following issues:", file=sys.stderr)
for msg in errors:
print(f" - {msg}", file=sys.stderr)
print("", file=sys.stderr)
print("Edit the vault with: ansible-vault edit ansible/group_vars/all/vault.yml", file=sys.stderr)
sys.exit(1)
print(" OK — all secrets are present and valid")
PYEOF