Add Dovecot IMAP + Fetchmail, fix Gitea SSO, simplify credential management
- Add local Dovecot IMAP server exposed via Traefik IMAPS on port 993; Roundcube now connects to it internally instead of requiring manual server entry - Add Fetchmail integration for pulling from external POP3 accounts with configurable per-account poll interval - Fix Gitea SSO registration: DISABLE_REGISTRATION=false + ALLOW_ONLY_EXTERNAL_REGISTRATION allows Keycloak-authenticated users to get accounts while blocking public sign-up; disable legacy OpenID 2.0 sign-in - Fix Keycloak post-logout redirect for Nextcloud (valid post logout redirect URI) - Replace all pre-hashed credentials (Traefik dashboard, registry, Dovecot) with plaintext passwords in vault; Ansible generates deterministic bcrypt/SHA-512 hashes at deploy time — no more manual htpasswd commands - Rewrite check-vault.sh with Python/PyYAML to properly validate both scalar and list-type secrets - Update provisioning and configuration runbooks throughout
This commit is contained in:
+47
-33
@@ -9,23 +9,9 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||
VAULT_FILE="${REPO_ROOT}/ansible/group_vars/all/vault.yml"
|
||||
|
||||
REQUIRED_KEYS=(
|
||||
traefik_dashboard_users
|
||||
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
|
||||
registry_htpasswd
|
||||
)
|
||||
|
||||
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/vault.yml" >&2
|
||||
echo " Create it with: ansible-vault create ansible/group_vars/all/vault.yml" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -37,23 +23,51 @@ fi
|
||||
echo "==> Decrypting vault (you will be prompted for the vault password)"
|
||||
VAULT_CONTENT=$(ansible-vault view "${VAULT_FILE}")
|
||||
|
||||
MISSING=()
|
||||
for key in "${REQUIRED_KEYS[@]}"; do
|
||||
# Match lines like: key: "value" or key: value — but not key: "" or key: '' or missing
|
||||
if ! echo "${VAULT_CONTENT}" | grep -qE "^${key}:[[:space:]]+[^'\"[:space:]]|^${key}:[[:space:]]+['\"].+['\"]"; then
|
||||
MISSING+=("${key}")
|
||||
fi
|
||||
done
|
||||
echo "${VAULT_CONTENT}" | python3 - <<'PYEOF'
|
||||
import sys, yaml
|
||||
|
||||
if [ ${#MISSING[@]} -gt 0 ]; then
|
||||
echo "" >&2
|
||||
echo "ERROR: the following secrets are missing or empty in vault.yml:" >&2
|
||||
for key in "${MISSING[@]}"; do
|
||||
echo " - ${key}" >&2
|
||||
done
|
||||
echo "" >&2
|
||||
echo "Edit the vault with: ansible-vault edit ansible/group_vars/vault.yml" >&2
|
||||
exit 1
|
||||
fi
|
||||
data = yaml.safe_load(sys.stdin.read())
|
||||
|
||||
echo " OK — all required secrets are present"
|
||||
# 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",
|
||||
]
|
||||
|
||||
# Required non-empty lists (must contain at least one entry)
|
||||
required_lists = [
|
||||
"traefik_dashboard_users",
|
||||
"registry_users",
|
||||
"dovecot_users",
|
||||
]
|
||||
|
||||
missing = []
|
||||
|
||||
for key in required_scalars:
|
||||
val = data.get(key, "")
|
||||
if not val or str(val).strip() in ("", '""', "''"):
|
||||
missing.append(key)
|
||||
|
||||
for key in required_lists:
|
||||
val = data.get(key)
|
||||
if not isinstance(val, list) or len(val) == 0:
|
||||
missing.append(key)
|
||||
|
||||
if missing:
|
||||
print("", file=sys.stderr)
|
||||
print("ERROR: the following secrets are missing or empty in vault.yml:", file=sys.stderr)
|
||||
for key in missing:
|
||||
print(f" - {key}", 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 required secrets are present")
|
||||
PYEOF
|
||||
|
||||
Reference in New Issue
Block a user