← Übersicht  ·  Skripte & Dateien  ·  Passwort-Manager selbst hosten

Vaultwarden auf Hetzner

Dein eigener Bitwarden-Server – winzig (~10 MB RAM), Docker + Caddy mit automatischem HTTPS (Hypertext Transfer Protocol Secure). Du nutzt die offiziellen Bitwarden-Apps (Browser-Extension, Handy, Desktop), und alle sonst kostenpflichtigen Funktionen (2FA-Codes, Anhänge, Organisationen, Notfallzugriff) sind hier frei.

Stand: 1. September 2026 ca. 20 Minuten ~5–6 €/Monat

Platzhalter einsetzen – werden in allen Befehlen unten ersetzt, nur im Browser, nichts wird gesendet

Das Prinzip

Vaultwarden ist eine schlanke, Bitwarden-kompatible Server-Implementierung (ein Rust-Binary, SQLite). Die offiziellen Bitwarden-Apps verbinden sich damit, als wäre es Bitwarden – Autofill, Passkeys, 2FA-Codes, alles. Caddy davor holt automatisch ein Let’s-Encrypt-Zertifikat. Dein Tresor ist Ende-zu-Ende verschlüsselt mit deinem Master-Passwort. Der Server sieht ihn nie im Klartext.

Deine Geräte Bitwarden-Extension · App · Desktop
Hetzner-Server Caddy → Vaultwarden (Docker)
SQLite-DB liegt hier
Ohne Server geht es auch

Nur einen kostenlosen, gehosteten Manager willst du? Proton Pass Free (2FA-Codes inklusive, eigene Kurzanleitung am Ende) oder Bitwarden Free. Diese Anleitung ist für den Fall „alles selbst, volle Kontrolle, alle Funktionen frei“.

01 Voraussetzung: Server-Basis

Konto, API-Token, hcloud CLI (Command-Line Interface) und SSH-Key – einmalig, in einer eigenen Anleitung.

Einmal einrichten

Server-Basis durcharbeiten (nur hcloud + ssh nötig).

Domain ist Pflicht

Bitwarden-Clients verbinden sich nur über HTTPS mit gültigem Zertifikat – Caddy braucht dafür einen Domainnamen. Du legst später vault.seb4u.com als Subdomain an (Schritt 4).

Firewall für Vaultwarden

Firewall-Prinzip: Server-Basis. Hier: 80 & 443 öffentlich (Zertifikat + Zugriff von überall), 22 nur von deiner IP (Internet Protocol).

Laptop · PowerShell
$ip = (Invoke-RestMethod 'https://ipv4.icanhazip.com').Trim()
hcloud firewall create --name vw-fw
hcloud firewall add-rule vw-fw --direction in --protocol tcp --port 80  --source-ips 0.0.0.0/0,::/0
hcloud firewall add-rule vw-fw --direction in --protocol tcp --port 443 --source-ips 0.0.0.0/0,::/0
hcloud firewall add-rule vw-fw --direction in --protocol tcp --port 22  --source-ips "$ip/32"
Was die Schalter bedeuten

Fünf Zeilen, drei Regeln – der ganze Unterschied steckt in --source-ips:

Schaltersteht beibewirkt
hcloud firewall create --name vw-fw zuerst Eine Hetzner-Firewall ist ein eigenständiges Objekt, kein Bestandteil des Servers: erst anlegen, dann Regeln hineinschreiben, dann an einen Server hängen. Sie wirkt im Netz vor dem Server – anders als ufw, das auf dem Server selbst läuft. Frisch angelegt enthält sie keine Regel und laesst damit nichts herein.
Invoke-RestMethod … icanhazip.com
.Trim()
Zeile 1 Holt die eigene öffentliche IPv4-Adresse. Invoke-RestMethod statt Invoke-WebRequest, weil es direkt den Inhalt liefert statt ein Antwortobjekt. Das .Trim() ist keine Kosmetik: die Antwort endet mit einem Zeilenumbruch, und "1.2.3.4 /32" wäre für Hetzner eine ungültige Angabe.
--direction in alle drei Regeln Hetzner-Firewalls filtern nur eingehend; ausgehend bleibt offen – der Server soll Updates ziehen und Push-Nachrichten senden können.
--source-ips 0.0.0.0/0,::/0 Port 80, 443 Offen für alle – nötig, denn die Vaultwarden-Oberfläche und die Apps sollen von überall erreichbar sein. Beide Notationen müssen dastehen: 0.0.0.0/0 ist jede IPv4-Adresse, ::/0 dasselbe für IPv6. Wer nur die erste angibt, sperrt alle IPv6-Clients aus und merkt es lange nicht, weil der eigene Anschluss meist über IPv4 geht. Port 80 wird nur für die Zertifikatsprüfung von Let's Encrypt und die Weiterleitung auf HTTPS gebraucht.
--source-ips "$ip/32" Port 22 /32 ist genau eine Adresse – die eigene. SSH ist damit für den Rest des Netzes unsichtbar, nicht nur passwortgeschützt. Bei einem Passwort-Tresor ist das der wichtigste Unterschied zwischen „jemand probiert es dauernd“ und „jemand kommt gar nicht erst an die Tür“. Die Anführungszeichen braucht PowerShell, um Variable und /32 zu einem Argument zu verbinden.
Wenn die eigene IP wechselt

DSL-Anschluesse bekommen bei der nächtlichen Zwangstrennung eine neue Adresse, und aus einem fremden Netz stimmt sie ohnehin nicht mehr. Dann sperrt die Regel dich aus. Der Weg zurück führt nicht über SSH, sondern über die Hetzner-Konsole im Browser (oder hcloud firewall delete-rule vom selben Rechner aus, solange der Token noch gilt). Die Weboberfläche auf 443 bleibt davon unberührt – man kommt also weiter an seine Passwörter, nur nicht mehr an den Server.

02 cloud-init (Docker)

Datei · cloud-init.yaml
#cloud-config
package_update: true
package_upgrade: true
packages:
  - docker.io
  - docker-compose-v2

03 Server erstellen

Vaultwarden braucht praktisch nichts. CAX11 (2 ARM-vCPU / 4 GB, ~4 €) ist schon großzügig. Läuft auch auf einem bestehenden Server mit.

Laptop · PowerShell
hcloud server create `
  --name vw-host `
  --type cax11 `
  --image ubuntu-24.04 `
  --ssh-key laptop `
  --firewall vw-fw `
  --user-data-from-file cloud-init.yaml

hcloud server ip vw-host        # IP notieren -> oben ins Feld "Server-IP"

04 DNS: Vault-Subdomain

Ein A-Record auf die Server-IP:

TypNameWert
Avault.seb4u.com<IP>

Liegt seb4u.com schon bei Cloudflare (siehe Domain zu Cloudflare umziehen), legst du vault einfach als A-Record in der bestehenden Zone an – kein Konto, keine Nameserver. Sonst: beim Domain-Anbieter bzw. der Hetzner DNS Console. Cloudflare-Proxy (orange Wolke) für diesen Record erstmal aus (grau) lassen, damit Caddy das Zertifikat holen kann – danach optional wieder an mit SSL-Modus „Full (strict)“. Prüfen: nslookup vault.seb4u.com.

05 compose-Datei & Caddyfile

Dieses Beispiel nutzt Caddy, weil es für einen Dienst am wenigsten Konfiguration ist. Läuft Vaultwarden neben anderen Diensten auf einem Server, besitzt ein Reverse Proxy Port 443 – dann Traefik als Edge und je Dienst ein Stack, siehe Mehrere Dienste auf einem Server.

Auf dem Server, alles in einem Ordner. Erst einloggen:

Laptop · PowerShell
ssh root@<IP>
mkdir -p /opt/vaultwarden && cd /opt/vaultwarden
Server · /opt/vaultwarden/docker-compose.yml
services:
  vaultwarden:
    image: vaultwarden/server:latest
    restart: unless-stopped
    environment:
      DOMAIN: "https://vault.seb4u.com"
      SIGNUPS_ALLOWED: "true"        # nur bis dein Konto steht (Schritt 9)
    volumes:
      - ./vw-data:/data

  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy-data:/data
      - ./caddy-config:/config
    depends_on:
      - vaultwarden
Server · /opt/vaultwarden/Caddyfile
{
    email admin@vault.seb4u.com
}

vault.seb4u.com {
    reverse_proxy vaultwarden:80
}

Seit Vaultwarden 1.30 laufen die WebSocket-Benachrichtigungen über denselben Port – kein Extra-Port nötig.

06 Starten & Konto anlegen

Server · bash
cd /opt/vaultwarden
docker compose up -d
docker compose logs -f caddy       # "certificate obtained" abwarten, dann Strg+C
Jetzt

https://vault.seb4u.com im Browser öffnen → Create account → E-Mail + Master-Passwort (gut merken, keine Wiederherstellung). Das ist ab jetzt dein Zugang.

07 Registrierung sperren + Admin-Panel

Damit sich nicht Fremde registrieren, und für die Server-Einstellungen.

Server · bash
# Admin-Token als Argon2-Hash erzeugen (Passwort eingeben, Hash kopieren):
docker run --rm -it vaultwarden/server /vaultwarden hash

# in eine .env schreiben (Hash 1:1 einfuegen, in Anfuehrungszeichen):
nano /opt/vaultwarden/.env
Server · /opt/vaultwarden/.env
ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$....'

In docker-compose.yml beim Dienst vaultwarden ergänzen / ändern:

Server · docker-compose.yml (Auszug)
    env_file: .env
    environment:
      DOMAIN: "https://vault.seb4u.com"
      SIGNUPS_ALLOWED: "false"
Server · bash
docker compose up -d
exit

Admin-Panel: https://vault.seb4u.com/admin – dort Nutzer verwalten, SMTP (Simple Mail Transfer Protocol) eintragen (Schritt 13), Einladungen verschicken (SIGNUPS_DOMAINS_WHITELIST oder direkt „Invite user“).

08 Bitwarden-Apps verbinden

In jeder offiziellen Bitwarden-App vor dem Login die Server-URL umstellen – danach ganz normal anmelden.

  • Browser-Extension / Desktop: beim Anmelde-Bildschirm oben auf das Zahnrad / Region: Self-hosted → Server-URL https://vault.seb4u.com → Speichern.
  • Android / iOS: beim ersten Start unten/oben Self-hosted wählen, gleiche URL (Uniform Resource Locator). Danach Autofill in den Systemeinstellungen aktivieren.
  • CLI: bw config server https://vault.seb4u.com.

09 Daten importieren

  • Web-Vault öffnen (https://vault.seb4u.com, einloggen) → Tools → Import data.
  • Aus dem vault.html-Tresor: dort Einstellungen → CSV (Comma-Separated Values) exportieren, beim Import als Format „Bitwarden (csv)“ wählen.
  • Aus einem anderen Manager: passendes Format aus der Liste (LastPass, Chrome, KeePass, 1Password …).
  • Danach die CSV-Datei sofort löschen – sie liegt im Klartext vor.

10 Backups

Alles Wichtige liegt in /opt/vaultwarden/vw-data/ (SQLite-DB, Anhänge, rsa_key*, config.json). Die DB ist pro Nutzer Ende-zu-Ende verschlüsselt – das Backup trotzdem gut schützen.

Server · /opt/vaultwarden/backup.sh
#!/bin/bash
set -e
cd /opt/vaultwarden
STAMP=$(date +%F_%H%M)
docker compose exec -T vaultwarden sqlite3 /data/db.sqlite3 ".backup /data/db-backup.sqlite3"
tar czf /root/vw-$STAMP.tar.gz -C vw-data db-backup.sqlite3 attachments sends rsa_key.pem rsa_key.pub.pem config.json 2>/dev/null || true
find /root -name 'vw-*.tar.gz' -mtime +14 -delete
# optional: zu einer Hetzner Storage Box schieben
# rclone copy /root/vw-$STAMP.tar.gz box:vaultwarden/
Server · bash
chmod +x /opt/vaultwarden/backup.sh
( crontab -l 2>/dev/null; echo "30 3 * * * /opt/vaultwarden/backup.sh" ) | crontab -

Zusätzlich die Hetzner-Server-Backups aktivieren (+20 %) – dann hast du auch bei einem Totalausfall des Servers alles.

+ Mailversand (optional)

Für Einladungen, Passwort-Hinweise, „neues Gerät“-Mails und E-Mail-2FA. Ohne SMTP läuft Vaultwarden trotzdem – nur diese Mails fehlen dann.

Port 25 gesperrt

Hetzner Cloud blockt ausgehend Port 25/465. Nutze einen SMTP-Relay über 587 (Brevo 300 Mails/Tag gratis, Mailgun, Amazon SES). Werte ins /admin-Panel oder in die .env:

Server · /opt/vaultwarden/.env (Ergänzung)
SMTP_HOST=smtp-relay.brevo.com
SMTP_PORT=587
SMTP_SECURITY=starttls
SMTP_FROM=vault@vault.seb4u.com
SMTP_USERNAME=DEIN_RELAY_USER
SMTP_PASSWORD=DEIN_RELAY_KEY

+ Hardening & Updates

  • SIGNUPS_ALLOWED=false lassen. Neue Nutzer nur per Invite im Admin-Panel.
  • ADMIN_TOKEN als Argon2-Hash (wie in Schritt 9), nie im Klartext. Oder /admin nach der Einrichtung ganz abschalten (DISABLE_ADMIN_TOKEN=false + Token leeren).
  • Updates: cd /opt/vaultwarden && docker compose pull && docker compose up -d (alle paar Wochen). OS (Betriebssystem): apt install unattended-upgrades.
  • fail2ban gegen Brute-Force auf Login und /admin – es gibt fertige Filter für Vaultwarden (Log via docker compose logs).
  • 2FA für deinen eigenen Account in der App aktivieren (TOTP oder Passkey).
  • Der Server-Betreiber (= du) kann den verschlüsselten Tresor sehen, nicht dessen Inhalt. Trotzdem: starkes Master-Passwort, Server aktuell halten.
Kritisch bei einem Passwort-Server

Backup außer Haus (restic nach Backblaze B2 / NAS) – der Server ist dein Passwort-Speicher. Und Zirkelschluss vermeiden: den Hetzner-Zugang samt 2FA-Recovery-Codes zusätzlich offline, sonst kommst du bei einem Hetzner-Ausfall an nichts mehr. Rest: die Grundausstattung-Checkliste.

+ Kosten

Preise sind Richtwerte. Hetzner hat 2026 zweimal erhöht (zuletzt 15. Juni: CX/CAX +30–40 %, CPX/CCX über 100 %). Aktuelle Server-Preise, alle Nebenposten, ein Rechner und Beispielrechnungen stehen zentral in Kosten & Budget.

Posten~€/Tagca. €/Monat
Server CAX11 (2 vCPU / 4 GB)~0,13~4
Primary-IP (IPv4)~0,02~0,50
Domain / Subdomain~0,02~0,50–1
Hetzner-Server-Backups (+20 %)~0,03~0,80
Caddy / Let’s Encrypt / Vaultwarden00
Summe~0,20~6
… oder auf einem bestehenden Server mit~0~0 extra

Kein Kill-Switch/Auto-Teardown – ein Passwort-Server soll erreichbar bleiben. Klein dimensionieren, Backups statt Redundanz.

+ Alternativen

OptionKostenBemerkung
Proton Pass (Free)0Cloud, Schweiz, Open Source. Unbegrenzt Geräte/Passwörter, 2FA-Codes gratis, 10 E-Mail-Aliase. Null Aufwand.
Bitwarden (Free)0Cloud. Unbegrenzt, Autofill, Passkeys. Seit Jan 2026 ohne eingebauten 2FA-Authenticator/Anhänge (jetzt Premium, ~20 $/Jahr).
Vaultwarden (diese Anleitung)~6/MonSelbst gehostet, offizielle Bitwarden-Apps, alle Funktionen frei, volle Kontrolle.
Bitwarden offiziell, selbst gehostetServer + ggf. LizenzSchwer: mehrere Container, ~2 GB (Gigabyte) RAM (Random Access Memory), Lizenzdatei für Org-Funktionen. Nur für größere Teams sinnvoll.
KeePassXC + Syncthing/Nextcloud0Kein fremder Server. .kdbx-Datei selbst synchronisieren, mehr Handarbeit.

Nur schnell etwas Kostenloses mit Autofill überall → Proton Pass Free. Volle Kontrolle und du hast eh einen Server → diese Anleitung.

+ Proton Pass Free einrichten

Der schnellste Weg ohne eigenen Server: kostenloser, gehosteter Manager aus der Schweiz, Open Source, mit Autofill auf allen Geräten und eingebautem 2FA-Authenticator. Kein Docker, keine Domain, keine Kreditkarte.

  1. Proton-Konto auf proton.me anlegen (kostenlos). Falls du schon Proton Mail hast – nutzen.
  2. pass.proton.me öffnen – der Tresor wird automatisch angelegt.
  3. Browser-Extension installieren (Chrome, Firefox, Edge, Safari), anmelden. In den Extension-Einstellungen Autofill und „beim Login anbieten“ aktivieren.
  4. Handy-App (iOS/Android) installieren, anmelden. Dann im System als Autofill-Dienst setzen:
    Android: Einstellungen → Passwörter & Konten → Autofill-Dienst → Proton Pass.
    iOS: Einstellungen → Allgemein → AutoFill & Passwörter → Proton Pass.
  5. Daten importieren: pass.proton.me → Einstellungen → Import → Quelle Bitwarden → die .csv aus vault.html (oder aus einem anderen Manager das passende Format). Danach die CSV löschen.
  6. 2FA-Codes: beim Eintrag das Feld 2FA-Secret hinterlegen – Proton Pass generiert den Code und füllt ihn mit aus.
  7. Dein Proton-Konto absichern: Einstellungen → Sicherheit → 2FA aktivieren (Authenticator-App oder Passkey).
Grenzen der Free-Stufe

Unbegrenzt Einträge und Geräte, 1 Tresor, begrenzte geteilte Tresore, 10 Hide-my-email-Aliase. Für die meisten reicht das. Mehr Tresore / unbegrenzt Aliase = Proton Pass Plus (ca. 2–4 €/Monat) oder Proton Unlimited.

⌂ Cockpit