11 KiB
📝 Kapitel 6 – Vaultwarden (ohne Docker, systemd)
Blog‑Stil, laienfreundlich, Schritt‑für‑Schritt nachvollziehbar. Du führst die Befehle aus und ersetzt die Platzhalter. Nach jedem Block steht kurz: was, warum, Erfolgskontrolle. Wenn relevant, nennen wir Alternativen.
🎯 Was wir bauen (in Klartext)
Wir richten Vaultwarden als Passwort‑Tresor ein. Das ist die kompatible Server‑Variante zu Bitwarden. Du bekommst:
- eine Web‑Oberfläche zum Verwalten deiner Passwörter und TOTP‑Codes,
- sichere Anmeldung (Admin‑Token, Registrierungen aus),
- HTTPS über den Nginx Proxy Manager (NPM) und
- Live‑Sync dank WebSockets.
Wir betreiben Vaultwarden ohne Docker (direkt als Programm), damit es möglichst wenig RAM verbraucht.
✅ Voraussetzungen (kurz & klar)
- LXC‑Container: Debian 12 (Bookworm), du bist als root angemeldet.
- NPM läuft (eigenes Kapitel), Domain existiert (z. B.
pass.DEINE-DOMAIN.tld). - Die IP deines Vaultwarden‑LXC (Beispiel:
10.0.0.16).
Platzhalter, die du gleich ersetzt:
<VW_IP>→ IP deines Vaultwarden‑LXC, z. B.10.0.0.16DEINE-DOMAIN.tld→ deine echte Domain
🧱 LXC‑Eigenschaften (Proxmox) — empfohlene Einstellungen
Empfehlung (GUI). So erstellst du den Container für dieses Kapitel; Details kannst du später anpassen.
Proxmox GUI → Create CT
-
General
- Hostname:
vaultwarden - Unprivileged container: ✔️ aktivieren (besserer Schutz)
- Root‑Passwort: setzen
- Optional SSH Public Key einfügen (falls vorhanden)
- Hostname:
-
Template
- OS:
Debian 12 (Bookworm) – standard
- OS:
-
Disks
- Storage:
local-lvm(oder dein Standard‑Storage) - Disk size: 4 GB (reicht, Daten liegen separat; später erweiterbar)
- Storage:
-
CPU
- Cores: 1
-
Memory
- RAM: 256 MB
- Swap: 256 MB
-
Network
- Bridge:
vmbr0 - IPv4: Static → z. B.
<VW_IP>/24(Beispiel10.0.0.16/24) - Gateway (IPv4): z. B.
10.0.0.1 - IPv6:
SLAAC (Auto)oderNone(wenn dein Netz kein IPv6 nutzt)
- Bridge:
-
DNS
- DNS server: IP deines DNS (z. B. Pi‑hole) oder
1.1.1.1 - Search domain: leer lassen (optional dein LAN‑Suffix)
- DNS server: IP deines DNS (z. B. Pi‑hole) oder
-
Confirm
- Start at boot (Onboot): ✔️ aktivieren
- Finish
Nach der Erstellung (Optionen anpassen):
- Options → Features:
keyctl=on,nesting=off,fuse=off - Start den CT und öffne Console → einloggen als
root(Passwort aus Schritt 1)
Warum diese Werte?
- Unprivileged reduziert Angriffsfläche.
- 1 vCPU / 256 MB RAM: reicht für Vaultwarden nativ (sparsam).
- 4 GB Disk: System + Logs; Tresor‑Daten liegen unter
/var/lib/vaultwarden.- SLAAC nur, wenn du IPv6 nutzt; sonst
None.
1) System vorbereiten
Wir aktualisieren das System, installieren Werkzeuge und richten einen eigenen Dienst‑Benutzer ein.
Warum ein eigener Dienst‑Benutzer? Dieser Benutzer ist nur für den Vaultwarden‑Dienst da (kein normales Login). Dadurch sind die Tresor‑Dateien vor anderen Diensten geschützt. In früheren Docker‑Kapiteln war diese Trennung im Container bereits vorhanden – jetzt übernehmen wir sie auf Systemebene.
apt update && apt upgrade -y
apt install -y ca-certificates curl unzip openssl nano
# Dienstnutzer ohne Login anlegen (nur für den Dienst, zur Absicherung)
useradd --system --home /var/lib/vaultwarden --shell /usr/sbin/nologin vaultwarden || true
# Arbeits- und Datenordner anlegen
mkdir -p /opt/vaultwarden
mkdir -p /var/lib/vaultwarden/data
# Eigentum der Daten an den Dienstbenutzer übergeben (Schutz der Tresor-Daten)
chown -R vaultwarden:vaultwarden /var/lib/vaultwarden
So prüfst du das Ergebnis:
id vaultwarden
ls -ld /opt/vaultwarden /var/lib/vaultwarden /var/lib/vaultwarden/data
Du siehst den Benutzer vaultwarden und die Ordner existieren.
2) Vaultwarden herunterladen (immer aktuelle stabile Version)
Wir installieren immer die neuste stabile Release direkt von der offiziellen Quelle. So sind Sicherheitsfixes sofort enthalten.
# 1) Download-URL der neuesten stabilen Release automatisch ermitteln
VW_URL=$(curl -s https://api.github.com/repos/dani-garcia/vaultwarden/releases/latest \
| grep browser_download_url \
| grep x86_64-unknown-linux-gnu.tar.gz \
| cut -d '"' -f 4)
# 2) Archiv herunterladen und entpacken
curl -L "$VW_URL" -o /tmp/vaultwarden.tar.gz
mkdir -p /tmp/vw && tar -xzf /tmp/vaultwarden.tar.gz -C /tmp/vw
# 3) Programmdatei nach /opt verschieben (wird unser fester Pfad)
install -m 0755 /tmp/vw/vaultwarden /opt/vaultwarden/vaultwarden
Woran erkenne ich Erfolg?
/opt/vaultwarden/vaultwarden --version || true
Du siehst die Version der frisch installierten Release.
Warum so? (Laienfreundlich)
- „Neuste stabile Release“ = aktuelle Sicherheitsfixes ohne Wartezeit.
- Wir holen die Datei direkt von der offiziellen Projektseite.
- Der Pfad
/opt/vaultwarden/bleibt gleich – Updates sind später nur „Datei tauschen + Dienst neu starten“.
🔐 Sicherheits‑Hinweis: Wenn die Release‑Seite einen SHA256‑Wert angibt, kannst du ihn optional prüfen:
sha256sum /tmp/vaultwarden.tar.gzausführen und den Wert mit dem auf der Release‑Seite visuell vergleichen.
🆙 Aktualisieren später: Wiederhole genau diesen Schritt (die drei Befehle oben) und starte den Dienst neu:
systemctl restart vaultwarden. Wenn sich seitdem Oberflächen/Optionen geändert haben, ergänzen wir im Video einen Hinweis und aktualisieren diesen Blog‑Post.
3) Konfigurationsdatei mit Nano erstellen
Wir hinterlegen Domain, Admin‑Token, Ports und WebSockets in einer .env‑Datei. Diese Datei liest der Dienst später automatisch ein.
- Sicheres Admin‑Token erzeugen (kopieren, wir fügen es gleich ein):
openssl rand -base64 48
- Datei mit Nano öffnen:
nano /etc/vaultwarden.env
- Folgenden Inhalt einfügen und Platzhalter ersetzen:
DOMAIN=https://pass.DEINE-DOMAIN.tld
ADMIN_TOKEN=HIER_DEIN_ERZEUGTES_TOKEN_EINFÜGEN
SIGNUPS_ALLOWED=false
WEBSOCKET_ENABLED=true
# Der Dienst lauscht auf der IP deines LXC (so erreicht NPM ihn)
ROCKET_ADDRESS=<VW_IP>
ROCKET_PORT=8000
# WebSocket-Endpunkt für Live-Sync
WEBSOCKET_ADDRESS=<VW_IP>
WEBSOCKET_PORT=3012
# Optional: nur wenn du E-Mails (z. B. Verifizierung/Reset) willst
# SMTP_HOST=smtp.example.com
# SMTP_FROM=pass@example.com
# SMTP_PORT=587
# SMTP_SECURITY=starttls
# SMTP_USERNAME=user
# SMTP_PASSWORD=deinPasswort
- Speichern in Nano:
Strg+O→Enter→ Beenden:Strg+X. - Datei schützen (damit nur root und der Dienst lesen dürfen):
chown root:vaultwarden /etc/vaultwarden.env
chmod 0640 /etc/vaultwarden.env
Kurz erklärt:
DOMAINbraucht https, damit Links/Icons korrekt sind.ADMIN_TOKENschützt das Admin‑Backend (ohne Token kommt man nicht rein).SIGNUPS_ALLOWED=falseverhindert offene Registrierungen.ROCKET_*undWEBSOCKET_*sorgen dafür, dass der Dienst auf deiner LXC‑IP erreichbar ist und Live‑Sync funktioniert.
4) Dienstdatei (systemd) anlegen
Die Dienstdatei sagt Linux: „So startest du Vaultwarden – und bitte automatisch beim Booten.“
- Datei öffnen:
nano /etc/systemd/system/vaultwarden.service
- Inhalt einfügen:
[Unit]
Description=Vaultwarden (Bitwarden-compatible) – native
After=network.target
[Service]
User=vaultwarden
Group=vaultwarden
EnvironmentFile=/etc/vaultwarden.env
ExecStart=/opt/vaultwarden/vaultwarden
WorkingDirectory=/var/lib/vaultwarden
# Sicherheit (Dienst hat nur, was er braucht)
LimitNOFILE=1048576
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
- Speichern & schließen:
Strg+O→Enter→Strg+X. - Dienst laden, aktivieren und starten:
systemctl daemon-reload
systemctl enable --now vaultwarden
systemctl status vaultwarden --no-pager
Woran erkenne ich Erfolg?
- Status zeigt active (running).
- Optional: Ports prüfen
ss -tulpn | grep -E ':8000|:3012'
Was haben wir gerade gemacht?
- Den Dienst systemweit registriert und dauerhaft aktiviert.
- Vaultwarden läuft jetzt im Hintergrund – automatisch auch nach Neustarts.
5) NPM einrichten (Proxy, WebSockets, Zertifikat)
So wird deine Instanz über HTTPS erreichbar und Live‑Sync funktioniert.
-
Proxy Host anlegen
- Domain Names:
pass.DEINE-DOMAIN.tld - Scheme:
http - Forward Hostname / IP:
<VW_IP> - Forward Port:
8000 - Block Common Exploits: ✔️
- Websockets Support: ✔️
- Domain Names:
-
Custom Location hinzufügen
- Location:
/notifications/hub - Forward Hostname / IP:
<VW_IP> - Forward Port:
3012 - Websockets Support: ✔️
- Location:
-
SSL aktivieren (Let’s Encrypt)
- Request a new SSL Certificate
- Force SSL, HTTP/2, HSTS: ✔️
Test: Rufe https://pass.DEINE-DOMAIN.tld im Browser auf → Loginseite sichtbar.
Was passiert hier?
- NPM nimmt Anfragen aus dem Internet an (443) und leitet sie an deinen Dienst weiter.
- Die Custom Location sorgt dafür, dass der WebSocket‑Kanal (Live‑Sync) funktioniert.
6) Erstkonfiguration im Browser
- Admin‑Backend öffnen:
https://pass.DEINE-DOMAIN.tld/admin→ Admin‑Token eingeben. - Registrierung prüfen: „Signups allowed“ ist aus (kommt aus deiner
.env). - Optional SMTP eintragen und Testmail senden.
- Erstes Benutzerkonto anlegen und 2FA (TOTP oder FIDO2) aktivieren.
Warum?
- So bleibt der Server privat (nur du legst Accounts an).
- 2FA schützt deinen Tresor zusätzlich.
7) Backup (Basis, schnell & sicher)
Wir sichern den Datenordner. Damit kannst du den Tresor später wiederherstellen.
# Für maximale Konsistenz könntest du kurz stoppen (optional)
# systemctl stop vaultwarden
tar -czf /root/vaultwarden-backup-$(date +%F).tar.gz -C /var/lib vaultwarden
# systemctl start vaultwarden
ls -lh /root/vaultwarden-backup-*.tar.gz
Wichtig: Plane das als Cron‑Job ein und teste gelegentlich das Restore auf einer Test‑VM.
🛠️ Wenn etwas nicht klappt
-
Seite lädt, aber kein Live‑Sync: In NPM die Custom Location
/notifications/hubprüfen (Port 3012, WebSockets ✔️). -
Icons/Links seltsam: In
/etc/vaultwarden.envmussDOMAINmit https beginnen. -
Ich komme nicht ins Admin‑Backend: Stimmt das ADMIN_TOKEN noch? (Zur Not neues Token in der
.envsetzen undsystemctl restart vaultwarden.) -
Dienst startet nicht:
journalctl -u vaultwarden -b --no-pager | tail -n 50Die letzten Zeilen zeigen meistens den Fehler (z. B. Tippfehler in der
.env).
✅ Ergebnis
- Deine Instanz ist über
https://pass.DEINE-DOMAIN.tlderreichbar. - Registrierungen sind aus, Admin‑Backend ist durch Token geschützt.
- WebSockets funktionieren (Live‑Sync zwischen Geräten).
- Backups sind eingerichtet.
Du hast jetzt einen schlanken, eigenen Passwort‑Server – ohne Docker‑Overhead, mit klaren Sicherungen und Updates.