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:
ml
2026-06-28 14:13:53 +02:00
parent fdcc0079cb
commit 187c6bdea4
15 changed files with 436 additions and 116 deletions
+29 -15
View File
@@ -11,8 +11,6 @@ setup of individual services.
### Local tools
- Ansible installed (`pip install ansible`)
- `htpasswd` available (`apt install apache2-utils` or `brew install httpd`)
- `docker` available (for generating the registry htpasswd entry)
- `openssl` available (for generating secrets)
### SSH keys
@@ -89,35 +87,51 @@ Create `ansible/group_vars/all/vault.yml` (gitignored) and encrypt it with Ansib
ansible-vault create ansible/group_vars/all/vault.yml
```
Populate all required secrets:
Populate all required secrets. Ansible generates all password hashes at
deploy time — store plaintext values here (the vault is encrypted).
```yaml
# Traefik dashboard basic auth
# Generate: echo $(htpasswd -nB admin) | sed -e 's/\$/\$\$/g'
traefik_dashboard_users: "admin:$$2y$$05$$..."
# Traefik dashboard basic auth — generate with: openssl rand -hex 32
traefik_dashboard_users:
- username: admin
password: "your-password"
# Gitea
# Generate secrets: openssl rand -hex 32
# Gitea — generate with: openssl rand -hex 32
gitea_db_password: ""
gitea_secret_key: ""
gitea_internal_token: ""
# Keycloak
# Keycloak — generate with: openssl rand -hex 32
keycloak_db_password: ""
keycloak_admin_password: ""
# Nextcloud
# Nextcloud — generate with: openssl rand -hex 32
nextcloud_db_password: ""
nextcloud_admin_password: ""
# Roundcube
# des_key must be exactly 24 characters: openssl rand -hex 12
# Roundcube — des_key must be exactly 24 characters: openssl rand -hex 12
roundcube_db_password: ""
roundcube_des_key: ""
# Container registry
# Generate: docker run --entrypoint htpasswd httpd:2 -Bbn <user> <password>
registry_htpasswd: "user:$2y$05$..."
# Container registry — generate with: openssl rand -hex 32
registry_users:
- username: alice
password: "your-password"
# Dovecot IMAP users — generate with: openssl rand -hex 32
dovecot_users:
- username: alice
password: "your-password"
# Fetchmail — external POP3 accounts to pull from (omit section if not needed)
# fetchmail_accounts:
# - server: pop.gmail.com
# username: user@gmail.com
# password: app-password # use a Gmail App Password, not your main password
# local_user: alice
# ssl: true
# keep: true # set false to delete from source after fetching
# poll_minutes: 10 # how often to poll this account (default: 10)
```
Verify all secrets are present and non-empty: