Vaultwarden einrichten: Eigener Passwortmanager mit Docker, sicher in 30 Minuten (2026)

Vaultwarden einrichten: Eigener Passwortmanager mit Docker, sicher in 30 Minuten (2026)

Vaultwarden einrichten dauert mit Docker keine halbe Stunde. Vaultwarden ist ein schlanker, in Rust geschriebener Server, der die Schnittstelle von Bitwarden nachbaut. Du betreibst ihn selbst und benutzt trotzdem die ganz normalen Bitwarden-Apps auf Handy, Desktop und im Browser. Deine Passwörter liegen damit auf deinem eigenen Server statt bei einem Anbieter, und das Ganze kostet dich nichts außer dem Server, den du vielleicht ohnehin schon hast.

Der Haken: Die meisten Anleitungen hören nach docker run auf. Genau danach fangen die interessanten Fragen an. Wir haben deshalb am 31. Oktober 2026 auf unserem eigenen Server einen frischen Vaultwarden 1.37.4 (das aktuelle Release vom 5. Oktober 2026) in einem Wegwerf-Container aufgesetzt und gezielt versucht, ihn kaputtzumachen. Vier Befunde vorweg:

1. Ab Werk darf sich jeder registrieren, der deine Adresse kennt. Ein frei erfundenes Konto war in 0,57 Sekunden angelegt und eingeloggt.

2. Die eingebaute Login-Sperre greift nach 10 Fehlversuchen. Mit einem gefälschten X-Real-IP-Header haben wir sie trotzdem 30 von 30 Mal umgangen, direkt und auch hinter einem Caddy mit Standardkonfiguration.

3. Wer den sicheren Argon2-Admin-Token ohne Escaping in die compose.yaml schreibt, bekommt ein verstümmeltes Klartext-Passwort. Das echte Passwort lehnt Vaultwarden dann ab, die verstümmelte Zeichenkette öffnet das Admin-Panel.

4. Eine config.json im Datenordner schlägt deine Umgebungsvariablen. Trotz SIGNUPS_ALLOWED=false konnten wir uns wieder registrieren.

Alle vier lassen sich mit je einer Zeile beheben. Unten steht die komplette, getestete Konfiguration.

Ein leuchtender Tresor in einem kleinen Server, umkreist von verschlüsselten Schlüsseln

Was ist Vaultwarden, und was ist der Unterschied zu Bitwarden?

Bitwarden ist ein Open-Source-Passwortmanager mit Apps für alle Plattformen. Den offiziellen Bitwarden-Server kann man auch selbst hosten, er besteht aber aus einem guten Dutzend Containern mit .NET und Microsoft SQL Server und will entsprechend Arbeitsspeicher. Vaultwarden ist eine unabhängige Neuimplementierung derselben Schnittstelle in Rust. Ein einziger Container, SQLite als Standard-Datenbank, fertig.

Bitwarden (offiziell, selbst gehostet)Vaultwarden
EntwicklerBitwarden Inc.Community-Projekt (dani-garcia/vaultwarden)
SpracheC# / .NETRust
Containerviele (API, Identity, Web, DB, …)einer
DatenbankMS SQL ServerSQLite, optional MySQL/MariaDB oder PostgreSQL
RAM im Leerlaufmehrere GB empfohlen7,9 MB in unserer Messung
Organisationen, Sends, Notfallzugriffja, Teile kostenpflichtigja, ohne Lizenz
Offizieller Supportjanein, Community
ClientsBitwarden-Appsdieselben Bitwarden-Apps

Die 7,9 MB sind kein Tippfehler. Unser frischer Container brauchte nach dem Start laut docker stats 7,898 MiB Arbeitsspeicher, vom Start bis zur ersten Antwort auf /alive vergingen 0,6 Sekunden. Das Image selbst ist mit 402 MB deutlich größer, das liegt vor allem am mitgelieferten Web-Tresor (in 1.37.4 die Web-Vault-Version 2026.7.0). Vaultwarden läuft damit problemlos auf dem kleinsten VPS, einem Raspberry Pi oder neben vielen anderen Diensten. Wie viel Speicher ein Server sonst so braucht, haben wir in Wie viel RAM braucht ein Server? gemessen.

Wichtig für die Einordnung: Vaultwarden ist kein Produkt von Bitwarden Inc. Fehler meldest du beim Vaultwarden-Projekt, nicht bei Bitwarden. Das sagt Vaultwarden beim Start auch selbst in einem großen Kasten im Log.

Ist Vaultwarden sicher? Was der Server überhaupt sieht

Die wichtigste Eigenschaft hat nichts mit Vaultwarden zu tun, sondern mit dem Bitwarden-Protokoll: Verschlüsselt wird auf deinem Gerät, nicht auf dem Server. Dein Master-Passwort verlässt den Client nie. Aus Master-Passwort und E-Mail-Adresse leitet die App per PBKDF2 (Standard: 600.000 Runden) einen Schlüssel ab. Damit wird ein zufälliger Tresorschlüssel verpackt, und mit dem wiederum jeder einzelne Eintrag. Zum Server geht nur ein abgeleiteter Hash fürs Login und der fertig verschlüsselte Datensalat.

Wir haben das nicht einfach geglaubt, sondern nachgeprüft. Mit einem kleinen Python-Skript haben wir den Client nachgebaut, ein Konto angelegt und einen Eintrag „Online-Banking“ mit Benutzer max.muster und Passwort Geheim-Passwort-123 gespeichert. Danach haben wir die SQLite-Datei des Servers samt WAL-Datei durchsucht:

grep -c "Geheim-Passwort-123\|max.muster\|Online-Banking\|bank.example" data/db.sqlite3*
# data/db.sqlite3:0
# data/db.sqlite3-shm:0
# data/db.sqlite3-wal:0

Null Treffer. In der Tabelle ciphers steht nur so etwas:

2.jwsJMnMtTGhfDHviPF0gAw==|M8sUtYaq6eGcvDAyPaeHiQ=|...

Das 2. steht für AES-256-CBC mit HMAC-SHA256, danach folgen Initialisierungsvektor, Geheimtext und Prüfsumme. Selbst wer deine komplette Datenbank klaut, hat erst einmal nur das. Er muss dann dein Master-Passwort offline erraten, und jeder Rateversuch kostet 600.000 PBKDF2-Runden. Auf unserem Server dauerte eine einzige Ableitung 125 Millisekunden. Spezialisierte Hardware ist zwar viel schneller, aber bei einem langen Master-Passwort hilft das wenig.

Ein Laptop verpackt einen goldenen Schlüssel in eine versiegelte Kapsel, der Server speichert nur die Kapsel

Was der Server trotzdem weiß: deine E-Mail-Adresse, wann du dich einloggst, von welcher IP, wie viele Einträge du hast und welche Geräte verbunden sind. Und es gibt eine Lücke, die kein Protokoll schließt: Wer deinen Server übernimmt, kann dir einen manipulierten Web-Tresor ausliefern, der dein Master-Passwort beim Tippen mitschneidet. Die Apps auf Handy und Desktop sind davon nicht betroffen, weil ihr Code aus dem App-Store kommt. Daraus folgt eine schlichte Regel: Für den Alltag die Apps oder die Browser-Erweiterung nutzen, den Web-Tresor nur, wenn es sein muss.

Ist Vaultwarden also sicher? Die Kryptografie ist dieselbe wie bei Bitwarden. Die Sicherheit deines Servers ist dagegen jetzt deine Aufgabe. Genau darum geht es im Rest dieses Artikels.

Voraussetzungen zum Vaultwarden einrichten

  • Ein Linux-Server mit Docker und Docker Compose. Ein kleiner VPS reicht. Falls du noch keinen hast: Linux-Server einrichten und Was ist Docker?.
  • Eine (Sub-)Domain, zum Beispiel vault.deinedomain.de, mit A-Record auf den Server.
  • HTTPS. Das ist keine Kür. Der Web-Tresor nutzt die Krypto-Schnittstelle des Browsers, und die gibt es nur in einem sicheren Kontext, also über HTTPS oder auf localhost. Was HTTPS genau leistet, erklären wir in Was ist HTTPS?.
  • Einen Reverse Proxy, der das Zertifikat holt. Wir nehmen Caddy, weil er Zertifikate automatisch besorgt. Nginx geht genauso, siehe Caddy vs. Nginx.

Wenn du Vaultwarden gar nicht ins Internet stellen willst, ist das übrigens eine sehr gute Idee. Dazu weiter unten mehr.

Schritt 1: Vaultwarden mit Docker Compose starten

Leg einen Ordner an, zum Beispiel /opt/vaultwarden, und darin eine compose.yaml. Das ist die Fassung, die wir am Ende getestet haben:

services:
  vaultwarden:
    image: vaultwarden/server:1.37.4
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      DOMAIN: "https://vault.deinedomain.de"
      SIGNUPS_ALLOWED: "false"
      ADMIN_TOKEN: '$$argon2id$$v=19$$m=65540,t=3,p=4$$...'   # Erklärung in Schritt 4
    volumes:
      - ./data:/data
    ports:
      - "127.0.0.1:8080:80"

Vier Details, die wichtiger sind, als sie aussehen:

  1. Feste Version statt latest. Dann entscheidest du, wann ein Update kommt, und kannst vorher ein Backup ziehen.
  2. 127.0.0.1:8080:80 statt 8080:80. Ohne die IP davor ist Vaultwarden direkt aus dem Internet erreichbar, an deinem Reverse Proxy vorbei. Docker trägt seine Portfreigaben dabei an der Firewall vorbei ein, eine ufw-Regel schützt dich hier nicht. Hintergrund in UFW-Firewall einrichten.
  3. DOMAIN muss exakt die Adresse sein, unter der du Vaultwarden aufrufst, mit https://. Sonst passen Links in E-Mails und einige Anmeldeverfahren nicht.
  4. Ein Port reicht. Früher brauchte Vaultwarden für Live-Synchronisation einen zweiten Port 3012. Seit Version 1.29 laufen die WebSockets über denselben Port. Wir haben das geprüft: /notifications/hub antwortet auf Port 80 (ohne gültigen Token mit 401, wie es sein soll). Viele ältere Anleitungen zeigen noch den zweiten Port.

Dann:

docker compose up -d
docker compose logs -f

Im Log sollte Rocket has launched from http://0.0.0.0:80 stehen. Mehr zum Aufbau solcher Dateien findest du in unserem Docker-Compose-Beispiel.

Schritt 2: HTTPS mit Caddy und die versteckte Falle bei der Login-Sperre

Die naheliegende Caddy-Konfiguration ist drei Zeilen lang:

vault.deinedomain.de {
    reverse_proxy 127.0.0.1:8080
}

Caddy holt das Zertifikat selbst, HTTPS steht. Genau diese Konfiguration hat in unserem Test aber ein Problem, und das hat mit der Login-Sperre zu tun.

Wie die Login-Sperre funktioniert

Vaultwarden hat einen eingebauten Bremsklotz gegen das Durchprobieren von Passwörtern. Standardmäßig sind 10 Versuche am Stück erlaubt, danach ein weiterer pro 60 Sekunden. Wir haben das gemessen: 30 falsche Logins hintereinander ergaben 10× „falsches Passwort“ und 20× HTTP 429 „Too many login requests“. Auch sieben Sekunden später war noch gesperrt. So weit, so gut.

Aber woher weiß Vaultwarden, von welcher IP ein Versuch kommt? Es liest standardmäßig den HTTP-Header X-Real-IP. Den setzt normalerweise der Reverse Proxy. Nur: Den kann auch der Angreifer selbst mitschicken.

Der Test: 30 Versuche, 30 Mal durchgelassen

Wir haben 30 falsche Logins geschickt und bei jedem einen anderen erfundenen X-Real-IP-Header mitgegeben (10.0.0.0, 10.0.0.1, …):

AufbauHeader gefälscht?Ergebnis bei 30 Versuchen
Direkt auf Vaultwardennein10× abgelehnt, 20× gesperrt
Direkt auf Vaultwardenja30× abgelehnt, 0× gesperrt
Hinter Caddy, Standard-Confignein10× abgelehnt, 20× gesperrt
Hinter Caddy, Standard-Configja30× abgelehnt, 0× gesperrt
Hinter Caddy mit header_upja10× abgelehnt, 20× gesperrt

Caddy reicht den mitgeschickten X-Real-IP des Clients unverändert durch. Vaultwarden glaubt ihn, und jeder Versuch kommt scheinbar von einer neuen IP. Im Vaultwarden-Log stehen dann brav die erfundenen Adressen:

Username or password is incorrect. Try again. IP: 10.0.0.29. Username: fremder@example.com.

Das heißt: Die Sperre ist ausgehebelt, und wer fail2ban auf dieses Log ansetzt, sperrt bestenfalls Fantasieadressen.

Und es gibt die Kehrseite. Ohne gefälschten Header hat Vaultwarden hinter Docker bei uns alle Anfragen derselben Adresse zugeordnet, nämlich dem Docker-Gateway 172.17.0.1. Die Sperre gilt dann für alle gleichzeitig. Wir haben es ausprobiert: Nach zwölf falschen Versuchen eines „Angreifers“ wurde auch das richtige Passwort des echten Nutzers mit 429 abgewiesen. Ein einzelner Störer sperrt also alle aus.

Der Fix: eine Zeile

vault.deinedomain.de {
    reverse_proxy 127.0.0.1:8080 {
        header_up X-Real-IP {remote_host}
    }
}

header_up überschreibt den Header mit der Adresse, die Caddy tatsächlich sieht. Mit dieser Zeile griff die Sperre auch bei gefälschtem Header wieder nach zehn Versuchen, und im Log stand die echte Adresse. Bei Nginx ist das Gegenstück:

proxy_set_header X-Real-IP $remote_addr;

Liegt vor deinem Proxy noch ein CDN wie Cloudflare, ist {remote_host} die Adresse des CDN. Dann musst du dem Proxy sagen, welchen Header er von welchen Adressen glauben darf (bei Caddy über trusted_proxies). Wie Reverse Proxys grundsätzlich mit solchen Headern umgehen, steht in Was ist ein Reverse Proxy?.

Ein Schutzschild vor einem Server, ein gefälschter Ausweis wird abgewiesen

Schritt 3: Konto anlegen und dann sofort die Registrierung schließen

Jetzt rufst du https://vault.deinedomain.de auf und legst dein Konto an. Dafür muss die Registrierung kurz offen sein. In unserer Compose-Datei oben steht schon SIGNUPS_ALLOWED: "false". Für den allerersten Start setzt du es also entweder kurz auf "true" oder lädst dich über das Admin-Panel selbst ein (dafür braucht Vaultwarden einen funktionierenden Mailversand per SMTP).

Warum das so wichtig ist

Ohne diese Variable ist die Registrierung offen. Wir haben das an einem frischen Container ausprobiert. Unser Skript hat sich als fremder@example.com registriert, mit 600.000 PBKDF2-Runden und frisch erzeugtem RSA-Schlüssel, und sich danach eingeloggt. Gesamtdauer: 0,57 Sekunden, Antwort registerFinish, danach Login mit HTTP 200. Kein Captcha und keine E-Mail-Bestätigung: Ohne konfigurierten Mailversand liefert Vaultwarden den „Bestätigungs“-Token bei der Registrierung direkt in der Antwort mit.

Ein Fremder kann deine Passwörter so nicht lesen, sie sind ja verschlüsselt. Aber er kann deinen Server als kostenlosen Speicher benutzen: Einträge, Anhänge und Sends (verschlüsselte Datei-Links zum Teilen) auf deine Kosten, auf deiner Domain und unter deiner IP. Das will niemand.

Mit SIGNUPS_ALLOWED=false bekam derselbe Versuch:

400 Registration not allowed or user already exists

Bestehende Konten konnten sich dabei ganz normal einloggen (HTTP 200).

Weitere Leute holst du später über das Admin-Panel per Einladung dazu. Oder du erlaubst gezielt nur deine eigene Domain mit SIGNUPS_DOMAINS_WHITELIST=deinedomain.de.

Eine offene Tresortür, durch die eine fremde Silhouette geht

Schritt 4: Das Admin-Panel sicher aktivieren (und die Dollar-Falle)

Ohne ADMIN_TOKEN ist das Admin-Panel unter /admin abgeschaltet. Vaultwarden zeigt dann nur: „admin panel is disabled, please configure the ‘ADMIN_TOKEN’ variable to enable it“. Das ist ein sehr vernünftiger Standard. Du brauchst das Panel für Einladungen, um Nutzer zu deaktivieren, für Diagnosen und um Einstellungen zu ändern. Wenn du es nicht brauchst, lass es aus.

Willst du es nutzen, dann nicht mit Klartext-Passwort. Vaultwarden kann sich einen Argon2id-Hash erzeugen:

docker exec -it vaultwarden /vaultwarden hash

Das -it ist Pflicht. Ohne Terminal stürzte der Befehl bei uns mit No such device or address ab, weil er das Passwort interaktiv abfragt. Mit Terminal dauerte die Erzeugung 131 Millisekunden (Voreinstellung „bitwarden“: 64 MiB Speicher, 3 Durchläufe, 4 Threads; alternativ --preset owasp mit 19 MiB). Heraus kommt etwas wie:

ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$NZxGeP...$ZLj9BE...'

Die Falle: Docker Compose frisst die Dollarzeichen

Kopierst du diesen Wert so in die compose.yaml, behandelt Docker Compose jedes $... als Variable. Bei uns gab docker compose config fünf Warnungen aus (The "argon2id" variable is not set. Defaulting to a blank string.), und im Container kam statt des Hashes an:

=19=65540,t=3,p=4/0v3Gldw+9dLkdKE

Vaultwarden erkennt darin keinen Hash mehr und behandelt die Zeichenkette als Klartext-Passwort. Die Folgen haben wir durchgespielt:

  • Im Log steht nur ein unscheinbares [NOTICE] You are using a plain text ADMIN_TOKEN which is insecure.
  • Dein echtes Admin-Passwort wird mit 401 abgelehnt. Du denkst, du hast dich vertippt.
  • Die verstümmelte Zeichenkette dagegen öffnet das Admin-Panel (HTTP 200 plus Sitzungs-Cookie).

Sicherheitslücke ist das keine große, die Zeichenkette ist immer noch lang und zufällig. Aber du hast kein Hash-Passwort mehr, sondern ein Klartext-Passwort, das dir niemand gesagt hat. Die Lösung: Jedes $ verdoppeln.

ADMIN_TOKEN: '$$argon2id$$v=19$$m=65540,t=3,p=4$$NZxGeP...$$ZLj9BE...'

Damit: keine Warnung, der Hash kommt exakt an (wir haben ihn im Container mit dem Original verglichen), kein Klartext-Hinweis mehr im Log, das echte Passwort ergibt 200, ein falsches 401. Alternativ legst du den Wert in eine .env-Datei neben der Compose-Datei. Auch dort gilt die Ersetzung, also auch dort $$ verwenden oder den Wert in einfache Anführungszeichen setzen. Prüfen kannst du es immer mit:

docker compose config | grep ADMIN_TOKEN
docker logs vaultwarden 2>&1 | grep -i "plain text"

Kommt beim zweiten Befehl etwas zurück, stimmt etwas nicht.

Die config.json: Warum das Admin-Panel deine Compose-Datei überstimmt

Speicherst du im Admin-Panel eine Einstellung, legt Vaultwarden eine Datei data/config.json an. Werte darin haben Vorrang vor Umgebungsvariablen. Wir haben das geprüft: Mit SIGNUPS_ALLOWED=false in der Compose-Datei, aber {"signups_allowed": true} in der config.json, gelang die Registrierung eines neuen Kontos wieder mit 200. Gleichzeitig meldete docker exec vaultwarden printenv SIGNUPS_ALLOWED immer noch false.

Wer also seine Compose-Datei liest und sich sicher fühlt, liest unter Umständen die falsche Datei. Zwei saubere Wege:

  • Entweder alles über Umgebungsvariablen und das Admin-Panel nur zum Anschauen, Einladen und Deaktivieren nutzen. Taucht trotzdem eine config.json auf, weißt du, dass jemand dort etwas gespeichert hat.
  • Oder bewusst das Admin-Panel als Quelle der Wahrheit nehmen. Dann gehört die config.json unbedingt mit ins Backup.

Schritt 5: Backup, Wiederherstellung und was du dabei nie vergessen darfst

Ein Passwortmanager ohne getestetes Backup ist ein Risiko mit Benutzeroberfläche. Gut ist: Der Datenordner ist winzig. Unser Testtresor mit zwei Konten belegte 604 KB.

Was in data/ liegt

Datei/OrdnerInhaltIns Backup?
db.sqlite3 (+ -wal, -shm)Konten, Einträge, Ordner, Organisationenja, aber richtig kopieren
rsa_key.pemSchlüssel, mit dem Vaultwarden Login-Tokens signiertja
attachments/verschlüsselte Dateianhängeja
sends/verschlüsselte Send-Dateienja
config.jsonEinstellungen aus dem Admin-Panelja, falls vorhanden
icon_cache/zwischengespeicherte Website-Iconsnein

Die Datenbank richtig sichern

Eine laufende SQLite-Datenbank einfach mit cp zu kopieren, ist riskant. Ein Teil der Änderungen kann in der WAL-Datei liegen, und du erwischst womöglich einen halben Schreibvorgang. Vaultwarden bringt dafür seit einiger Zeit einen eigenen Befehl mit:

docker exec vaultwarden /vaultwarden backup
# Backup to 'data/db_20261031_080507.sqlite3' was successful

Das dauerte bei uns 0,08 Sekunden. sqlite3 … "pragma integrity_check" meldete ok, beide Konten und der Eintrag waren drin. Alternativ geht sqlite3 data/db.sqlite3 ".backup '/pfad/backup.sqlite3'" vom Host aus.

Für den Zeitplan nimmst du einen Cronjob (Cronjob erstellen) und schiebst die Sicherung danach weg vom Server, am besten nach der 3-2-1-Backup-Strategie. Ein Beispiel:

# /etc/cron.d/vaultwarden-backup, täglich 03:15
15 3 * * * root docker exec vaultwarden /vaultwarden backup && \
  tar czf /backup/vw-$(date +\%F).tgz -C /opt/vaultwarden/data \
  $(cd /opt/vaultwarden/data && ls -t db_*.sqlite3 | head -1) rsa_key.pem attachments sends \
  && find /opt/vaultwarden/data -name 'db_*.sqlite3' -mtime +7 -delete

Danach mit restic, rsync oder ähnlichem raus vom Server. Das Backup selbst ist übrigens unkritischer, als es klingt: Die Einträge darin sind ja verschlüsselt. Trotzdem gehört es nicht ungeschützt in eine öffentliche Cloud, denn E-Mail-Adressen und Metadaten stehen im Klartext drin.

Die Wiederherstellung haben wir ausprobiert

Ein Backup, das nie zurückgespielt wurde, ist eine Hoffnung. Wir haben deshalb einen leeren Ordner genommen, nur die Sicherungsdatei als db.sqlite3 und die rsa_key.pem hineinkopiert und einen neuen Container darauf gestartet. Ergebnis: Login 200, Synchronisation 200, der Eintrag war da.

Dann der zweite Versuch ohne rsa_key.pem. Vaultwarden erzeugt beim Start einfach einen neuen Schlüssel. Login und Tresor funktionierten trotzdem, denn die Tresordaten hängen an deinem Master-Passwort, nicht an diesem Schlüssel. Aber jede bestehende Sitzung war ungültig: Ein vorher ausgestellter Token bekam 401. In der Praxis heißt das, alle Geräte müssen sich neu anmelden. Ärgerlich, aber kein Datenverlust. Die rsa_key.pem sicherst du also mit, und wenn sie doch fehlt, ist es kein Weltuntergang.

Drei Kopien eines leuchtenden Tresorwürfels in verschiedenen Regalen und einer Cloud

Schritt 6: Härten — die Checkliste nach dem Vaultwarden einrichten

Mit den Schritten oben bist du weiter als die meisten Installationen. Diese Punkte gehören noch dazu:

  1. Zwei-Faktor-Anmeldung im Tresor einschalten (Einstellungen → Sicherheit → Zweistufige Anmeldung). TOTP mit einer Authenticator-App funktioniert ohne weitere Konfiguration, Passkeys/WebAuthn ebenfalls über HTTPS. Den Wiederherstellungscode ausdrucken und weglegen.
  2. Ein langes Master-Passwort. Vier bis sechs zufällige Wörter schlagen jedes P@ssw0rd!. Es ist der einzige Schlüssel zu allem, und niemand kann es zurücksetzen, auch du als Admin nicht.
  3. Die Login-Sperre mit fail2ban ergänzen. Die eingebaute Bremse sperrt nur für Minuten. Setz LOG_FILE: "/data/vaultwarden.log" und lass fail2ban auf die Zeile Username or password is incorrect. Try again. IP: <HOST> reagieren. Das funktioniert nur, wenn der header_up-Fix aus Schritt 2 sitzt, sonst sperrt fail2ban Fantasieadressen oder den eigenen Proxy. Grundlagen in fail2ban einrichten.
  4. Admin-Panel abschalten, wenn du es nicht brauchst. Einfach ADMIN_TOKEN weglassen. Alternativ den Pfad /admin im Reverse Proxy auf dein Heimnetz oder VPN beschränken.
  5. Updates einplanen. Vaultwarden veröffentlicht regelmäßig, allein seit Juli fünf Releases (1.37.0 am 24. Juli, 1.37.1 am 29. Juli, 1.37.2 am 22. August, 1.37.3 am 13. September, 1.37.4 am 5. Oktober 2026). Ablauf: Release-Notes lesen, Backup ziehen, Versionsnummer in der Compose-Datei ändern, docker compose pull && docker compose up -d. Die Datenbank wird beim Start automatisch migriert.
  6. SMTP konfigurieren (SMTP_HOST, SMTP_FROM, …), wenn du Einladungen, Notfallzugriff oder E-Mail-Bestätigungen nutzen willst. Ohne Mail funktioniert der Kern trotzdem.

Gar nicht ins Internet: Vaultwarden nur im VPN

Die sicherste Login-Seite ist eine, die niemand im Internet findet. Wenn alle deine Geräte ohnehin in einem VPN wie Tailscale oder WireGuard hängen, lässt du Vaultwarden einfach nur dort lauschen. Die Bitwarden-Apps synchronisieren dann nur, wenn das VPN steht. Unterwegs ohne VPN arbeiten sie mit ihrer lokalen, verschlüsselten Kopie weiter und können Passwörter anzeigen, aber neue Einträge erst später abgleichen. Welche VPN-Variante zu dir passt, vergleichen wir in Tailscale vs. WireGuard. Ein Detail: Auch im VPN braucht der Web-Tresor HTTPS. Tailscale kann dafür Zertifikate für deine ts.net-Adresse ausstellen.

Video: Vaultwarden mit Docker und fail2ban

Wer den Ablauf lieber einmal sehen will: Deployn zeigt die Installation mit Docker Compose und die Absicherung mit fail2ban Schritt für Schritt auf Deutsch. Das Video ist von April 2025, die Grundschritte sind gleich geblieben. Achte beim Nachbauen auf die X-Real-IP-Zeile aus Schritt 2.

Und für die VPN-Variante: Das englischsprachige Video von IT Homelab Online (Juli 2026) zeigt Vaultwarden mit einem Tailscale-Sidecar-Container, also ganz ohne offene Ports im Internet.

Die Bitwarden-Apps mit deinem Server verbinden

Das ist der angenehmste Teil. In jeder Bitwarden-App gibt es auf dem Anmeldebildschirm eine Auswahl der Region. Dort wählst du „Selbst gehostet“ und trägst deine Server-URL ein, also https://vault.deinedomain.de. Mehr nicht. Das gilt für die Apps auf Android und iOS, für die Desktop-App, für die Browser-Erweiterung und für die Kommandozeile (bw config server https://vault.deinedomain.de).

Umzug von einem anderen Passwortmanager: Im Web-Tresor unter Werkzeuge → Daten importieren nimmt Vaultwarden Exporte aus Bitwarden, KeePass, 1Password, LastPass, Chrome, Firefox und vielen anderen an. Die Importdatei liegt dabei unverschlüsselt auf deinem Rechner. Lösch sie nach dem Import richtig und lass sie nicht im Download-Ordner liegen.

Was wir nicht getestet haben

Damit du weißt, worauf du dich verlassen kannst und worauf nicht:

  • MySQL/MariaDB und PostgreSQL als Datenbank haben wir nicht ausprobiert, nur das Standard-SQLite. Für eine Familie oder ein kleines Team reicht SQLite völlig. Wann sich der Wechsel lohnt, steht allgemein in SQLite vs. PostgreSQL.
  • Die echten Apps haben wir nicht angeschlossen, sondern den Client per Skript nachgebaut. Die Anmeldung über die Apps nutzt dieselbe Schnittstelle, die wir getestet haben.
  • SSO (die Anmeldung über einen externen Identitätsanbieter, in den aktuellen Versionen enthalten), Organisationen und Notfallzugriff haben wir nicht durchgespielt.
  • Last haben wir nicht gemessen. Für die Größenordnung „ein Haushalt“ ist sie ohnehin kein Thema.
  • Die Fallen haben wir mit Vaultwarden 1.37.4 und Caddy 2.11.7 nachgestellt. In späteren Versionen kann sich das Verhalten ändern.

FAQ: Häufige Fragen zu Vaultwarden

Ist Vaultwarden kostenlos?

Ja. Vaultwarden ist Open Source (AGPL-3.0) und kostet nichts. Auch Funktionen, die bei Bitwarden ein Abo brauchen, etwa Organisationen oder Anhänge, sind enthalten. Du zahlst nur für den Server, auf dem es läuft.

Ist Vaultwarden sicher genug für meine Passwörter?

Die Verschlüsselung passiert in den Bitwarden-Apps auf deinem Gerät. In unserer Datenbank stand kein einziges Passwort im Klartext. Die Sicherheit des Servers liegt aber bei dir: HTTPS, geschlossene Registrierung, korrekt gesetzte X-Real-IP, Updates, Backups und Zwei-Faktor-Anmeldung. Wer das nicht pflegen will, ist mit einem gehosteten Passwortmanager besser bedient.

Was ist der Unterschied zwischen Vaultwarden und Bitwarden?

Bitwarden ist das Original von Bitwarden Inc., mit eigenem Server und eigenen Apps. Vaultwarden ist eine unabhängige Server-Neuimplementierung in Rust, die dieselben Apps bedient. Sie braucht nur einen Container und kaum Arbeitsspeicher (bei uns 7,9 MB im Leerlauf), hat aber keinen offiziellen Support.

Kann ich Vaultwarden ohne Domain und ohne HTTPS betreiben?

Nur eingeschränkt. Der Web-Tresor braucht einen sicheren Kontext, also HTTPS oder localhost. Für ein Heimnetz kannst du ein Zertifikat über eine echte Domain mit DNS-Challenge holen oder Vaultwarden über ein VPN wie Tailscale erreichbar machen, das selbst Zertifikate ausstellt.

Wie viel RAM und Speicher braucht Vaultwarden?

Sehr wenig. Unser frischer Container brauchte 7,9 MB RAM und startete in 0,6 Sekunden. Das Docker-Image ist 402 MB groß, der Datenordner eines kleinen Haushalts nur einige hundert Kilobyte bis wenige Megabyte, plus eventuelle Anhänge.

Was passiert, wenn mein Vaultwarden-Server ausfällt?

Die Bitwarden-Apps halten eine verschlüsselte Kopie deines Tresors auf dem Gerät. Du kannst also weiterhin Passwörter abrufen. Neue Einträge werden erst wieder synchronisiert, wenn der Server zurück ist. Genau deshalb ist das Backup so wichtig: Fällt der Server endgültig aus, holst du alles aus der Sicherung zurück.

Kann ich das Master-Passwort zurücksetzen, wenn ich es vergesse?

Nein, auch nicht als Admin. Das ist die Kehrseite der Verschlüsselung auf dem Gerät: Ohne Master-Passwort lässt sich der Tresor nicht entschlüsseln. Der Admin kann ein Konto nur löschen. Für Familien gibt es den Notfallzugriff, bei dem eine Vertrauensperson nach einer Wartezeit Zugriff bekommt.

Muss ich das Admin-Panel aktivieren?

Nein. Ohne ADMIN_TOKEN ist es abgeschaltet, und das ist ein guter Zustand. Du brauchst es für Einladungen, um Nutzer zu verwalten, und für Diagnosen. Wenn du es aktivierst, dann mit Argon2-Hash und verdoppelten $$ in der Compose-Datei.

Warum werden meine Änderungen in der compose.yaml ignoriert?

Wahrscheinlich gibt es eine data/config.json. Die entsteht, sobald du im Admin-Panel speicherst, und hat Vorrang vor Umgebungsvariablen. Schau nach, ob die Datei existiert, und entscheide dich für einen der beiden Wege.

Wie mache ich ein Update von Vaultwarden?

Backup ziehen (docker exec vaultwarden /vaultwarden backup), die Release-Notes lesen, die Versionsnummer im image: anpassen und docker compose pull && docker compose up -d ausführen. Die Datenbank wird beim Start automatisch migriert. Wenn etwas schiefgeht, nimmst du die alte Version und das Backup.

Brauche ich zusätzlich fail2ban?

Die eingebaute Sperre bremst Rateversuche für ein paar Minuten. fail2ban sperrt die Quelle länger und auf Firewall-Ebene. Beides zusammen ist sinnvoll, aber nur, wenn Vaultwarden die echte Client-IP sieht. Sonst helfen beide nicht.

Fazit: Vaultwarden einrichten lohnt sich, wenn du die vier Zeilen nicht vergisst

Vaultwarden ist eines der dankbarsten Self-Hosting-Projekte überhaupt: ein Container, kaum Ressourcen, die guten Bitwarden-Apps, und deine Passwörter liegen bei dir. Die Kryptografie macht ihren Job, unsere Datenbank enthielt nicht ein einziges lesbares Passwort.

Die Risiken liegen in der Konfiguration, und die meisten Anleitungen übergehen sie. Unsere Messung hat vier Stellen gezeigt, an denen der Standard oder ein naheliegender Fehler die Tür offen lässt:

  1. SIGNUPS_ALLOWED: "false", sonst kann sich jeder registrieren.
  2. header_up X-Real-IP {remote_host} im Proxy, sonst ist die Login-Sperre umgehbar oder sperrt alle aus.
  3. $$ statt $ im Admin-Token, sonst hast du ein verstümmeltes Klartext-Passwort.
  4. Ein Auge auf data/config.json, sonst gilt nicht, was in deiner Compose-Datei steht.

Dazu ein Backup, das du einmal wirklich zurückgespielt hast, Zwei-Faktor-Anmeldung und regelmäßige Updates. Dann hast du einen Passwortmanager, der einem kommerziellen Angebot in nichts nachsteht und dir gehört.