diff --git a/05-Vaultwarden-CT103.md b/05-Vaultwarden-CT103.md new file mode 100644 index 0000000..d54367b --- /dev/null +++ b/05-Vaultwarden-CT103.md @@ -0,0 +1,116 @@ +# CT 103 — Vaultwarden (Passwortmanager) — Rebuild-Runbook + +Sensibelster Dienst im gesamten Setup — bewusst **nur über Tailscale** erreichbar, nie öffentlich. + +## 1. Container erstellen + +```bash +pct create 103 local:vztmpl/debian-13-standard_13.6-1_amd64.tar.zst \ + --hostname vaultwarden \ + --unprivileged 1 \ + --cores 1 \ + --memory 512 \ + --swap 512 \ + --rootfs local-lvm:4 \ + --net0 name=eth0,bridge=vmbr0,ip=/24,gw= \ + --features nesting=1 \ + --timezone Europe/Berlin \ + --onboot 1 \ + --nameserver +pct start 103 +``` + +## 2. TUN-Device für Tailscale (siehe `01-pve-host.md`, Abschnitt 8) + +```bash +pct stop 103 +cat >> /etc/pve/lxc/103.conf <<'EOF' +lxc.cgroup2.devices.allow: c 10:200 rwm +lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file 0 0 +EOF +pct start 103 +``` + +## 3. Docker + +```bash +pct exec 103 -- apt-get update +pct exec 103 -- apt-get install -y curl ca-certificates +pct exec 103 -- bash -c "curl -fsSL https://get.docker.com | sh" +``` + +## 4. Tailscale-Mitgliedschaft + HTTPS-Zertifikat + +```bash +pct exec 103 -- bash -c "curl -fsSL https://tailscale.com/install.sh | sh" +pct exec 103 -- tailscale up --authkey= --hostname=vaultwarden +``` + +Kein `--accept-routes` nötig — anders als CT 102 sitzt dieser Container nicht zusätzlich im ``-LAN in einer Weise, die einen Routing-Konflikt erzeugen würde (Netz-Interface ist zwar auf dem LAN, aber der Dienst wird ausschließlich über die Tailscale-IP angesprochen). + +Voraussetzung in der Tailscale-Admin-Konsole: **Settings → DNS → „HTTPS Certificates"** muss aktiviert sein (einmalig für den ganzen Tailnet, siehe `01-pve-host.md`). + +## 5. Vaultwarden via Docker Compose + +```bash +mkdir -p /opt/vaultwarden/data +ADMIN_TOKEN=$(openssl rand -base64 48 | tr -d '\n') + +cat > /opt/vaultwarden/docker-compose.yml <" + ADMIN_TOKEN: "$ADMIN_TOKEN" + SIGNUPS_ALLOWED: "true" + WEBSOCKET_ENABLED: "true" + volumes: + - ./data:/data + ports: + - "127.0.0.1:8080:80" +EOF + +cd /opt/vaultwarden && docker compose up -d +``` + +`SIGNUPS_ALLOWED` bewusst zuerst `true`, um das/die Konto(s) anzulegen. **Nach der Konto-Anlage zwingend zurückstellen:** +```bash +sed -i 's/SIGNUPS_ALLOWED: "true"/SIGNUPS_ALLOWED: "false"/' /opt/vaultwarden/docker-compose.yml +cd /opt/vaultwarden && docker compose up -d +``` + +## 6. HTTPS-Exposition via `tailscale serve` (kein Caddy, kein manuelles Zertifikat) + +```bash +tailscale serve --bg http://127.0.0.1:8080 +``` + +Erreichbar unter `https://vaultwarden.`, automatisch gültiges Let's-Encrypt-Zertifikat, automatische Erneuerung, **nicht öffentlich** (nur Tailnet-Mitglieder). + +⚠️ **NICHT TUN:** `tailscale serve --bg https / http://...` (alte Syntax). Neuere Tailscale-CLI-Versionen erwarten nur noch `tailscale serve --bg http://127.0.0.1:8080` (HTTPS wird automatisch angenommen). + +⚠️ **NICHT TUN:** Vaultwarden zusätzlich über Caddy auf dem VPS öffentlich exponieren (wie bei Guacamole). Bewusste Entscheidung: der Passwort-Tresor ist der sensibelste Dienst im gesamten Setup, öffentliche Erreichbarkeit erhöht die Angriffsfläche unnötig — der Internetcafé-Fall wird stattdessen über Guacamole selbst abgedeckt (SFTP/RDP-Zugriff auf andere Dienste, nicht direkt auf den Tresor). + +## 7. Konto-Anlage (manueller Web-Schritt, nicht per CLI) + +Über `https://vaultwarden.` (nur von einem Tailnet-Mitglied aus erreichbar) im Browser ein Konto mit **selbst gewähltem Master-Passwort** anlegen. Das Master-Passwort wird bewusst **nie** programmatisch gesetzt oder irgendwo notiert — es ist der einzige Schlüssel zum gesamten Tresor. + +## Bekannte Stolpersteine (bereits behoben, hier nur als Hinweis) + +* Beim Passwort-Import versehentlich Duplikate erzeugt (zweimal importiert) → behoben durch: alle Einträge auswählen → löschen → Papierkorb leeren → sauber neu importieren. + +## Verifikation + +```bash +curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/ # lokal, im Container +curl -s -o /dev/null -w "%{http_code}\n" https://vaultwarden./ # von einem Tailnet-Mitglied +tailscale serve status +```