Auf dem Raspberry Pi Zero 2 W wollte ich mal einen HashiCorp Vault installieren. Ich habe dazu ein Kali 32-Bit System verwendet, aber es läuft auch analog auf anderen Systemen.
Ziel ist es per Java und AppRole Workflow auf den Vault mit diesem Workflow zuzugreifen:
Hier die Schritte im Überblick die gezeigt werden:
Teil 1:
–HashiCorp Vault laden und installieren
-User einrichten
-Vault in vault.hcl einrichten
-Quicktest
-Zertifikate für https ergänzen
-Systemservice erstellen
-Zugriff auf Vault CLI Api
-einen non root token einrichten
-Cubbyhole Secrets Engine lesen und schreiben
Teil 2:
-Vault Rollen und Rechte einrichten
-Java Zugriff mit Demo App
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# System updaten sudo apt update && sudo apt upgrade -y # Passende 32-Bit Version für Kali-Linux Arm holen curl -LO https://releases.hashicorp.com/vault/1.20.4/vault_1.20.4_linux_arm.zip # Archive auspacken sudo unzip -o vault_1.20.4_linux_arm.zip -d /usr/local/bin/ # Versions Check vault version # ok, läuft: Vault v1.20.4 (55bd8f18c6c84aa89fdede4850a622c57f03bd7e), built 2025-09-23T13:22:38Z # Verzeichnis & Nutzer anlegen sudo useradd --system --home /etc/vault.d --shell /usr/sbin/nologin vault sudo mkdir -p /etc/vault.d /opt/vault/data sudo chown -R vault:vault /etc/vault.d /opt/vault # Konfigurations Date, anlegen (erst mal per http für Quicktest, oder gleich zu https springen) , IP Adresse anpassen: sudo vi /etc/vault.d/vault.hcl # Inhalt: storage "file" { path = "/opt/vault/data" } listener "tcp" { address = "7.7.7.93:8200" tls_disable = "true" # nur lokal; für Remote TLS konfigurieren } disable_mlock = true ui = true api_addr = "http://7.7.7.93:8200" cluster_addr = "http://7.7.7.93:8201" # Test starte vault mit Konfig Datei: sudo /usr/local/bin/vault server -config=/etc/vault.d/vault.hcl # es läuft: ┌──(thomaswenzlaff㉿pi-kali)-[~] └─$ sudo /usr/local/bin/vault server -config=/etc/vault.d/vault.hcl ==> Vault server configuration: Administrative Namespace: Api Address: http://7.7.7.93:8200 Cgo: disabled Cluster Address: https://7.7.7.93:8201 Environment Variables: HOME, LANG, LC_ALL, LC_TERMINAL, LC_TERMINAL_VERSION, LOGNAME, LS_COLORS, MAIL, PATH, SHELL, SUDO_COMMAND, SUDO_GID, SUDO_HOME, SUDO_TTY, SUDO_UID, SUDO_USER, TERM, USER Go Version: go1.24.6 Listener 1: tcp (addr: "7.7.7.93:8200", cluster address: "7.7.7.93:8201", disable_request_limiter: "false", max_json_array_element_count: "10000", max_json_depth: "300", max_json_object_entry_count: "10000", max_json_string_value_length: "1048576", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled") Log Level: Mlock: supported: true, enabled: false Recovery Mode: false Storage: file Version: Vault v1.20.4, built 2025-09-23T13:22:38Z Version Sha: 55bd8f18c6c84aa89fdede4850a622c57f03bd7e ==> Vault server started! Log data will stream in below: # Eingabe 1 und 1, keys Downloaden: { "keys": [ "96801cfac8d8fb050e2286c153f659999bd195ce21263b07cc19cbda1e16c8b1" ], "keys_base64": [ "loAc+sjY+wUOIobBU/ZZmZvRlc4hJjsHzBnL2h4WyLE=" ], "root_token": "hvs.BCEBFAg5qMrAkbMfc00cKsvi" } # So jetzt soll es mit https und Zertifikate laufen # Zertifikat mit XCA erstellen wie hier schon beschrieben ( http://blog.wenzlaff.de/?s=XCA ) und nach kopieren: /usr/local/share/ca-certificates # update update-ca-certificates # In config https ergänzen: sudo vi /etc/vault.d/vault.hcl cat /etc/vault.d/vault.hcl storage "file" { path = "/opt/vault/data" } # HTTPS listener listener "tcp" { address = "7.7.7.93:8200" # Public Zertifikat: Wird verteilt und von Clients zur Validierung des Vault-Servers genutzt. tls_cert_file = "/usr/local/share/ca-certificates/wenzlaff_pi-kali_vault.crt" # Private Key: Bleibt am Server, niemals öffentlich, dient zur Verschlüsselung und als Authentifizierungsnachweis für TLS. tls_key_file = "/usr/local/share/ca-certificates/wenzlaff_pi-kali_vault.pem" } disable_mlock = true ui = true api_addr = "https://7.7.7.93:8200" cluster_addr = "https://7.7.7.93:8201" sudo /usr/local/bin/vault server -config=/etc/vault.d/vault.hcl # noch ein Systemservice anlegen sudo vi /etc/systemd/system/vault.service [Unit] Description=HashiCorp Vault ConditionFileNotEmpty=/etc/vault.d/vault.hcl [Service] User=vault Group=vault AmbientCapabilities=CAP_IPC_LOCK CapabilityBoundingSet=CAP_SYSLOG CAP_IPC_LOCK ExecStart=/usr/local/bin/vault server -config=/etc/vault.d/vault.hcl ExecReload=/bin/kill --signal HUP $MAINPID KillMode=process KillSignal=SIGINT Restart=on-failure [Install] WantedBy=multi-user.target # Aktivieren & starten sudo systemctl daemon-reload sudo systemctl enable --now vault systemctl status vault --no-pager |
So jetzt läuft der Vault, und wir können über die GUI per https zugreifen mit (IP anpassen): https://7.7.7.93:8200
Nun wollen wir von der Kommandozeile aus auf die Vault CLI zugreifen. Dazu müssen wir einmalig die Adresse setzen, z.B.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
export VAULT_ADDR=https://7.7.7.93:8200 # Dann habe wir Zugriff z.B. mit vault status # Wir bekommen dann z.B. Key Value --- ----- Seal Type shamir Initialized true Sealed false Total Shares 1 Threshold 1 Version 1.20.4 Build Date 2025-09-23T13:22:38Z Storage Type file Cluster Name vault-cluster-ca72947d Cluster ID 2e39f08c-716e-8d82-d18b-a3acb23618fc HA Enabled false # Nun setzen wir erst mal den root Token export VAULT_TOKEN=hvs.BCEBFAg5qMrAkbMfc00cKsvi # nun einen eigenen Token, der nicht root ist erzeugen
vault token create -policy=default #Antwort: # Key Value # --- ----- # token hvs.CAESIJ5s1dbhSt2EMS-8ripWn7FRsOxPWTuvnhM5hp11-1I9Gh4KHGh2cy5tQnh6elYzMWptM0F4cHFZZ3JzZGE4NHk # token_accessor rcH3rGrPwO64yWpQ6YY5Slby # token_duration 768h # token_renewable true # token_policies ["default"] # identity_policies [] # policies ["default"] # diese privaten Token wollen wir nun verwenden # dazu den root-Token durch den eben erzeugten token ersetzen: export VAULT_TOKEN=hvs.CAESIJ5s1dbhSt2EMS-8ripWn7FRsOxPWTuvnhM5hp11-1I9Gh4KHGh2cy5tQnh6elYzMWptM0F4cHFZZ3JzZGE4NHk # Nun machen wir den ersten Eintrag in das cubbyhole (Ablagefach), das immer vorhanden ist und nur mit dem jeweiligen Token zu lesen ist: vault kv put -mount=cubbyhole mindmap derKey=derValue:kleinhirn.eu # Ergebnis: Success! Data written to: cubbyhole/mindmap # wenn man sich an die GUI mit dem Token anmeldet, findet man den Eintrag, solage der Token gültig ist # oder über die CLI kann man ihn wieder lesen: vault read cubbyhole/mindmap # Ergebnis: # Key Value # --- ----- # derKey derValue:kleinhirn.eu # oder vault kv get -mount=cubbyhole mindmap # oder ohne SSL-Zertifikatsprüfung in Testumgebung mit curl curl --insecure -H "X-Vault-Token: hvs.CAESIJ5s1dbhSt2EMS-8ripWn7FRsOxPWTuvnhM5hp11-1I9Gh4KHGh2cy5tQnh6elYzMWptM0F4cHFZZ3JzZGE4NHk" https://10.0.7.93:8200/v1/cubbyhole/mindmap # Ergebnis # {"request_id":"3e898521-0dcb-77b4-2fc0-36538e21664a","lease_id":"","renewable":false,"lease_duration":0,"data": {"derKey":"derValue:kleinhirn.eu"},"wrap_info":null,"warnings":null,"auth":null,"mount_type":"cubbyhole"} |
So sieht der Cubbyhole-Token in der Gui aus:
Cubbyhole ist übrigens eine spezielle Secrets Engine in HashiCorp Vault, die flüchtigen, privaten Speicher pro Token bereitstellt. Jeder Token erhält seinen eigenen, komplett isolierten und nur für diesen Token zugänglichen Speicherplatz – vergleichbar mit eigenen kleinen Fächern (Cubbies) in einem Kindergarten.
Eigenschaften von Cubbyhole
– Isolation: Kein anderer Token (auch nicht der Root-Token) kann auf die Daten eines anderen Cubbyhole zugreifen.
– Lebensdauer: Sobald ein Token verfällt oder widerrufen wird, wird dessen Cubbyhole und alle darin gespeicherten Daten gelöscht.
– Keine Versionierung: Anders als die KV-Engine gibt es keine Versionen oder TTLs für die gespeicherten Daten; Cubbyhole existiert nur solange wie das Token.
– Standardmäßig aktiv: Die Cubbyhole-Engine ist von Beginn an aktiv und kann weder entfernt, verschoben noch mehrfach aktiviert werden.
Hauptanwendungsfälle
– One-Time-Secrets: Sicheres Übermitteln von einmaligen Secrets, z. B. Initialisierungstoken an Applikationen.
– Response Wrapping: Temporäre Speicherung geheimer Daten über einen sogenannten Wrapping-Token, der die Daten an Empfänger weitergibt, ohne die Werte selbst preiszugeben.
Cubbyhole ist also ein temporärer, token-gebundener Speicher, der garantiert, dass sensible Daten nur dem berechtigten Token-Inhaber und für die Lebensdauer des Tokens zur Verfügung stehen.
So, nun kommt der Zugriff über Java auf den Vault, aber das im Teil 2.