Vaultwarden selbst hosten: Schritt-für-Schritt-Anleitung mit Docker, Caddy und Fail2Ban
Deinen eigenen Passwort-Manager, Vaultwarden, sicher und effizient selbst hosten. Vaultwarden als Docker-Container installieren und mit Fail2Ban absichern.

Inhaltsverzeichnis
- Was ist Vaultwarden?
- Voraussetzungen
- Schritt 1: Vorbereitung des Servers
- Schritt 2: Docker Netzwerk erstellen
- Schritt 3: Vaultwarden Verzeichnisstruktur anlegen
- Schritt 4: Docker Compose Datei für Vaultwarden erstellen
- Schritt 5: Vaultwarden Starten
- Schritt 6: Reverse Proxy (Caddy) konfigurieren
- Schritt 7: Erster Zugriff und Kontoerstellung
- Schritt 8: Admin-Bereich absichern und Registrierung deaktivieren
- Schritt 9: Logging für Vaultwarden konfigurieren
- Schritt 10: Fail2Ban für zusätzliche Sicherheit einrichten
- Schritt 11: Fail2Ban Konfiguration erstellen
- Schritt 12: Fail2Ban starten und testen
- Schritt 13: Backup-Strategie
- Zusammenfassung
Was ist Vaultwarden?
Vaultwarden ist ein alternativer Server für das Bitwarden-Ökosystem, geschrieben in der Programmiersprache Rust. Das macht ihn besonders performant und ressourcenschonend – ideal für einen Heimserver oder einen kleinen VPS. Du kannst damit alle offiziellen Bitwarden-Clients (Browser-Erweiterungen, Desktop-Apps, Mobile Apps) nutzen.
Voraussetzungen
Bevor wir loslegen, stelle sicher, dass du Folgendes hast:
- Einen Server: Ein Server mit einem gängigen Linux-Betriebssystem. Ich verwende hier Ubuntu 24.04, aber andere Distributionen funktionieren ähnlich.
- Docker und Docker Compose: Müssen auf dem Server installiert sein.
- Eine Domain: Eine Domain oder Subdomain, die auf die öffentliche IP-Adresse deines Servers zeigt.
- Einen Reverse Proxy: Ein funktionierender Reverse Proxy. In diesem Tutorial verwenden wir Caddy. Andere Proxys wie Nginx Proxy Manager oder Traefik sind ebenfalls möglich, erfordern aber eine angepasste Konfiguration.
- (Optional) Pengolin: Falls du einen Heimserver ohne feste öffentliche IPv4-Adresse nutzt, schau dir Pengolin (oder ein ähnliches Tool/Video dazu) an, um deinen Server erreichbar zu machen.
Schritt 1: Vorbereitung des Servers
Öffne ein Terminal und verbinde dich per SSH mit deinem Server.
ssh dein_benutzer@DEINE_SERVER_IP
Ersetze dein_benutzer
und DEINE_SERVER_IP
entsprechend.
Domain-Check: Stelle sicher, dass deine Domain korrekt auf die IP deines Servers zeigt.
ping passwort.deinedomain.de
Ersetze passwort.deinedomain.de
mit deiner gewünschten Domain. Die Ausgabe sollte die IP-Adresse deines Servers anzeigen. Wenn nicht, überprüfe deine DNS-Einstellungen und warte ggf. auf die Propagierung.
Docker-Check: Überprüfe, ob Docker und Docker Compose installiert sind.
docker -v
docker compose version
Du solltest die Versionsnummern sehen. Falls nicht, installiere Docker und Docker Compose gemäß der offiziellen Dokumentation für dein Betriebssystem.
Schritt 2: Docker Netzwerk erstellen
Wir benötigen ein gemeinsames Docker-Netzwerk, damit unser Reverse Proxy (Caddy) mit dem Vaultwarden-Container kommunizieren kann.
sudo docker network create proxy
Wir nennen das Netzwerk proxy
. Du kannst den Namen überprüfen mit:
sudo docker network ls
Schritt 3: Vaultwarden Verzeichnisstruktur anlegen
Erstelle ein Verzeichnis für die Vaultwarden-Konfiguration und die persistenten Daten.
mkdir ~/vaultwarden
cd ~/vaultwarden
mkdir vw-data
Der Ordner vw-data
wird später die verschlüsselte Datenbank, Anhänge und Einstellungen von Vaultwarden enthalten.
Schritt 4: Docker Compose Datei für Vaultwarden erstellen
Erstelle eine docker-compose.yml
-Datei im ~/vaultwarden
-Verzeichnis:
nano docker-compose.yml
Füge folgenden Inhalt ein und passe ihn an:
version: "3"
services:
vaultwarden:
image: vaultwarden/server:1.31.0 # Verwende einen spezifischen Tag statt 'latest'
container_name: vaultwarden
restart: always
environment:
# - WEBSOCKET_ENABLED=true # Deaktiviere WebSocket, wenn nicht benötigt oder Probleme auftreten
# Hier wird der Admin-Token später eingefügt
# ADMIN_TOKEN: 'DEIN_SICHERER_ADMIN_TOKEN_HASH'
# Zeitzone setzen (Wichtig für Logs und Fail2Ban)
TZ: "Europe/Berlin" # Passe dies an deine Zeitzone an
volumes:
- ./vw-data:/data
# Mounts für die Zeitzone (Wichtig für korrekte Log-Zeiten -> Fail2Ban)
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
# Netzwerk für die Verbindung zum Reverse Proxy
networks:
- proxy
# Als Non-Root User ausführen (optional aber empfohlen)
# Finde deine User/Group ID mit 'id' im Terminal
# user: '1000:1000' # Ersetze 1000:1000 mit deiner UID:GID
networks:
proxy:
external: true # Wir verwenden das zuvor erstellte externe Netzwerk
Wichtige Anpassungen:
- Image Tag: Ich habe
vaultwarden/server:1.33.2
verwendet. Prüfe auf GitHub nach der neuesten stabilen Version und ersetze den Tag entsprechend. Die Verwendung eines spezifischen Tags verhindert unerwartete Updates und erleichtert das manuelle, kontrollierte Updaten. - Ports: Wir entfernen die
ports
-Sektion, da der Zugriff ausschließlich über den Reverse Proxy erfolgen soll. - Netzwerk: Wir fügen den Container dem
proxy
-Netzwerk hinzu und deklarieren dieses alsexternal
. - User (Optional): Um die Sicherheit zu erhöhen, kannst du den Container unter deinem normalen Benutzer laufen lassen. Finde deine User ID (UID) und Group ID (GID) mit dem Befehl
id
auf deinem Server heraus und füge dieuser: 'UID:GID'
Zeile ein (Kommentar entfernen). Stelle sicher, dass dein Benutzer Schreibrechte auf das./vw-data
Verzeichnis hat (ggf.sudo chown DEINE_UID:DEINE_GID vw-data
). - Zeitzone (TZ, Volumes): Die
TZ
-Variable und dielocaltime
/timezone
-Volumes sind wichtig, damit die Logs im Container die korrekte Zeit haben. Dies ist später entscheidend für Fail2Ban. Passe'Europe/Berlin'
an deine Zeitzone an.
Speichere die Datei (Strg+X, dann Y, dann Enter in nano
).
Schritt 5: Vaultwarden Starten
Starte den Vaultwarden-Container im Hintergrund:
sudo docker compose up -d
Docker wird nun das Vaultwarden-Image herunterladen (falls noch nicht vorhanden) und den Container starten.
Schritt 6: Reverse Proxy (Caddy) konfigurieren
Jetzt konfigurieren wir Caddy, damit Vaultwarden über deine Domain erreichbar ist und automatisch ein SSL-Zertifikat erhält. Bearbeite deine Caddyfile (der Pfad kann variieren, oft /etc/caddy/Caddyfile
oder ein Verzeichnis, wenn Caddy auch als Docker-Container läuft):
# Beispiel für deine Caddyfile
passwort.deinedomain.de {
# Header für echte Client-IP hinzufügen (wichtig für Logs/Fail2Ban)
reverse_proxy vaultwarden:80 {
header_up X-Real-IP {remote_host}
}
# Optional: Log-Level für Caddy anpassen
log {
level WARN
}
}
# Füge hier ggf. weitere Domains hinzu
Wichtige Punkte:
- Ersetze
passwort.deinedomain.de
durch deine Domain. vaultwarden:80
verweist auf den Container-Namen (vaultwarden
) und den internen Port, auf dem Vaultwarden lauscht (Standard ist 80).header_up X-Real-IP {remote_host}
ist entscheidend, damit Vaultwarden die echte IP-Adresse des Clients sieht und nicht die des Caddy-Containers. Das ist wichtig für die Logs und für Fail2Ban.- Passe ggf. das
log level
an, um die Log-Ausgabe von Caddy zu reduzieren.
Lade die Caddy-Konfiguration neu. Wenn Caddy als Docker-Container läuft (z.B. namens caddy
), könnte es sein:
sudo docker exec caddy caddy reload -c /etc/caddy/Caddyfile
Schritt 7: Erster Zugriff und Kontoerstellung
Öffne deinen Browser und rufe https://passwort.deinedomain.de
auf. Du solltest die Vaultwarden-Weboberfläche sehen. Klicke auf “Konto erstellen”, gib deine Daten ein und erstelle dein erstes Benutzerkonto.
Du kannst dich nun einloggen und den Passwort-Manager nutzen!
Schritt 8: Admin-Bereich absichern und Registrierung deaktivieren
Standardmäßig kann jeder ein Konto auf deiner Vaultwarden-Instanz erstellen. Das wollen wir ändern. Dazu benötigen wir Zugriff auf den Admin-Bereich, der über https://passwort.deinedomain.de/admin
erreichbar ist. Dieser ist durch einen Admin-Token geschützt, den wir erst generieren müssen.
Admin Token generieren:
Wir verwenden argon2
zum Hashen des Admin-Passworts. Installiere es zuerst (Beispiel für Debian/Ubuntu):
sudo apt update && sudo apt install argon2 -y
Generiere nun den Hash für dein gewünschtes Admin-Passwort (ersetze DeinSicheresAdminPasswort
)
echo -n 'DeinSicheresAdminPasswort' | argon2 "$(openssl rand -base64 16)" -e -id -k 65536 -t 3 -p 4 | sed 's/\$/\$\$/g'
Kopiere die gesamte Ausgabe, beginnend mit $$argon2id$$...
.
Admin Token zur docker-compose.yml
hinzufügen:
Öffne die docker-compose.yml
erneut:
nano docker-compose.yml
Füge unter environment
die ADMIN_TOKEN
-Variable hinzu oder entferne das Kommentarzeichen und füge den Hash ein:
# ... (andere Services oder Einstellungen)
services:
vaultwarden:
# ... (andere Vaultwarden-Einstellungen)
environment:
# ... (andere Umgebungsvariablen wie TZ)
ADMIN_TOKEN: DEIN_KOPIERTER_ARGON2_HASH # Füge hier den kopierten Hash ein
# ... (Rest der Vaultwarden-Konfiguration)
# ... (Netzwerke etc.)
Speichere die Datei und starte Vaultwarden neu, damit die Änderung wirksam wird:
sudo docker compose down
sudo docker compose up -d
Registrierung deaktivieren:
- Gehe zu
https://passwort.deinedomain.de/admin
. - Gib dein ursprüngliches Admin-Passwort ein (das, was du oben in den
echo
-Befehl eingegeben hast, nicht den Hash). - Gehe zu den “Allgemeinen Einstellungen”.
- Entferne das Häkchen bei “Anmeldungen erlauben” (Allow new signups).
- Klicke auf “Speichern”.
Versuche nun (z.B. in einem privaten Browserfenster), ein neues Konto zu erstellen. Es sollte eine Fehlermeldung erscheinen, dass die Registrierung deaktiviert ist.
Im Admin-Panel kannst du auch SMTP-Einstellungen für den E-Mail-Versand konfigurieren (nützlich für Einladungen oder Passwort-Reset) und Benutzer verwalten.
Schritt 9: Logging für Vaultwarden konfigurieren
Um fehlgeschlagene Anmeldeversuche protokollieren zu können (was wir für Fail2Ban brauchen), fügen wir Logging-Optionen zur docker-compose.yml
hinzu.
Öffne die docker-compose.yml
:
nano docker-compose.yml
Füge unter environment
beim vaultwarden
-Service folgende Zeilen hinzu:
# ...
services:
vaultwarden:
# ...
environment:
# ... (TZ, ADMIN_TOKEN)
LOG_FILE: "/data/vaultwarden.log"
LOG_LEVEL: "warn" # Loggt Warnungen und Fehler (inkl. falscher Logins)
# ...
# ...
# ...
Speichere die Datei und starte Vaultwarden neu:
sudo docker compose down
sudo docker compose up -d
Jetzt werden fehlgeschlagene Anmeldungen in die Datei vw-data/vaultwarden.log
geschrieben. Du kannst dies testen, indem du versuchst, dich mit einem falschen Passwort anzumelden und dann den Log prüfst:
tail -f ~/vaultwarden/vw-data/vaultwarden.log
Du solltest eine Zeile wie [WARN] Wrong password provided for user...
oder [INFO] Login request failed...
sehen, gefolgt von der IP-Adresse des Clients (dank X-Real-IP
im Caddy-Setup).
Schritt 10: Fail2Ban für zusätzliche Sicherheit einrichten
Fail2Ban überwacht Logdateien und sperrt IP-Adressen, die wiederholt fehlgeschlagene Anmeldeversuche unternehmen. Wir verwenden das beliebte Fail2Ban Docker-Image von CrazyMax.
Verzeichnisstruktur für Fail2Ban:
Erstelle im ~/vaultwarden
-Verzeichnis einen Ordner für die Fail2Ban-Daten:
cd ~/vaultwarden
mkdir fail2ban-data
Fail2Ban zur docker-compose.yml
hinzufügen:
Öffne die docker-compose.yml
:
nano docker-compose.yml
Füge einen neuen Service für Fail2Ban hinzu:
services:
vaultwarden:
# ... (Deine Vaultwarden Konfiguration von oben) ...
fail2ban:
image: crazymax/fail2ban:latest
container_name: fail2ban
restart: always
# Wichtig: Host-Netzwerkmodus, damit Fail2Ban Host-iptables ändern kann
network_mode: host
# Notwendige erweiterte Rechte für Netzwerkadministration
cap_add:
- NET_ADMIN
- NET_RAW
environment:
# Setze die Zeitzone passend zu deinem Host und Vaultwarden
TZ: "Europe/Berlin"
# Optional: Setze das Log-Level für Fail2Ban selbst
F2B_LOG_LEVEL: "INFO"
volumes:
# Persistente Daten für Fail2Ban (Datenbank der Bans etc.)
- ./fail2ban-data:/data
# Vaultwarden Log-Datei (nur lesend einbinden)
- ./vw-data/vaultwarden.log:/var/log/vaultwarden/vaultwarden.log:ro
networks:
proxy:
external: true
Wichtige Punkte:
network_mode: host
: Erlaubt Fail2Ban, direkt auf die Netzwerkkonfiguration undiptables
des Host-Systems zuzugreifen, um IPs zu blockieren.cap_add: [NET_ADMIN, NET_RAW]
: Gibt dem Container die nötigen Rechte dafür.volumes
: Wir binden dasfail2ban-data
-Verzeichnis für die Konfiguration und die Datenbank, sowie dievaultwarden.log
(nur lesend!) ein. Der Pfad/var/log/vaultwarden/vaultwarden.log
im Container ist der Pfad, den wir später in der Fail2Ban-Konfiguration verwenden.TZ
: Stelle sicher, dass die Zeitzone hier mit der des Hosts und des Vaultwarden-Containers übereinstimmt!
Speichere die Datei.
Schritt 11: Fail2Ban Konfiguration erstellen
Wir müssen Fail2Ban mitteilen, wonach es in der Logdatei suchen soll (Filter) und was es tun soll, wenn es etwas findet (Jail).
Wechsle in das Fail2Ban-Datenverzeichnis und erstelle die nötigen Unterordner:
cd ~/vaultwarden/fail2ban-data
mkdir filter.d jail.d action.d
Filter erstellen:
Erstelle eine Filterdatei für normale Vaultwarden-Logins:
nano filter.d/vaultwarden.local
Füge folgenden Inhalt ein:
[Includes]
before = common.conf
[Definition]
failregex = ^.*?Username or password is incorrect\. Try again\. IP: <ADDR>\. Username: .*$
ignoreregex =
Speichere die Datei.
Erstelle eine Filterdatei für fehlgeschlagene Admin-Logins:
nano filter.d/vaultwarden-admin.local
Füge folgenden Inhalt ein:
[Includes]
before = common.conf
[Definition]
failregex = ^.*?Invalid admin token\. IP: <ADDR>.*$
# ignoreregex =
Speichere die Datei.
Jail erstellen:
Erstelle eine zentrale Jail-Konfigurationsdatei:
nano jail.d/vaultwarden.local
Füge folgenden Inhalt ein und passe die Werte nach Bedarf an:
[vaultwarden]
enabled = true
# Pfad zur Logdatei, wie sie in den Fail2Ban-Container gemountet wurde
logpath = /var/log/vaultwarden/vaultwarden.log
# Verwendeter Filter (Name der .local Datei ohne Endung)
filter = vaultwarden
action = iptables-allports[name=vaultwarden, chain=DOCKER-USER]
ports = 80,443
# Maximale Anzahl Fehlversuche
maxretry = 5
# Zeitraum für Fehlversuche (z.B. 1h = 1 Stunde)
findtime = 1h
# Sperrdauer (z.B. 24h = 24 Stunden, 1d = 1 Tag, 1w = 1 Woche)
bantime = 24h
[vaultwarden-admin]
enabled = true
logpath = /var/log/vaultwarden/vaultwarden.log
filter = vaultwarden-admin
action = iptables-allports[name=vaultwarden-admin, chain=DOCKER-USER]
ports = 80,443
# Strengere Regeln für den Admin-Zugang
maxretry = 3
findtime = 10h
bantime = 7d # 7 Tage Sperre
Wichtige Parameter:
enabled = true
: Aktiviert das Jail.logpath
: Muss exakt dem Pfad entsprechen, unter dem die Logdatei im Fail2Ban-Container erreichbar ist.filter
: Der Name der zugehörigen Filterdatei infilter.d
(ohne.local
).action = %(action_)s
: Nutzt die Standard-Aktion von Fail2Ban, die normalerweiseiptables
verwendet, um die IP zu blockieren.maxretry
: Anzahl der erlaubten Fehlversuche.findtime
: Zeitfenster, in dem diemaxretry
Versuche stattfinden müssen, um einen Ban auszulösen.bantime
: Dauer der Sperre in Sekunden (Suffixe wiem
,h
,d
,w
sind möglich).
Passe maxretry
, findtime
und bantime
nach deinen Sicherheitsanforderungen an. Speichere die Datei.
Schritt 12: Fail2Ban starten und testen
Gehe zurück in das Hauptverzeichnis (cd ~/vaultwarden
) und starte beide Container neu, damit alle Änderungen (Compose-Datei, Fail2Ban-Konfigs) geladen werden:
sudo docker compose down
sudo docker compose up -d
Überprüfe die Fail2Ban-Logs:
sudo docker compose logs -f fail2ban
Du solltest Meldungen sehen, dass die Jails vaultwarden
und vaultwarden-admin
gefunden und gestartet wurden, sowie am Ende etwas wie Server ready
.
Testen:
-
Öffne deine Vaultwarden-Loginseite (
https://passwort.deinedomain.de
). -
Gib absichtlich 5 Mal (oder entsprechend deines
maxretry
-Wertes für[vaultwarden]
) ein falsches Passwort ein. -
Beim nächsten Versuch (oder schon davor) sollte die Seite nicht mehr laden (Timeout oder Verbindungsfehler).
-
Überprüfe den Status des Jails im Fail2Ban-Container (ersetze
DEINE_AKTUELLE_IP
durch die IP, von der aus du getestet hast):sudo docker compose exec fail2ban fail2ban-client status vaultwarden
Du solltest sehen, dass deine IP unter “Currently banned” gelistet ist.
-
Entsperren (falls du dich selbst ausgesperrt hast):
sudo docker compose exec fail2ban fail2ban-client set vaultwarden unbanip DEINE_AKTUELLE_IP
Danach solltest du die Seite wieder laden können.
Wiederhole den Test ggf. für den Admin-Bereich (/admin
) mit einem falschen Admin-Token, um das vaultwarden-admin
-Jail zu testen (Achtung: maxretry
ist hier niedriger).
Schritt 13: Backup-Strategie
Ein selbst gehosteter Dienst ist nur so gut wie sein Backup! Stelle sicher, dass du regelmäßig Backups erstellst. Wichtige Daten sind:
- Vaultwarden-Daten: Der gesamte Inhalt des Ordners
~/vaultwarden/vw-data
. Er enthält die verschlüsselte Datenbank, Anhänge, Einstellungen und Logs. Dies ist der kritischste Teil! - Fail2Ban-Daten: Der gesamte Inhalt des Ordners
~/vaultwarden/fail2ban-data
. Er enthält deine Konfiguration und die Datenbank der gesperrten IPs. - Docker Compose Datei: Die
~/vaultwarden/docker-compose.yml
. - Caddy Konfiguration: Deine
Caddyfile
und ggf. von Caddy generierte Daten (Zertifikate etc., oft unter/var/lib/caddy
oder einem gemappten Volume).
Es gibt viele Backup-Tools. Duplicati ist eine gängige Optionen. Stelle sicher, dass deine Backups an einem sicheren, externen Ort gespeichert und regelmäßig getestet werden!
Zusammenfassung
Herzlichen Glückwunsch! Du hast erfolgreich:
- Vaultwarden mit Docker Compose aufgesetzt.
- Einen spezifischen Image-Tag verwendet und den Container als Non-Root-User konfiguriert (optional).
- Caddy als Reverse Proxy mit SSL und Real-IP-Header eingerichtet.
- Den Admin-Bereich mit einem Token gesichert und die öffentliche Registrierung deaktiviert.
- Das Logging für Vaultwarden konfiguriert.
- Fail2Ban zur automatischen Blockierung von Angreifern eingerichtet und getestet.
- Die Wichtigkeit einer Backup-Strategie erkannt.
Dein eigener, sicherer Passwort-Manager läuft nun auf deinem Server! Du kannst jetzt die Bitwarden Browser-Erweiterungen und Apps mit deiner Server-URL (https://passwort.deinedomain.de
) konfigurieren und deine Passwörter sicher verwalten.
Ich hoffe, dieser Blogpost hilft dir bei der Installation von Vaultwarden! Lass mich wissen, wenn du Anpassungen oder Ergänzungen wünschst.