Ohne authentik gab es nur den Notfall-Admin – ein geteiltes Konto ohne Rollen und ohne erkennbare Akteure im Audit-Log. Admins legen jetzt lokale Konten an; sshkv erzeugt ein Einmal-Passwort, das bei der ersten Anmeldung ersetzt wird, danach ist TOTP Pflicht. Rollen, Sperren (beendet Sitzungen sofort) und Zurücksetzen unter Einstellungen → Benutzer, nur für Admins mit frischer Bestätigung. SSHKV_LOKALE_KONTEN=0 schaltet lokale Konten ab; der Notfall-Admin bleibt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5.6 KiB
Installation und Betrieb
SSHKeyVault läuft als Docker-Compose-Stapel aus drei Diensten plus einem einmaligen Migrationslauf:
| Dienst | Aufgabe | Netz | Geheimnisse |
|---|---|---|---|
db |
PostgreSQL 17 | nur intern (internal: true) |
Datenbankpasswort |
migrate |
Schema einspielen, Notfall-Admin und Vorlagen anlegen (läuft bei jedem Start einmal) | intern | Notfall-Passwort beim ersten Start |
web |
Weboberfläche (Port 3400) | intern + nach außen zum OIDC-Anbieter | SSHKV_APP_SECRET, OIDC-Client-Secret – kein Master-Key |
worker |
SSH zu den Hosts, Ver-/Entschlüsselung, Zeitpläne | intern + zu den Hosts | Master-Key (Docker-Secret), SSHKV_APP_SECRET |
Voraussetzungen
- Linux-Host mit Docker und Docker Compose v2, im internen Netz bzw. nur per VPN erreichbar.
- Der Worker muss die zu verwaltenden Hosts per SSH erreichen (Port 22 oder den jeweiligen Port).
- authentik (oder ein anderer OIDC-Anbieter) für die Anmeldung.
- Ein Reverse Proxy mit TLS vor der Weboberfläche.
Schritt für Schritt
sudo mkdir -p /opt/sshkv && cd /opt/sshkv
git clone <repo> . # oder Release entpacken
cp .env.example .env && chmod 600 .env
In .env eintragen (Kommentare in der Datei erklären jede Variable):
POSTGRES_PASSWORD–openssl rand -hex 24SSHKV_APP_SECRET–openssl rand -base64 48SSHKV_APP_URL– die Adresse, unter der Benutzer sshkv aufrufen, z. B.https://sshkv.intern.example.deSSHKV_BREAKGLASS_PASSWORD– mindestens 16 Zeichen; Notfall-AdminnotfallSSHKV_OIDC_*– siehe unten
Master-Key erzeugen und nur für den Worker lesbar machen:
sudo mkdir -p geheim
sudo sh -c 'head -c 32 /dev/urandom > geheim/master.key'
sudo chown 1001:1001 geheim/master.key && sudo chmod 400 geheim/master.key
Starten:
docker compose up -d --build
docker compose logs -f worker # „sshkv-worker … bereit“
Beim ersten Start legt migrate das Schema, den Notfall-Admin und die eingebauten Vorlagen an; der
Worker erzeugt den Deployment-Key der Instanz. Danach sofort den Master-Key sichern
(sicherung.md).
authentik einrichten
- Provider „OAuth2/OpenID Provider“ anlegen: Client-Typ confidential, Redirect-URI
https://sshkv.intern.example.de/api/auth/oidc/rueckruf, Scopesopenid profile emailund ein Scope-Mapping, das die Gruppen als Claimgroupsliefert (in authentik Standard). - Application „SSHKeyVault“ mit diesem Provider anlegen.
- Gruppen
sshkv-admins,sshkv-operators,sshkv-readersanlegen und Benutzer zuordnen (Namen änderbar überSSHKV_OIDC_GROUP_*). Wer in keiner Gruppe ist, kommt nicht hinein. - In
.env:SSHKV_OIDC_ISSUER=https://authentik.example.de/application/o/sshkv/,SSHKV_OIDC_CLIENT_ID,SSHKV_OIDC_CLIENT_SECRET,SSHKV_OIDC_NAME=authentik.
Erneute Bestätigung vor kritischen Aktionen schickt prompt=login und max_age=0; sshkv prüft
auth_time im ID-Token. authentik liefert auth_time standardmäßig.
| Rolle | darf |
|---|---|
| Leser | alles ansehen, eigene Public Keys hinterlegen |
| Operator | zusätzlich Hosts verwalten, Host-Keys bestätigen, Schlüssel erzeugen, Public Keys ausrollen, abgleichen |
| Admin | zusätzlich Private Keys ausrollen/anzeigen/löschen, Zielkonten mit sudo, Massenwiderruf, Einstellungen, Vorlagen |
Ohne authentik starten: lokale Konten
authentik ist nicht Pflicht. Ohne SSHKV_OIDC_* zeigt die Anmeldeseite nur das Formular für
lokale Konten und den Notfallzugang:
- Als Notfall-Admin anmelden (TOTP einrichten).
- Einstellungen → „Konten verwalten“ → für jede Person ein Konto mit passender Rolle anlegen und das Einmal-Passwort auf sicherem Weg weitergeben.
- Für den Alltag die eigenen Konten nutzen, den Notfall-Admin nur im Notfall – so bleibt im Audit-Log erkennbar, wer was getan hat.
Später lässt sich authentik dazuschalten; lokale Konten und OIDC laufen nebeneinander.
SSHKV_LOKALE_KONTEN=0 schaltet die lokalen Konten danach ab.
Reverse Proxy (Beispiel Caddy)
sshkv.intern.example.de {
tls internal # oder das interne Zertifikat
@extern not remote_ip 10.0.0.0/8 192.168.0.0/16
respond @extern 403
reverse_proxy 127.0.0.1:3400
}
Wichtig: SSHKV_APP_URL muss die Adresse mit https:// sein – davon hängen Secure-Cookie und
OIDC-Rückruf ab.
Hosts vorbereiten
- Debian/Ubuntu mit
openssh-server,sudo,runuser(util-linux),base64,sha256sum,visudo(bei Dienstbenutzer) – auf Standardinstallationen vorhanden. - Für den Bootstrap per Passwort einmalig ein Konto mit Passwort-Login (root oder ein Benutzer mit sudo). Danach kann Passwort-Login aus; sshkv zeigt den sshd-Befund an.
Aktualisieren
cd /opt/sshkv
sudo bash deploy/sichern.sh
git pull
docker compose up -d --build # migrate spielt neue Migrationen ein
Variablen (Auswahl)
| Variable | Bedeutung |
|---|---|
SSHKV_SYNC_CRON |
Zeitplan des Abgleichs (Standard 30 2 * * *, Europe/Berlin) |
SSHKV_MELDUNG_CRON |
tägliche Zusammenfassung der Benachrichtigungen (Standard 0 7 * * *); geänderte Host-Keys gehen alle 5 Minuten sofort hinaus |
SSHKV_SYSLOG_HOST/_PORT/_PROTOKOLL |
Kopie des Protokolls an einen Syslog-Server (RFC 5424, UDP oder TCP) |
SSHKV_SYSLOG_FACILITY / _APPNAME |
Facility (Standard authpriv) und App-Name (Standard sshkv) |
SSHKV_WORKER_USER |
Benutzer des Worker-Containers, falls die Master-Key-Datei nicht UID 1001 gehört |
SSHKV_BIND / SSHKV_PORT |
Bindeadresse/Port der Weboberfläche (Standard 127.0.0.1:3400) |