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.

Vaultwarden selbst hosten: Schritt-für-Schritt-Anleitung mit Docker, Caddy und Fail2Ban hero image

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:

  1. Einen Server: Ein Server mit einem gängigen Linux-Betriebssystem. Ich verwende hier Ubuntu 24.04, aber andere Distributionen funktionieren ähnlich.
  2. Docker und Docker Compose: Müssen auf dem Server installiert sein.
  3. Eine Domain: Eine Domain oder Subdomain, die auf die öffentliche IP-Adresse deines Servers zeigt.
  4. 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.
  5. (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:

  1. 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.
  2. Ports: Wir entfernen die ports-Sektion, da der Zugriff ausschließlich über den Reverse Proxy erfolgen soll.
  3. Netzwerk: Wir fügen den Container dem proxy-Netzwerk hinzu und deklarieren dieses als external.
  4. 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 die user: '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).
  5. Zeitzone (TZ, Volumes): Die TZ-Variable und die localtime/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:

  1. Ersetze passwort.deinedomain.de durch deine Domain.
  2. vaultwarden:80 verweist auf den Container-Namen (vaultwarden) und den internen Port, auf dem Vaultwarden lauscht (Standard ist 80).
  3. 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.
  4. 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:

  1. Gehe zu https://passwort.deinedomain.de/admin.
  2. Gib dein ursprüngliches Admin-Passwort ein (das, was du oben in den echo-Befehl eingegeben hast, nicht den Hash).
  3. Gehe zu den “Allgemeinen Einstellungen”.
  4. Entferne das Häkchen bei “Anmeldungen erlauben” (Allow new signups).
  5. 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:

  1. network_mode: host: Erlaubt Fail2Ban, direkt auf die Netzwerkkonfiguration und iptables des Host-Systems zuzugreifen, um IPs zu blockieren.
  2. cap_add: [NET_ADMIN, NET_RAW]: Gibt dem Container die nötigen Rechte dafür.
  3. volumes: Wir binden das fail2ban-data-Verzeichnis für die Konfiguration und die Datenbank, sowie die vaultwarden.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.
  4. 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 in filter.d (ohne .local).
  • action = %(action_)s: Nutzt die Standard-Aktion von Fail2Ban, die normalerweise iptables verwendet, um die IP zu blockieren.
  • maxretry: Anzahl der erlaubten Fehlversuche.
  • findtime: Zeitfenster, in dem die maxretry Versuche stattfinden müssen, um einen Ban auszulösen.
  • bantime: Dauer der Sperre in Sekunden (Suffixe wie m, 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:

  1. Öffne deine Vaultwarden-Loginseite (https://passwort.deinedomain.de).

  2. Gib absichtlich 5 Mal (oder entsprechend deines maxretry-Wertes für [vaultwarden]) ein falsches Passwort ein.

  3. Beim nächsten Versuch (oder schon davor) sollte die Seite nicht mehr laden (Timeout oder Verbindungsfehler).

  4. Ü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.

  5. 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:

  1. 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!
  2. Fail2Ban-Daten: Der gesamte Inhalt des Ordners ~/vaultwarden/fail2ban-data. Er enthält deine Konfiguration und die Datenbank der gesperrten IPs.
  3. Docker Compose Datei: Die ~/vaultwarden/docker-compose.yml.
  4. 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.

Diesen Beitrag teilen:

Diese Website verwendet Cookies. Diese sind notwendig, um die Funktionalität der Website zu gewährleisten. Weitere Informationen finden Sie in der Datenschutzerklärung