From 5c08c0334d44ced8b49c52392abbd40380295359 Mon Sep 17 00:00:00 2001 From: mrwhiski Date: Mon, 5 Oct 2026 19:40:40 +0200 Subject: [PATCH] Adds vaultwarden instance for testing whether I like it --- docker/npm/compose.yaml | 10 +++++ docker/vaultwarden/README.md | 76 +++++++++++++++++++++++++++++++++ docker/vaultwarden/compose.yaml | 27 ++++++++++++ docs/todo.md | 6 ++- 4 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 docker/vaultwarden/README.md create mode 100644 docker/vaultwarden/compose.yaml diff --git a/docker/npm/compose.yaml b/docker/npm/compose.yaml index 086b796..8aee8e4 100644 --- a/docker/npm/compose.yaml +++ b/docker/npm/compose.yaml @@ -8,7 +8,17 @@ services: - "80:80" # HTTP, proxied traffic - "443:443" # HTTPS, proxied traffic - "81:81" # Admin UI + # `default` keeps the existing setup; `proxy` reaches containers that + # publish no ports (Vaultwarden) by container name. + networks: + - default + - proxy volumes: # Both contain the INWX DNS-challenge password in plain text — never commit. - ./data:/data - ./letsencrypt:/etc/letsencrypt + +networks: + proxy: + # Created once by hand: docker network create proxy + external: true diff --git a/docker/vaultwarden/README.md b/docker/vaultwarden/README.md new file mode 100644 index 0000000..b7e4b67 --- /dev/null +++ b/docker/vaultwarden/README.md @@ -0,0 +1,76 @@ +# Vaultwarden + +Password manager for both of us. Runs on the OptiPlex homeserver +(`192.168.30.20`) in `~/vaultwarden`, reachable only as +`https://vault.home.staffenberger.at` — at home or through the WireGuard VPN. +Clients are the official Bitwarden apps and browser extensions, set to the +self-hosted server URL. + +## Network + +The container publishes **no ports**. NPM reaches it on a shared Docker network +called `proxy`, so the only way in is HTTPS through NPM. Bitwarden clients +refuse plain HTTP anyway, and this stops anyone on the LAN from going around TLS. + +One-time setup on the OptiPlex, before the first `docker compose up -d`: + +```bash +docker network create proxy +``` + +Then recreate NPM so it joins the network (`cd ~/npm && docker compose up -d`). + +## Setup + +1. **Pi-hole Local DNS record:** `vault.home.staffenberger.at` → `192.168.30.20`, + on whichever Pi-hole the clients use right now. +2. **NPM proxy host:** `vault.home.staffenberger.at`, scheme `http`, forward + to `vaultwarden` port `80`, **Websockets Support on** (live sync between + devices), wildcard certificate, Force SSL, HTTP/2. + The forward host must be the **container name**, not `192.168.30.20`: the + host's port 80 is NPM itself, which caused a redirect loop + (`ERR_TOO_MANY_REDIRECTS`). +3. Open the URL and create **both accounts**. Each person picks their own + master password; it can't be reset, only changed while logged in. +4. Set `SIGNUPS_ALLOWED: "false"` and run `docker compose up -d`. Check that + "Create account" fails. +5. Turn on **two-step login (authenticator app)** for both accounts, and keep + the recovery codes outside the vault. +6. Create an **Organization** (e.g. "Home") with collections for shared logins, + invite the partner's account, then confirm them as owner. + No SMTP is configured, so no invite mail is sent: the partner accepts + in the web vault, then you confirm. Untested here, check while setting it up. +7. **Import** the old vaults (Tools → Import data; Bitwarden reads Enpass + JSON). Delete the plain-text export files afterwards and empty the trash. + +## Backups + +**Don't move real passwords in before this works.** Devices that are logged in +keep an encrypted offline copy, but that doesn't replace a backup. + +- Contents of `./data` to keep: `db.sqlite3`, `attachments/`, `sends/`, + `rsa_key*` and `config.json` (if present). +- Copy the database with `sqlite3 db.sqlite3 ".backup ..."`, not `cp`, + since the file may be mid-write. +- Encrypted copy to the NAS, part of the OptiPlex off-box backup + (see [../../docs/todo.md](../../docs/todo.md)). +- Occasionally: an **encrypted** export from the web vault, kept offline. +- **Test a restore** once, onto a throwaway container. + +## Using it away from home + +The apps can fill passwords offline, but **saving or editing needs the +server**. Set the WireGuard app on both phones to connect automatically when +not on the home Wi-Fi, otherwise passwords for new sign-ups get lost. +The VPN is split-tunnel (Servers + IoT only), so normal browsing doesn't go +through it. + +## Notes + +- `/admin` is disabled (no `ADMIN_TOKEN`). If it is ever needed, set a + hashed token generated with `docker exec -it vaultwarden /vaultwarden hash`, + never a plain-text one. +- The image is pinned; check the release notes before bumping. +- Write down for the partner how to get at their passwords if the server + or I am unavailable: their master password, where the backups are, and how + to restore them. diff --git a/docker/vaultwarden/compose.yaml b/docker/vaultwarden/compose.yaml new file mode 100644 index 0000000..301d4bb --- /dev/null +++ b/docker/vaultwarden/compose.yaml @@ -0,0 +1,27 @@ +services: + vaultwarden: + # Pin the exact version; read the release notes before bumping — Bitwarden + # client updates sometimes require a newer server. + # https://github.com/dani-garcia/vaultwarden/releases + image: vaultwarden/server:1.37.3 + container_name: vaultwarden + restart: unless-stopped + # No published ports: only reachable through NPM on the shared `proxy` + # network, so there is no plain-HTTP path to the vault. + networks: + - proxy + environment: + TZ: Europe/Vienna + DOMAIN: "https://vault.home.staffenberger.at" + # true only until both accounts exist, then false + `docker compose up -d`. + SIGNUPS_ALLOWED: "true" + SHOW_PASSWORD_HINT: "false" + # No ADMIN_TOKEN: the /admin page stays disabled. + volumes: + # Database, attachments and the server's RSA key — back up encrypted, + # never commit. + - ./data:/data + +networks: + proxy: + external: true diff --git a/docs/todo.md b/docs/todo.md index d96fd7a..5439375 100644 --- a/docs/todo.md +++ b/docs/todo.md @@ -38,7 +38,11 @@ Set up 2026-10-04, see [homeserver.md](homeserver.md). **Services** - [ ] Portainer (behind HTTPS; for viewing and restarts only, compose files stay the source of truth). -- [ ] Vaultwarden, with backups to the NAS. +- [ ] Vaultwarden, with backups to the NAS — setup steps in [`../docker/vaultwarden/`](../docker/vaultwarden/README.md). Real passwords only move in once the backup works. + - [x] Running at `https://vault.home.staffenberger.at`, own account created, desktop + phone working (2026-10-05). + - [ ] **Trial phase:** a few non-critical passwords kept in both Enpass and Vaultwarden. Decide whether to switch. + - [ ] If yes: partner's account (then `SIGNUPS_ALLOWED: "false"`), Organization "Home", backup + test restore, then both import their old vaults. + - [ ] Every phone's WireGuard tunnel needs the OptiPlex Pi-hole as DNS server — edited by hand in the app (changing it in the ER605 only affects newly generated configs). - [ ] Own Docker tools. **Home Assistant** -- 2.45.2