Files
server_cloud_ladkau_de/docs/runbook-configuration.md
T
ml 1c36b7bbcb Add Vaultwarden self-hosted password vault at vault.ladkau.de
- New vaultwarden role — Vaultwarden container with SQLite storage, admin
  panel protected by token, Keycloak SSO enabled on second deploy after
  the OIDC client secret is available (SSO_ENABLED conditionally set so
  first provisioning deploy works without Keycloak being configured yet)
- Traefik routes vault.ladkau.de with lax rate limiting (SPA loads many assets)
- vault.ladkau.de added to DNS table, check-services.sh, status dashboard,
  and check-vault.sh (admin token required; SSO secret is post-provisioning)
- Configuration runbook: step 2.6 for Keycloak client, section 6 for
  Vaultwarden setup including admin panel, SSO login, and client configuration
2026-06-28 15:39:42 +02:00

259 lines
9.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Configuration Runbook
First-run configuration steps to perform after the Ansible playbook has
provisioned the server. See `runbook-provisioning.md` for the provisioning steps.
## 1. Verify all services are reachable
Before configuring individual services, confirm every HTTPS endpoint is up and
TLS certificates are valid. Run this from your local machine:
```bash
bash scripts/check-services.sh
```
The script checks these endpoints and verifies the expected HTTP status code:
| URL | Expected | Notes |
|-----|----------|-------|
| `https://cloud.ladkau.de/dashboard/` | 401 | Basic-auth prompt — correct without credentials |
| `https://gitea.ladkau.de` | 200 | Gitea sign-in page |
| `https://nextcloud.ladkau.de` | 200 | First visit triggers setup and takes 12 min |
| `https://sso.ladkau.de/realms/master` | 200 | Keycloak realm JSON — first start takes ~90 s |
| `https://mail.ladkau.de` | 200 | Roundcube webmail login |
| `https://cr.ladkau.de/v2/` | 401 | Registry API — auth required, correct without credentials |
| `https://k8s.ladkau.de` | 200 | Placeholder page |
| `https://vault.ladkau.de` | 200 | Vaultwarden web vault |
A `000` result means the connection was refused or timed out — a container that
did not start. Keycloak and Nextcloud may return `502` for up to 90 seconds on
first boot; wait and retry before investigating.
Once the script passes, open `https://cloud.ladkau.de/dashboard/` in a browser
and authenticate with the `traefik_dashboard_users` credentials to verify the
dashboard loads correctly.
## 2. Keycloak
Keycloak is the identity provider for all services. Configure it first so that
Gitea and Nextcloud can be wired up to SSO in the steps that follow.
Keycloak takes ~90 seconds to start on first boot. If the login page at
`https://sso.ladkau.de` is not immediately available, wait and retry.
### 2.1 Log in and change the admin password
1. Go to `https://sso.ladkau.de` and sign in with username `admin` and the
value of `keycloak_admin_password` from the vault.
2. Click the **admin** dropdown (top right) → **Manage account**
**Password** → set a new password.
The bootstrap credentials are only used on first start. After changing the
password, the vault value is no longer authoritative — store the new password
in your password manager.
### 2.2 Create an application realm
1. In the left sidebar, click the realm dropdown (shows **master**) →
**Create realm**.
2. Set **Realm name** to `ladkau` and click **Create**.
3. Make sure the `ladkau` realm is selected in the sidebar for all steps below.
The `master` realm is for Keycloak administration only. All application users
and clients live in `ladkau`.
### 2.3 Create users
For each user you want to be able to log in to Gitea and Nextcloud:
1. **Users****Add user**.
2. Fill in **Username**, **Email**, **First name**, **Last name****Create**.
3. Go to the **Credentials** tab → **Set password**.
4. Enter a password, turn off **Temporary**, and click **Save**.
### 2.4 Create the Gitea OIDC client
1. **Clients****Create client**.
2. **Client type**: OpenID Connect — **Client ID**: `gitea`**Next**.
3. Turn **Client authentication** on (confidential client) → **Next**.
4. **Valid redirect URIs**: `https://gitea.ladkau.de/user/oauth2/keycloak/callback`
5. **Web origins**: `https://gitea.ladkau.de`**Save**.
6. Go to the **Credentials** tab and copy the **Client secret** — you will
need it in step 3.
### 2.5 Create the Nextcloud OIDC client
1. **Clients****Create client**.
2. **Client type**: OpenID Connect — **Client ID**: `nextcloud`**Next**.
3. Turn **Client authentication** on → **Next**.
4. **Valid redirect URIs**: `https://nextcloud.ladkau.de/apps/user_oidc/code`
5. **Valid post logout redirect URIs**: `https://nextcloud.ladkau.de/*`
6. **Web origins**: `https://nextcloud.ladkau.de`**Save**.
7. Go to the **Credentials** tab and copy the **Client secret** — you will
need it in step 4.
### 2.6 Create the Vaultwarden OIDC client
1. **Clients****Create client**.
2. **Client type**: OpenID Connect — **Client ID**: `vaultwarden`**Next**.
3. Turn **Client authentication** on → **Next**.
4. **Valid redirect URIs**: `https://vault.ladkau.de/*`
5. **Valid post logout redirect URIs**: `https://vault.ladkau.de/*`
6. **Web origins**: `https://vault.ladkau.de`**Save**.
7. Go to the **Credentials** tab and copy the **Client secret**.
8. Add it to the vault as `vaultwarden_sso_client_secret` and redeploy:
```bash
ansible-vault edit ansible/group_vars/all/vault.yml
ansible-playbook -i ansible/inventory.ini ansible/site.yml --tags vaultwarden --ask-vault-pass
```
## 3. Gitea
### 3.1 Create the admin account
1. Go to `https://gitea.ladkau.de` — Gitea shows an initial configuration
dialog on the first visit.
2. Scroll to the bottom of the form to the **Administrator Account Settings**
section and fill in the admin username, email, and password.
3. Click **Install Gitea**.
Gitea initialises the database and creates the admin account in one step.
Public registration is closed — only users authenticating via Keycloak can
get an account (controlled by `ALLOW_ONLY_EXTERNAL_REGISTRATION`).
### 3.2 Connect Gitea to Keycloak
1. In Gitea, go to **Site Administration** → **Identity & Access** →
**Authentication Sources** → **Add Authentication Source**.
2. Set **Authentication type** to **OAuth2**.
3. Set **OAuth2 provider** to **OpenID Connect**.
4. Fill in:
- **Name**: `keycloak`
- **Client ID**: `gitea`
- **Client secret**: the secret copied in step 2.4
- **OpenID Connect Auto Discovery URL**:
`https://sso.ladkau.de/realms/ladkau/.well-known/openid-configuration`
5. Click **Add Authentication Source**.
Users can now sign in via **Sign in with keycloak** on the Gitea login page.
## 4. Nextcloud
The admin credentials are set via `nextcloud_admin_user` and
`nextcloud_admin_password` in the vault. The first HTTP request triggers
installation, which takes a minute or two.
### 4.1 Log in
1. Go to `https://nextcloud.ladkau.de` and sign in with the admin credentials
from the vault.
### 4.2 Connect Nextcloud to Keycloak
1. Go to **Apps** → search for **OpenID Connect user backend** → **Download
and enable**.
2. Go to **Administration settings** → **OpenID Connect** → **Add provider**.
3. Fill in:
- **Identifier**: `keycloak`
- **Client ID**: `nextcloud`
- **Client secret**: the secret copied in step 2.5
- **Discovery endpoint**:
`https://sso.ladkau.de/realms/ladkau/.well-known/openid-configuration`
4. Click **Save**.
Users can now sign in to Nextcloud with their Keycloak credentials via the
**Log in with keycloak** button.
## 5. Mail (Dovecot + Roundcube + Fetchmail)
The mail stack runs a local Dovecot IMAP server. Roundcube connects to it
internally. External IMAP clients connect to `mail.ladkau.de:993` (IMAPS —
TLS terminated by Traefik). Fetchmail polls external POP3 accounts and
delivers to Dovecot.
Dovecot users and fetchmail accounts are configured in the vault before
provisioning — see step 4 of `runbook-provisioning.md`. To add users or
accounts after initial deployment, edit the vault and redeploy:
```bash
ansible-vault edit ansible/group_vars/all/vault.yml
ansible-playbook -i ansible/inventory.ini ansible/site.yml --tags mail --ask-vault-pass
```
### 5.1 Import mail from an old Dovecot server
If migrating from an existing Dovecot server, sync the Maildir directly:
```bash
# Run on the old server — syncs to the new server's maildir volume
rsync -av --progress /var/mail/alice/Maildir/ \
root@217.154.207.148:/opt/mail/maildir/alice/Maildir/
# Fix ownership for Dovecot's vmail user (UID 5000)
ssh root@217.154.207.148 "chown -R 5000:5000 /opt/mail/maildir/alice"
```
Alternatively, use `imapsync` to copy via IMAP from the old server to the
new one (works without direct server access):
```bash
imapsync \
--host1 old.server.com --user1 alice --password1 oldpass \
--host2 mail.ladkau.de --user2 alice --password2 newpass \
--port2 993 --ssl2
```
### 5.2 Connect an IMAP client
| Setting | Value |
|-----------|----------------------|
| Server | `mail.ladkau.de` |
| Port | `993` |
| Security | SSL/TLS |
| Username | as set in vault |
## 6. Vaultwarden
Vaultwarden is a self-hosted Bitwarden-compatible password vault. Any official
Bitwarden client (browser extension, desktop, mobile) can connect to it.
### 6.1 Log in to the admin panel
Go to `https://vault.ladkau.de/admin/` and enter the `vaultwarden_admin_token`
from the vault. From here you can invite users and manage the instance.
### 6.2 Sign in with Keycloak SSO
Users can sign in at `https://vault.ladkau.de` using the **Enterprise Single
Sign-On** button — enter `https://sso.ladkau.de/realms/ladkau` as the
organisation identifier. On first login Vaultwarden creates an account
automatically (public self-registration is otherwise disabled).
### 6.3 Connect a Bitwarden client
In any official Bitwarden client, set the **Server URL** to
`https://vault.ladkau.de` before logging in.
## 7. Container registry
```bash
# Login
docker login cr.ladkau.de
# Push
docker tag myimage:latest cr.ladkau.de/myimage:latest
docker push cr.ladkau.de/myimage:latest
# Pull
docker pull cr.ladkau.de/myimage:latest
```
Registry users are managed via `registry_users` in the vault — store plaintext
passwords, Ansible generates bcrypt hashes at deploy time. To add or rotate a
user, edit the vault and redeploy:
```bash
ansible-vault edit ansible/group_vars/all/vault.yml
ansible-playbook -i ansible/inventory.ini ansible/site.yml --tags registry --ask-vault-pass
```