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.
SQLite-DB liegt hier
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.
Server-Basis
durcharbeiten (nur hcloud + ssh nötig).
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).
$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"
Fünf Zeilen, drei Regeln – der ganze Unterschied steckt in --source-ips:
| Schalter | steht bei | bewirkt |
|---|---|---|
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. |
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)
#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.
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:
| Typ | Name | Wert |
|---|---|---|
| A | vault.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:
ssh root@<IP>
mkdir -p /opt/vaultwarden && cd /opt/vaultwarden
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
{
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
cd /opt/vaultwarden
docker compose up -d
docker compose logs -f caddy # "certificate obtained" abwarten, dann Strg+C
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.
# 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
ADMIN_TOKEN='$argon2id$v=19$m=65540,t=3,p=4$....'
In docker-compose.yml beim Dienst vaultwarden ergänzen / ändern:
env_file: .env
environment:
DOMAIN: "https://vault.seb4u.com"
SIGNUPS_ALLOWED: "false"
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.
#!/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/
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.
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:
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=falselassen. Neue Nutzer nur per Invite im Admin-Panel.- ADMIN_TOKEN als Argon2-Hash (wie in Schritt 9), nie im Klartext.
Oder
/adminnach 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 viadocker 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.
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 | ~€/Tag | ca. €/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 / Vaultwarden | 0 | 0 |
| 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
| Option | Kosten | Bemerkung |
|---|---|---|
| Proton Pass (Free) | 0 | Cloud, Schweiz, Open Source. Unbegrenzt Geräte/Passwörter, 2FA-Codes gratis, 10 E-Mail-Aliase. Null Aufwand. |
| Bitwarden (Free) | 0 | Cloud. Unbegrenzt, Autofill, Passkeys. Seit Jan 2026 ohne eingebauten 2FA-Authenticator/Anhänge (jetzt Premium, ~20 $/Jahr). |
| Vaultwarden (diese Anleitung) | ~6/Mon | Selbst gehostet, offizielle Bitwarden-Apps, alle Funktionen frei, volle Kontrolle. |
| Bitwarden offiziell, selbst gehostet | Server + ggf. Lizenz | Schwer: mehrere Container, ~2 GB (Gigabyte) RAM (Random Access Memory), Lizenzdatei für Org-Funktionen. Nur für größere Teams sinnvoll. |
| KeePassXC + Syncthing/Nextcloud | 0 | Kein 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.
- Proton-Konto auf proton.me anlegen (kostenlos). Falls du schon Proton Mail hast – nutzen.
- pass.proton.me öffnen – der Tresor wird automatisch angelegt.
- Browser-Extension installieren (Chrome, Firefox, Edge, Safari), anmelden. In den Extension-Einstellungen Autofill und „beim Login anbieten“ aktivieren.
- 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. - Daten importieren:
pass.proton.me→ Einstellungen → Import → Quelle Bitwarden → die.csvausvault.html(oder aus einem anderen Manager das passende Format). Danach die CSV löschen. - 2FA-Codes: beim Eintrag das Feld 2FA-Secret hinterlegen – Proton Pass generiert den Code und füllt ihn mit aus.
- Dein Proton-Konto absichern: Einstellungen → Sicherheit → 2FA aktivieren (Authenticator-App oder Passkey).
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.