116 lines
4.4 KiB
Markdown
116 lines
4.4 KiB
Markdown
|
|
# 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=<LAN_IP_VAULTWARDEN>/24,gw=<LAN_IP_ROUTER> \
|
||
|
|
--features nesting=1 \
|
||
|
|
--timezone Europe/Berlin \
|
||
|
|
--onboot 1 \
|
||
|
|
--nameserver <LAN_IP_ADGUARD>
|
||
|
|
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=<AUTH_KEY> --hostname=vaultwarden
|
||
|
|
```
|
||
|
|
|
||
|
|
Kein `--accept-routes` nötig — anders als CT 102 sitzt dieser Container nicht zusätzlich im `<LAN_SUBNET>`-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 <<EOF
|
||
|
|
services:
|
||
|
|
vaultwarden:
|
||
|
|
image: vaultwarden/server:latest
|
||
|
|
container_name: vaultwarden
|
||
|
|
restart: unless-stopped
|
||
|
|
logging:
|
||
|
|
driver: json-file
|
||
|
|
options:
|
||
|
|
max-size: "10m"
|
||
|
|
max-file: "3"
|
||
|
|
environment:
|
||
|
|
DOMAIN: "https://vaultwarden.<TAILNET>"
|
||
|
|
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.<TAILNET>`, 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.<TAILNET>` (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.<TAILNET>/ # von einem Tailnet-Mitglied
|
||
|
|
tailscale serve status
|
||
|
|
```
|