Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Sicherheit & Datenschutz 05.07.2026 · 10 min Lesezeit

OpenBao mit Docker installieren: Linux – Zentraler Secrets-Store unter MPL-2.0

OpenBao – der Linux-Foundation-Fork von HashiCorp Vault unter MPL-2.0 – läuft per Docker Compose in 25 Minuten. Diese Anleitung zeigt den vollständigen Weg: compose.yaml, PostgreSQL-Backend, Unseal-Prozess, CLI und Troubleshooting.

OpenBao mit Docker unter Linux installieren: Zentraler Secrets Store mit Docker Container, sicherer Verwaltung von Passwörtern, API Schlüsseln und Zertifikaten, verschlüsselter Speicherung sowie rollenbasierter Zugriffskontrolle für Self Hosting und DevOp

Wer Credentials, TLS-Zertifikate und dynamische Datenbankzugänge zentral verwalten möchte, stand bisher vor einer klaren Wahl: HashiCorp Vault – oder nichts Vergleichbares. Seit HashiCorp 2023 die Lizenz auf BSL gewechselt hat, ist diese Wahl für viele Teams rechtlich heikel geworden. OpenBao löst dieses Problem: Der Fork wird von der Linux Foundation betreut, steht unter der MPL-2.0 und ist vollständig API-kompatibel zu Vault. Mit 6.300+ GitHub-Stars und regelmäßigen Releases (aktuell 2.5.4) ist er kein Experiment mehr, sondern produktionstaugliche Software für DevOps-Teams, Entwickler und KMU-Admins, die einen lizenzrechtlich sauberen Secrets-Store brauchen.

Voraussetzungen

  1. Linux-Host oder VM (Ubuntu 22.04/24.04, Debian 12 oder vergleichbar) mit Docker Engine 24+ und Compose Plugin v2 – wie du Docker und Compose installierst, zeigt die Docker- und Docker-Compose-Grundlage
  2. Mindestens 512 MB RAM (empfohlen: 1 GB+), mindestens 1 GB freier Speicherplatz
  3. Netzwerkzugriff auf Port 8200/TCP (API); für Cluster-Replikation zusätzlich 8201/TCP
  4. Texteditor für config.hcl und .env
  5. Passwortmanager oder sicherer Speicher für Unseal-Schlüssel und Root-Token (z. B. Vaultwarden)
  6. Optional: Reverse Proxy (Traefik, Nginx, Caddy) für HTTPS – in Produktion Pflicht

Eckdaten: Image, Ports, Volumes und Umgebungsvariablen

ParameterWertHinweis
Imageopenbao/openbao:2.5.4Stable-Tag pinnen; Multi-Arch: amd64, arm64, armv7, s390x, riscv64, ppc64le
Alternatives Imageghcr.io/openbao/openbao:2.5.4GitHub Container Registry als Fallback
Port8200:8200API + (ehem.) UI; 8201 nur für Multi-Node-HA
Volume config./config:/openbao/configHCL/JSON-Konfiguration; vor dem ersten Start anlegen
Volume databao_data:/openbao/filePersistenter Datenspeicher (File-Backend)
Volume logsbao_logs:/openbao/logsAudit-Logs; optional, aber empfohlen
Env: BAO_LOG_LEVELinfotrace/debug/info/warn/error
CapabilityIPC_LOCKVerhindert Swap-Auslagerung von Secrets – Pflicht
Useropenbao (non-root)Volumes müssen schreibbar sein

Schritt 1: Projektordner anlegen und vorbereiten

Lege einen dedizierten Ordner für OpenBao an. /opt/openbao/ ist für Server-Dienste die übliche Wahl; auf einem NAS oder als normaler Nutzer geht auch ~/openbao/.

mkdir -p /opt/openbao/config
cd /opt/openbao

Das Unterverzeichnis config/ nimmt gleich die config.hcl auf. Docker legt die Named Volumes (postgres_data, bao_data, bao_logs) automatisch an – dafür sind keine weiteren Verzeichnisse nötig.

Verifizieren: ls -la /opt/openbao/ – du solltest config/ als leeres Verzeichnis sehen.

Schritt 2: .env-Datei anlegen

Alle Passwörter und variablen Parameter kommen in die .env-Datei. Diese Datei darf niemals ins Git-Repository.

# /opt/openbao/.env  –  NICHT in Git einchecken!
POSTGRES_DB=openbao
POSTGRES_USER=openbao
POSTGRES_PASSWORD=SICHER_AENDERN
BAO_LOG_LEVEL=info

Ersetze SICHER_AENDERN durch ein starkes, zufälliges Passwort. Enthält das Passwort Sonderzeichen wie @, / oder ?, müssen diese in der connection_url in der config.hcl URL-kodiert werden (z. B. @%40), sonst schlägt der PostgreSQL-Verbindungsaufbau mit „invalid dsn" fehl.

chmod 600 /opt/openbao/.env

Verifizieren: cat /opt/openbao/.env – alle vier Variablen sichtbar, keine Leerzeilen davor.

Schritt 3: Konfigurationsdatei config.hcl anlegen

OpenBao liest beim Start alle .hcl- und .json-Dateien aus dem gemounteten Konfigurationsverzeichnis. Hier richtest du das PostgreSQL-Storage-Backend ein und deaktivierst TLS für den lokalen Betrieb hinter einem Reverse Proxy.

# /opt/openbao/config/config.hcl

storage "postgresql" {
  connection_url = "postgres://openbao:SICHER_AENDERN@postgres:5432/openbao?sslmode=disable"
  ha_enabled     = "false"
}

listener "tcp" {
  address     = "0.0.0.0:8200"
  tls_disable = "true"
}

api_addr = "http://0.0.0.0:8200"
ui       = false

Passe SICHER_AENDERN an das Passwort aus deiner .env an. Der Hostname postgres entspricht dem Service-Namen im Compose-Stack – Docker löst ihn intern auf. ha_enabled = "false" ist korrekt für Einzelknoten-Betrieb. tls_disable = "true" ist hinter einem Reverse Proxy akzeptabel; ohne vorgelagerten Proxy unbedingt TLS aktivieren, da sonst Root-Token und Secrets im Klartext übertragen werden.

Verifizieren: cat /opt/openbao/config/config.hcl – Storage-Block, Listener und api_addr vollständig und ohne Tippfehler.

Schritt 4: compose.yaml erstellen und Stack starten

Der Stack besteht aus zwei Services: PostgreSQL als Storage-Backend und OpenBao selbst. Der depends_on-Healthcheck stellt sicher, dass PostgreSQL Verbindungen akzeptiert, bevor OpenBao startet.

# /opt/openbao/compose.yaml
services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB:-openbao}
      POSTGRES_USER: ${POSTGRES_USER:-openbao}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD muss in .env gesetzt sein}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-openbao} -d ${POSTGRES_DB:-openbao}"]
      interval: 10s
      timeout: 5s
      retries: 5

  openbao:
    image: openbao/openbao:2.5.4
    restart: unless-stopped
    cap_add:
      - IPC_LOCK
    ports:
      - "8200:8200"
    volumes:
      - ./config:/openbao/config
      - bao_data:/openbao/file
      - bao_logs:/openbao/logs
    environment:
      BAO_LOG_LEVEL: ${BAO_LOG_LEVEL:-info}
    command: ["server", "-config=/openbao/config/config.hcl"]
    depends_on:
      postgres:
        condition: service_healthy

volumes:
  postgres_data:
  bao_data:
  bao_logs:

Wichtige Details: cap_add: IPC_LOCK ist Pflicht, damit OpenBao Secrets im RAM sperren und eine Swap-Auslagerung verhindern kann. Ohne diese Capability gibt OpenBao eine Warnung aus und Secrets könnten unverschlüsselt im Swap-Speicher landen. command: ["server", "-config=..."] überschreibt den Standard-Dev-Modus des offiziellen Images – ohne diesen Eintrag würde OpenBao im Dev-Modus starten, bei dem alle Daten nur im RAM liegen und nach einem Neustart verloren sind.

cd /opt/openbao
docker compose up -d

Verifizieren:

docker compose ps

Erwartete Ausgabe: beide Services zeigen Status: Up, postgres zusätzlich (healthy).

docker compose logs openbao --tail=20

Erwartetes Ergebnis: Zeilen wie core: vault is sealed oder core: security barrier not initialized – das ist korrekt. Keine Fehler zu Port, Volume oder Datenbankverbindung. HTTP 503 von der API in diesem Stadium ist ebenfalls normal und erwartet.

Schritt 5: OpenBao initialisieren und entsiegeln (Unseal)

Nach dem ersten Start befindet sich OpenBao im Sealed-Zustand: Die Barrier ist verschlüsselt und antwortet auf alle API-Anfragen mit HTTP 503. Die Initialisierung erzeugt die fünf Unseal-Schlüssel und den Root-Token.

docker compose exec openbao bao operator init

Die Ausgabe enthält fünf Unseal Keys und einen Initial Root Token. Speichere diese Werte sofort in einem sicheren Passwortmanager – sie können nicht wiederhergestellt werden. Bei Verlust aller Unseal-Schlüssel ist der gesamte Datenspeicher dauerhaft verschlüsselt.

Nun entsiegele OpenBao mit mindestens drei der fünf Schlüssel (Shamir-Verfahren). Führe den Befehl dreimal aus und gib jedes Mal einen anderen Schlüssel ein:

docker compose exec openbao bao operator unseal
# Erster Schlüssel eingeben – Unseal Progress: 1/3
docker compose exec openbao bao operator unseal
# Zweiter Schlüssel – Unseal Progress: 2/3
docker compose exec openbao bao operator unseal
# Dritter Schlüssel – Sealed: false

Nach jedem Container-Neustart muss das Unseal wiederholt werden. Für automatisierte Umgebungen lässt sich Auto-Unseal per AWS KMS, Azure Key Vault oder einem HSM konfigurieren.

Verifizieren:

curl -s http://localhost:8200/v1/sys/health | python3 -m json.tool

Erwartete Ausgabe bei erfolgreichem Unseal: HTTP 200 mit "sealed": false und "initialized": true. HTTP 503 bedeutet, OpenBao ist noch versiegelt. Alternativ direkt per CLI:

docker compose exec openbao bao status

Die Spalte Sealed muss false zeigen.

Schritt 6: Ersten Login und Secret anlegen

Mit dem Root-Token meldest du dich an und kannst sofort Secrets verwalten. In der Praxis solltest du schnellstmöglich weitere Policies und Auth-Methoden einrichten, um den Root-Token danach sicher wegzusperren.

# Root-Token setzen (ersetze tttt... durch deinen echten Token)
export BAO_TOKEN=tttt...
export BAO_ADDR=http://localhost:8200

# KV-Secrets-Engine aktivieren
docker compose exec -e BAO_TOKEN=$BAO_TOKEN -e BAO_ADDR=$BAO_ADDR openbao \
  bao secrets enable -path=secret kv-v2

# Erstes Secret schreiben
docker compose exec -e BAO_TOKEN=$BAO_TOKEN -e BAO_ADDR=$BAO_ADDR openbao \
  bao kv put secret/meine-app db_password="supersicher" api_key="abc123"

# Secret lesen
docker compose exec -e BAO_TOKEN=$BAO_TOKEN -e BAO_ADDR=$BAO_ADDR openbao \
  bao kv get secret/meine-app

Wer lieber mit der REST-API arbeitet, kann denselben Weg per curl gehen – alle Vault-API-Endpunkte sind vollständig kompatibel.

curl -s -H "X-Vault-Token: $BAO_TOKEN" \
  http://localhost:8200/v1/secret/data/meine-app | python3 -m json.tool

Verifizieren: Die Ausgabe zeigt "db_password": "supersicher" und "api_key": "abc123" unter dem Schlüssel data.data. HTTP 403 deutet auf einen ungültigen Token hin; HTTP 404 bedeutet, der Pfad existiert noch nicht.

Schritt 7: Container aktualisieren

OpenBao erscheint alle ein bis zwei Monate mit einem neuen Release. Beim Update das Image-Tag in der compose.yaml anpassen, dann:

cd /opt/openbao
docker compose pull
docker compose up -d

Nach dem Neustart ist OpenBao wieder versiegelt – führe das Unseal-Prozedere (drei Schlüssel) erneut durch. Automatisches Container-Monitoring für neue Releases richtest du z. B. mit Diun oder WUD ein.

Verifizieren:

docker compose ps
docker compose exec openbao bao version

Die neue Versionsnummer muss dem Tag in der compose.yaml entsprechen.

Troubleshooting / Typische Fehler

  1. HTTP 503 nach dem Start: OpenBao ist versiegelt. Normal nach jedem (Neu-)Start. Lösung: docker compose exec openbao bao operator unseal dreimal mit je einem anderen Unseal-Schlüssel aufrufen.
  2. HTTP 501 – not initialized: Die Initialisierung wurde noch nicht durchgeführt. Lösung: docker compose exec openbao bao operator init ausführen und die Ausgabe sofort sicher speichern.
  3. „failed to lock memory" / IPC_LOCK-Warnung: cap_add: IPC_LOCK fehlt in der compose.yaml. Eintrag ergänzen und den Stack neu starten. Ohne diesen Eintrag können Secrets in den Swap-Speicher gelangen.
  4. „invalid dsn" beim Datenbankstart: Das PostgreSQL-Passwort enthält Sonderzeichen (@, /, ?, #), die in der connection_url URL-kodiert werden müssen. Beispiel: @%40.
  5. „error creating core: failed to create storage": PostgreSQL war noch nicht bereit, als OpenBao startete. Der depends_on-Healthcheck in der compose.yaml verhindert das – prüfe, ob der Healthcheck korrekt konfiguriert ist. Notfalls docker compose restart openbao.
  6. „permission denied" beim Datei-Backend: Das Volume-Verzeichnis gehört nicht dem Container-User openbao. Lösung: UID/GID des Containers prüfen mit docker compose exec openbao id und Volume-Rechte entsprechend anpassen.
  7. Alle Secrets weg nach Neustart: Du betreibst OpenBao im Dev-Modus. Erkennbar daran, dass kein Unseal nötig war. Lösung: command: ["server", "-config=/openbao/config/config.hcl"] in der compose.yaml setzen und den Stack neu aufsetzen.
  8. Unseal-Schlüssel verloren: Bei Verlust aller Schlüssel ist der Datenspeicher unwiederbringlich verschlüsselt – keine Hintertür, keine Recovery. Einzige Option: Neustart mit leerem Volume. Prävention: Schlüssel per Shamir-Verfahren auf mehrere Personen verteilen oder Auto-Unseal einrichten.

Häufige Fragen

Wie unterscheidet sich OpenBao von HashiCorp Vault?

OpenBao ist ein direkter Fork von Vault, der nach dem BSL-Lizenzwechsel von HashiCorp im Jahr 2023 unter MPL-2.0 weiterentwickelt wird. API, CLI-Syntax und Konfigurationsformat sind weitgehend identisch. Die wesentlichen Unterschiede: Der CLI-Befehl heißt bao statt vault, Umgebungsvariablen beginnen mit BAO_ statt VAULT_, und die Web-UI wurde in OpenBao ab Version 2.1.0 entfernt. Für Teams, die bereits Vault nutzen, ist eine Migration deshalb vergleichsweise reibungsarm.

Muss ich OpenBao nach jedem Neustart manuell entsiegeln?

Im Standardbetrieb mit Shamir-Seal ja – nach jedem Neustart müssen mindestens drei der fünf Unseal-Schlüssel eingegeben werden. Für automatisierten Betrieb lässt sich Auto-Unseal per AWS KMS, Azure Key Vault, GCP KMS oder einem Hardware-Security-Modul (PKCS#11) konfigurieren. Damit öffnet sich OpenBao beim Start automatisch, ohne manuellen Eingriff.

Kann ich OpenBao ohne PostgreSQL betreiben?

Ja – mit dem File-Storage-Backend (storage "file" { path = "/openbao/file" }) ist keine externe Datenbank erforderlich. Das File-Backend ist einfacher einzurichten, unterstützt aber kein High Availability. Für Produktion mit Ausfallsicherheit empfehlen sich das integrierte Raft-Backend oder PostgreSQL.

Gibt es eine Web-Oberfläche für OpenBao?

Nein – ab Version 2.1.0 wurde die Web-UI entfernt. Verwaltung erfolgt ausschließlich per CLI (bao) oder REST-API. Als Alternative können inoffizielle Community-Tools oder direkte API-Abfragen per curl genutzt werden. Die CLI deckt alle Funktionen vollständig ab.

Welche Ports müssen in der Firewall freigegeben werden?

Für Einzelknoten-Betrieb genügt Port 8200/TCP (API). Port 8201/TCP wird nur für Cluster-Kommunikation zwischen mehreren OpenBao-Knoten benötigt und muss nicht nach außen freigegeben werden. Hinter einem Reverse Proxy (Traefik, Nginx, Caddy) reicht es, nur den Proxy-Port (443) öffentlich zu machen.

Wie sichere ich die OpenBao-Daten?

Die Daten liegen im Docker Volume bao_data (File-Backend) bzw. in der PostgreSQL-Datenbank (Volume postgres_data). Für ein zuverlässiges Backup bietet sich eine Kombination aus pg_dump und offsite-Synchronisierung an – wie das funktioniert, zeigt die Anleitung zu PostgreSQL-Backup mit cron und rclone. Bewahre die Unseal-Schlüssel und den Root-Token getrennt von den Datensicherungen auf.

Ist OpenBao für den produktiven Einsatz geeignet?

Ja – das PostgreSQL-Backend gilt als „production ready", der Codebasis liegt der bewährte HashiCorp-Vault-Kern zugrunde, und die Linux Foundation gewährleistet langfristige Pflege unter klarer Open-Source-Lizenz. Für Produktion solltest du TLS (oder einen vorgelagerten Reverse Proxy mit HTTPS), Auto-Unseal und regelmäßige Backups einrichten. Wie du einen Reverse Proxy mit automatischem HTTPS bereitstellst, zeigt Traefik als Docker-Reverse-Proxy.

Fazit

OpenBao ist die konsequente Antwort auf den HashiCorp-Lizenzwechsel: API-kompatibler Vault-Fork, MPL-2.0, Linux Foundation – kein Lizenzrisiko, keine proprietären Abhängigkeiten. Der Betrieb per Docker Compose ist in 25 Minuten eingerichtet; das PostgreSQL-Backend macht den Stack produktionstauglich. Der entscheidende operative Unterschied zu vielen anderen Self-Hosting-Projekten ist der Unseal-Prozess: Unseal-Schlüssel und Root-Token sind nicht wiederherstellbar und müssen von Anfang an sicher aufbewahrt werden. Wer das verinnerlicht und Auto-Unseal für automatisierten Betrieb einplant, bekommt mit OpenBao einen vollständig selbst kontrollierten, lizenzrechtlich sauberen Secrets-Store – ohne Abstriche beim Funktionsumfang.

Weiterführende Anleitungen und Quellen

  1. Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only für den Produktivbetrieb
  2. Vaultwarden produktiv betreiben: Argon2-Admin-Token, Fail2Ban und sicheres Backup
  3. Traefik als Docker-Reverse-Proxy mit automatischem HTTPS
  4. PostgreSQL-Backup automatisieren mit cron und rclone
  5. Single Sign-On für den Self-Hosted-Stack: Authentik vs. Authelia mit Traefik Forward-Auth

Offizielle Quellen: OpenBao Installationsdokumentation · GitHub-Repository · Docker Hub Image

Passende Anleitungen auf S-EDV

  1. PostgreSQL schließt elf Sicherheitslücken in den Versionen 14 bis 18
  2. CVE-2022-0492: CISA warnt vor aktiv ausgenutztem Container-Escape im Linux-Kerne
  3. Restic Backup auf Linux und Windows einrichten und automatisieren (cron/Task Sch