Eine Einführung in den Tresorraum

1. Überblick

In diesem Lernprogramm werden wir Hashicorps Vault erkunden - ** ein beliebtes Werkzeug für die sichere Verwaltung vertraulicher Informationen in modernen Anwendungsarchitekturen.

Zu den wichtigsten Themen, die wir behandeln werden, gehören:

  • Welches Problem versucht Vault zu lösen?

  • Architektur und Hauptkonzepte von Vault

  • Einrichtung einer einfachen Testumgebung

  • Interaktion mit Vault mithilfe des Befehlszeilentools

2. Das Problem mit sensiblen Informationen

Bevor wir uns mit Vault beschäftigen, versuchen wir, das Problem zu verstehen, das es zu lösen versucht: sensibles Informationsmanagement.

  • Die meisten Anwendungen benötigen Zugriff auf vertrauliche Daten, um ordnungsgemäß arbeiten zu können ** . Beispielsweise kann eine E-Commerce-Anwendung irgendwo einen Benutzernamen/ein Kennwort haben, um eine Verbindung zu ihrer Datenbank herzustellen. Möglicherweise sind auch API-Schlüssel für die Integration mit anderen Dienstanbietern erforderlich, beispielsweise mit Zahlungsgateways, Logistik und anderen Geschäftspartnern.

Datenbankanmeldeinformationen und API-Schlüssel sind einige Beispiele für vertrauliche Informationen, die wir benötigen, um unsere Anwendungen auf sichere Art und Weise zu speichern.

Eine einfache Lösung besteht darin, diese Anmeldeinformationen in einer Konfigurationsdatei zu speichern und beim Start zu lesen. Das Problem bei diesem Ansatz ist jedoch offensichtlich. Wer Zugriff auf diese Datei hat, hat die gleichen Datenbankberechtigungen wie unsere Anwendung - in der Regel vollen Zugriff auf alle gespeicherten Daten.

Wir können versuchen, die Dinge etwas schwieriger zu gestalten, indem wir diese Dateien verschlüsseln. Dieser Ansatz wird jedoch nicht viel zur allgemeinen Sicherheit beitragen.

Hauptsächlich, weil unsere Anwendung Zugriff auf den Hauptschlüssel haben muss.

Wenn Verschlüsselung auf diese Weise verwendet wird, wird nur ein falsches Sicherheitsgefühl erreicht.

Moderne Anwendungen und Cloud-Umgebungen erhöhen die Komplexität: Verteilte Dienste, mehrere Datenbanken, Nachrichtensysteme usw. sorgen dafür, dass vertrauliche Informationen überall verbreitet werden, wodurch das Risiko einer Sicherheitsverletzung erhöht wird.

Also was können wir tun? Lasst es uns im Tresorraum!

3. Was ist Vault?

Hashicorp Vault befasst sich mit dem Problem der Verwaltung vertraulicher Informationen - ein secret im Sprachgebrauch von Vault. "Verwalten" bedeutet in diesem Zusammenhang, dass Vault alle Aspekte einer sensiblen Information kontrolliert ** : Erzeugung, Speicherung, Verwendung und nicht zuletzt die Sperrung.

Hashicorp bietet zwei Versionen von Vault an. Die in diesem Artikel verwendete Open-Source-Version kann auch in kommerziellen Umgebungen kostenlos verwendet werden. Es ist auch eine kostenpflichtige Version verfügbar, die technischen Support für verschiedene SLAs und zusätzliche Funktionen wie HSM-Unterstützung (Hardware Security Module) umfasst.

3.1. Die Architektur

Die Architektur von Vault ist täuschend einfach. Seine Hauptkomponenten sind:

  • Ein Persistenz-Backend - Speicher für alle Geheimnisse

  • Ein API-Server, der Clientanforderungen verarbeitet und Vorgänge ausführt

Geheimnisse ** Eine Anzahl von __secret-Engines, __e für jeden unterstützten Geheimtyp

Art

Durch das Delegieren der gesamten geheimen Abwicklung an Vault können wir einige Sicherheitsprobleme verringern:

  • Unsere Anwendungen müssen nicht mehr gespeichert werden - fragen Sie einfach Vault

wenn nötig und verwerfen ** Wir können kurzlebige Geheimnisse verwenden, wodurch das "Fenster von" eingeschränkt wird

Gelegenheit “, wo ein Angreifer ein gestohlenes Geheimnis verwenden kann

Vault verschlüsselt alle Daten mit einem Verschlüsselungsschlüssel, bevor sie in den Laden geschrieben werden. Dieser Verschlüsselungsschlüssel wird durch einen weiteren Schlüssel - den Hauptschlüssel, der nur beim Start verwendet wird - verschlüsselt.

Ein wichtiger Punkt bei der Implementierung von Vault ist, dass der Hauptschlüssel nicht auf dem Server gespeichert wird. Dies bedeutet, dass nicht einmal Vault nach dem Start auf die gespeicherten Daten zugreifen kann. An diesem Punkt wird gesagt, dass sich eine Vault-Instanz in einem versiegelten Zustand befindet.

Später gehen wir die Schritte durch, die zum Generieren des Hauptschlüssels und zum Entsiegeln einer Vault-Instanz erforderlich sind.

Nach dem Versiegeln kann Vault API-Anforderungen akzeptieren. Für diese Anforderungen ist natürlich eine Authentifizierung erforderlich, sodass wir wissen, wie Vault Clients authentifiziert und entscheidet, was sie tun können oder nicht.

3.2. Authentifizierung

Um auf Geheimnisse in Vault zugreifen zu können, muss sich ein Client mit einer der unterstützten Methoden authentifizieren. Die einfachste Methode verwendet Tokens. Hierbei handelt es sich lediglich um Zeichenfolgen, die bei jeder API-Anforderung mit einem speziellen HTTP-Header gesendet werden.

Bei der Erstinstallation generiert Vault automatisch ein "Root-Token".

Dieses Token ist das Äquivalent als Root-Superuser in Linux-Systemen. Daher sollte seine Verwendung auf ein Minimum beschränkt sein. Als bewährte Methode sollten Sie dieses Stammtoken verwenden, um andere Token mit weniger Berechtigungen zu erstellen und sie dann zu widerrufen. Dies ist jedoch kein Problem, da wir später ein anderes Root-Token mit nicht gesiegelten Schlüsseln generieren können.

Vault unterstützt auch andere Authentifizierungsmechanismen wie LDAP-, JWT- und TLS-Zertifikate. Alle diese Mechanismen bauen auf dem grundlegenden Token-Mechanismus auf: Sobald Vault unseren Client überprüft, wird ein Token bereitgestellt, mit dem wir auf andere APIs zugreifen können.

Mit Token sind einige Eigenschaften verknüpft. Die Haupteigenschaften sind:

  • Eine Gruppe von zugeordneten Policies (siehe nächster Abschnitt)

  • Zeit zu leben

  • Kann es erneuert werden?

  • Maximale Nutzungsanzahl

Wenn nichts anderes gesagt wird, bilden die von Vault erstellten Token eine Eltern-Kind-Beziehung. Ein untergeordnetes Token kann höchstens dieselbe Berechtigungsstufe wie das übergeordnete Element besitzen.

Das Gegenteil trifft nicht zu: Wir können - und tun dies in der Regel - ein untergeordnetes Token mit restriktiven Richtlinien. Ein weiterer wichtiger Aspekt dieser Beziehung:

Wenn ein Token ungültig wird, werden auch alle untergeordneten Token und ihre Nachkommen ungültig gemacht

3.3. Richtlinien

  • Richtlinien definieren genau, auf welche Geheimnisse ein Client zugreifen kann und welche Operationen er damit ausführen kann. Mal sehen, wie eine einfache Richtlinie aussieht:

path "secret/accounting" {
    capabilities =["read"]}

Hier haben wir die HCL-Syntax (Hashicorp’s Configuration Language) verwendet, um unsere Richtlinie zu definieren. Vault unterstützt auch JSON für diesen Zweck. In unseren Beispielen halten wir uns jedoch an HCL, da es einfacher zu lesen ist.

  • Richtlinien in Vault sind standardmäßig "verweigern" ** . Ein an diese Beispielrichtlinie angehängtes Token erhält Zugriff auf unter secret/accounting gespeicherte Geheimnisse und sonst nichts. Zum Zeitpunkt der Erstellung kann ein Token an mehrere Richtlinien angehängt werden. Dies ist sehr nützlich, da wir damit kleinere Richtlinien erstellen, testen und nach Bedarf anwenden können.

Ein weiterer wichtiger Aspekt der Politik ist, dass sie die Lazy-Evaluation nutzen. Dies bedeutet, dass wir eine bestimmte Richtlinie aktualisieren können und alle Token sofort betroffen sind.

Die bisher beschriebenen Richtlinien werden auch als Zugriffssteuerungslisten-Richtlinien oder ACL-Richtlinien bezeichnet. Vault unterstützt außerdem zwei zusätzliche Richtlinientypen: EGP- und RGP-Richtlinien. Diese sind nur in den kostenpflichtigen Versionen verfügbar und erweitern die grundlegende Richtliniensyntax um die Unterstützung Sentinel .

Wenn verfügbar, können wir in unseren Richtlinien zusätzliche Attribute wie Tageszeit, mehrere Authentifizierungsfaktoren, Herkunft des Client-Netzwerks usw. berücksichtigen. Beispielsweise können wir eine Richtlinie definieren, die den Zugriff auf ein bestimmtes Geheimnis nur während der Geschäftszeiten ermöglicht.

Weitere Einzelheiten zur Richtliniensyntax finden Sie in der Dokumentation zu Vault .

4. Geheime Typen

Vault unterstützt eine Reihe verschiedener geheimer Typen, die verschiedene Anwendungsfälle behandeln:

  • Key-Value: einfache Paare von statischen Schlüsselwerten

  • Dynamisch generierte Anmeldeinformationen : Wird auf Anforderung von Vault generiert

von einem Kunden ** Cryptographic keys : Wird verwendet, um kryptographische Funktionen mit auszuführen

Kundendaten

Jeder geheime Typ wird durch die folgenden Attribute definiert:

  • Ein mount point, , der sein REST-API-Präfix definiert

  • Eine Reihe von Vorgängen, die über die entsprechende API verfügbar gemacht werden

  • Eine Reihe von Konfigurationsparametern

Auf eine bestimmte geheime Instanz kann über einen path zugegriffen werden, ähnlich wie in einem Verzeichnisbaum in einem Dateisystem. Die erste Komponente dieses Pfads entspricht dem __mount-Punkt, an dem sich alle Geheimnisse dieses Typs befinden .

Zum Beispiel entspricht der String _secret/my-application dem Pfad, unter dem Schlüsselpaare für my-application_ gefunden werden können.

4.1. Schlüsselwert-Geheimnisse

  • Schlüsselwert-Geheimnisse sind, wie der Name schon sagt, einfache Paare, die unter einem bestimmten Pfad verfügbar sind. Zum Beispiel können wir das Paar foo = bar unter dem Pfad /secret/my-application speichern.

Später verwenden wir denselben Pfad, um dasselbe Paar oder dieselben Paare abzurufen. Mehrere Paare können unter demselben Pfad gespeichert werden.

Vault unterstützt drei Arten von Schlüsselwertgeheimnissen:

  • Nichtversionierte Schlüsselpaare , wobei Aktualisierungen vorhandene Werte ersetzen

  • Versioned Key-Pairs, , die eine konfigurierbare Anzahl von alten beibehalten

Versionen ** Cubbyhole , ein spezieller Typ von nicht versionierten Schlüsselpaaren, deren Werte

sind auf ein bestimmtes access-token (mehr dazu später) beschränkt.

Schlüsselwert-Geheimnisse sind von Natur aus statisch, daher gibt es kein Konzept für einen damit verbundenen Ablauf. Der Hauptanwendungsfall für diese Art von Geheimnis ist das Speichern von Anmeldeinformationen für den Zugriff auf externe Systeme, z. B. API-Schlüssel.

In solchen Szenarien handelt es sich bei den Aktualisierungen der Berechtigungsnachweise um einen halbmanuellen Prozess, bei dem normalerweise neue Berechtigungsnachweise angefordert werden müssen und die Vault-Befehlszeile oder die Benutzeroberfläche zur Eingabe der neuen Werte verwendet wird.

4.2. Dynamisch erzeugte Geheimnisse

  • Dynamische Geheimnisse werden von Vault schnell generiert, wenn Sie von einer Anwendung dazu aufgefordert werden ** Vault unterstützt verschiedene Arten von dynamischen Geheimnissen, einschließlich der folgenden:

  • Datenbankanmeldeinformationen

  • SSH-Schlüsselpaare

  • X.509-Zertifikate

  • AWS-Berechtigungsnachweise

  • Google Cloud-Dienstkonten

  • Active Directory-Konten

Alle diese folgen demselben Verwendungsmuster. Zunächst konfigurieren wir die geheime Engine mit den Details, die erforderlich sind, um eine Verbindung zum zugehörigen Dienst herzustellen.

Dann definieren wir ein oder mehrere Rollen, die die eigentliche geheime Schöpfung beschreiben.

Nehmen wir als Beispiel die geheime Datenbank-Engine. Zunächst müssen wir Vault mit allen Benutzerdatenbankverbindungsdetails konfigurieren, einschließlich der Anmeldeinformationen eines bereits vorhandenen Benutzers mit Administratorrechten, um neue Benutzer zu erstellen.

Dann erstellen wir eine oder mehrere Rollen (Vault-Rollen, nicht Datenbankrollen), die die tatsächlichen SQL-Anweisungen enthalten, die zum Erstellen eines neuen Benutzers verwendet werden. Dazu gehören in der Regel nicht nur die Anweisung zur Benutzererstellung, sondern auch alle erforderlichen grant -Anweisungen, die für den Zugriff auf Schemaobjekte (Tabellen, Ansichten usw.) erforderlich sind.

Wenn ein Client auf die entsprechende API zugreift, erstellt Vault mit den angegebenen Anweisungen einen neuen temporären Benutzer in der Datenbank und gibt seine Berechtigungsnachweise zurück ** . Der Client kann dann diese Anmeldeinformationen verwenden, um während des Zeitraums, der durch das Time-to-Live-Attribut der angeforderten Rolle definiert wird, auf die Datenbank zuzugreifen.

Sobald ein Berechtigungsnachweis seine Ablaufzeit erreicht, widerruft Vault automatisch alle mit diesem Benutzer verknüpften Berechtigungen. Ein Client kann Vault auch dazu auffordern, diese Berechtigungsnachweise zu erneuern. Der Erneuerungsprozess wird nur durchgeführt, wenn er vom jeweiligen Datenbanktreiber unterstützt und von der zugeordneten Richtlinie zugelassen wird.

4.3. Kryptographische Schlüssel

Geheime Engines des Typs behandeln kryptografische Funktionen wie Verschlüsselung, Entschlüsselung, Signieren usw. Alle diese Vorgänge verwenden kryptografische Schlüssel, die intern von Vault generiert und gespeichert werden ** . Wenn dies nicht ausdrücklich gesagt wird, wird Vault niemals einen bestimmten kryptographischen Schlüssel verfügbar machen.

Mit der zugehörigen API können Clients Vault-Klartextdaten senden und eine verschlüsselte Version davon erhalten. Das Gegenteil ist auch möglich: Wir können verschlüsselte Daten senden und erhalten den ursprünglichen Text zurück.

Derzeit gibt es nur eine Engine dieses Typs: die Transit Engine.

Diese Engine unterstützt gängige Schlüsseltypen wie RSA und ECDSA sowie __Convergent Encryption. Bei Verwendung dieses Modus führt ein bestimmter Klartextwert immer zu demselben Cyphertext-Ergebnis. Diese Eigenschaft ist in manchen Anwendungen sehr nützlich.

Mit diesem Modus können Sie beispielsweise Kreditkartennummern in einer Transaktionsprotokolltabelle verschlüsseln. Bei der konvergenten Verschlüsselung wäre der Wert der verschlüsselten Kreditkarte bei jedem Einfügen einer neuen Transaktion gleich, wodurch die Verwendung normaler SQL-Abfragen für Berichte, Suchen usw. ermöglicht wird.

5. Vault-Setup

In diesem Abschnitt erstellen wir eine lokale Testumgebung, um die Fähigkeiten des Vault zu testen.

Die Bereitstellung von Vault ist einfach: einfach download das Paket , das unserem Betriebssystem entspricht und dessen ausführbare Datei ( __vault oder vault.exe __on Windows) in ein Verzeichnis auf unserem Pfad extrahiert.

  • Diese ausführbare Datei enthält den Server und ist auch der Standardclient ** .

Es gibt auch ein offizielles Docker-Image , aber wir werden es hier nicht behandeln.

Vault unterstützt einen development -Modus, der für ein schnelles Testen und für die Einarbeitung in sein Befehlszeilentool geeignet ist, aber für echte Anwendungsfälle viel zu einfach ist: Beim Neustart gehen alle Daten verloren und der API-Zugriff verwendet einfaches HTTP .

Stattdessen verwenden wir einen dateibasierten permanenten Speicher und richten HTTPS ein, sodass wir einige der Konfigurationsdetails aus der Praxis untersuchen können, die zu Problemen führen können.

5.1. Starten des Vault-Servers

Vault verwendet eine Konfigurationsdatei im HCL- oder JSON-Format. Die folgende Datei definiert die gesamte Konfiguration, die zum Starten unseres Servers mit einem Dateispeicher und einem selbstsignierten Zertifikat erforderlich ist:

storage "file" {
  path = "./vault-data"
}
listener "tcp" {
  address = "127.0.0.1:8200"
  tls__cert__file = "./src/test/vault-config/localhost.cert"
  tls__key__file = "./src/test/vault-config/localhost.key"
}

Lassen Sie uns jetzt Vault ausführen. Öffnen Sie eine Befehlsshell, wechseln Sie in das Verzeichnis mit unserer Konfigurationsdatei und führen Sie den folgenden Befehl aus:

$ vault server -config ./vault-test.hcl

Vault wird gestartet und zeigt einige Initialisierungsmeldungen an. Sie enthalten die Version, einige Konfigurationsdetails und die Adresse, unter der die API verfügbar ist. Das ist es - unser Vault-Server ist betriebsbereit.

5.2. Vault-Initialisierung

Unser Vault-Server läuft jetzt, aber da dies der erste Lauf ist, müssen wir ihn initialisieren.

Öffnen wir eine neue Shell und führen Sie die folgenden Befehle aus,

$ export VAULT__ADDR=https://localhost:8200
$ export VAULT__CACERT=./src/test/vault-config/localhost.cert
$ vault operator init

Hier haben wir einige Umgebungsvariablen definiert, so dass wir sie nicht jedes Mal als Parameter an Vault übergeben müssen:

  • VAULT ADDR__: Basis-URI, an den unser API-Server Anforderungen abwickelt

  • VAULT CACERT__: Pfad zum öffentlichen Zertifikatschlüssel unseres Servers

In unserem Fall verwenden wir VAULT CACERT__, damit wir mit HTTPS auf die API von Vault zugreifen können. Wir brauchen das, weil wir selbstsignierte Zertifikate verwenden.

Dies wäre für Produktionsumgebungen nicht erforderlich, in denen wir normalerweise auf von CA signierte Zertifikate zugreifen können.

Nachdem Sie den obigen Befehl ausgeführt haben, sollte eine Meldung wie folgt angezeigt werden:

Unseal Key 1: <key share 1 value>
Unseal Key 2: <key share 2 value>
Unseal Key 3: <key share 3 value>
Unseal Key 4: <key share 4 value>
Unseal Key 5: <key share 5 value>

Initial Root Token: <root token value>

... more messages omitted

Die fünf ersten Zeilen sind die Master-Schlüsselfreigaben, die wir später verwenden werden, um den Speicher von Vault aufzuheben. Bitte beachten Sie, dass Vault während der Initialisierung nur die Freigaben des Master-Schlüssels anzeigt - und nie mehr. ** Beachten Sie und bewahren Sie sie sicher auf. Andernfalls verlieren wir beim Neustart des Servers den Zugriff auf unsere Geheimnisse!

Beachten Sie auch das root token , da wir es später brauchen werden.

Im Gegensatz zu nicht verschließbaren Schlüsseln können ** Root-Token leicht zu einem späteren Zeitpunkt generiert werden. Da wir später Befehle ausgeben werden, für die ein Authentifizierungstoken erforderlich ist, speichern wir das Stammtoken jetzt in einer Umgebungsvariablen:

$ export VAULT__TOKEN=<root token value> (Unix/Linux)

Lassen Sie uns unseren Serverstatus jetzt anzeigen, nachdem wir ihn mit dem folgenden Befehl initialisiert haben:

$ vault status
Key                Value
---                -----
Seal Type          shamir
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    0/3
Unseal Nonce       n/a
Version            0.10.4
HA Enabled         false

Wir können sehen, dass Vault immer noch versiegelt ist. Wir können auch den Fortschritt der Versiegelung verfolgen: „0/3“ bedeutet, dass Vault drei Anteile benötigt, aber bisher keine erhalten hat. Gehen wir voran und versorgen Sie es mit unseren Aktien.

5.3. Gewölbe entsiegeln

Wir entfernen jetzt Vault, damit wir seine Geheimdienste nutzen können. Wir müssen drei der fünf Schlüsselaktien angeben, um den Entsiegelungsprozess abzuschließen:

$ vault operator unseal <key share 1 value>
$ vault operator unseal <key share 2 value>
$ vault operator unseal <key share 3 value>

Nach der Ausgabe druckt jeder Vault den Verlauf der Versiegelung einschließlich der benötigten Anzahl an Freigaben. Beim Senden der letzten Schlüsselfreigabe wird eine Nachricht wie folgt angezeigt:

Key             Value
---             -----
Seal Type       shamir
Sealed          false
... other properties omitted

Die Eigenschaft „Sealed“ ist in diesem Fall „false“. Dies bedeutet, dass Vault bereit ist, Befehle zu akzeptieren.

6. Tresor testen

In diesem Abschnitt werden wir unser Vault-Setup mit zwei unterstützten geheimen Typen testen: Schlüssel/Wert und Datenbank. Außerdem zeigen wir Ihnen, wie Sie neue Token mit bestimmten Richtlinien erstellen.

6.1. Verwenden von Schlüssel-/Wertgeheimnissen

Zuerst speichern wir geheime Schlüssel-Wert-Paare und lesen sie zurück. Unter der Annahme, dass die zum Initialisieren von Vault verwendete Befehls-Shell noch geöffnet ist, verwenden wir den folgenden Befehl, um diese Paare unter dem Pfad secret/fakebank zu speichern:

$ vault kv put secret/fakebank api__key=abc1234 api__secret=1a2b3c4d

Wir können diese Paare jetzt jederzeit mit dem folgenden Befehl wiederherstellen:

$ vault kv get secret/fakebank
======= Data =======
Key           Value
---           -----
api__key       abc1234
api__secret    1a2b3c4d

Dieser einfache Test zeigt uns, dass Vault so funktioniert, wie es sollte. Wir können jetzt einige zusätzliche Funktionen testen.

6.2. Neue Token erstellen

Bisher haben wir das Root-Token verwendet, um unsere Anfragen zu authentifizieren. Da ein Stamm-Token way zu mächtig ist, wird es als bewährte Methode angesehen, Token mit weniger Privilegien und kürzerer Lebensdauer zu verwenden.

Lassen Sie uns ein neues Token erstellen, das wir wie das Root-Token verwenden können, das jedoch nach einer Minute verfällt

$ vault token create -ttl 1m
Key                  Value
---                  -----
token                <token value>
token__accessor       <token accessor value>
token__duration       1m
token__renewable      true
token__policies      ["root"]identity__policies   []policies            ["root"]----

Testen wir dieses Token, um die zuvor erstellten Schlüssel/Wert-Paare zu lesen:

[source,bash,gutter:,true]

$ export VAULT TOKEN=<token value> $ vault kv get secret/fakebank ======= Data ======= Key Value --- ----- api key abc1234 api__secret 1a2b3c4d

Wenn wir eine Minute warten und versuchen, diesen Befehl erneut auszuführen, wird eine Fehlermeldung angezeigt:

[source,bash,gutter:,true]

$ vault kv get secret/fakebank Error making API request.

  • permission denied

Die Nachricht zeigt an, dass unser Token nicht mehr gültig ist, was wir erwartet haben.

[[testing__policies]]

====  6.3. Richtlinien testen

Das Beispiel-Token, das wir im vorherigen Abschnitt erstellt haben, war von kurzer Dauer, aber dennoch sehr mächtig Verwenden wir nun Richtlinien, um stärker eingeschränkte Token zu erstellen.

Definieren wir beispielsweise eine Richtlinie, die nur Lesezugriff auf den zuvor verwendeten Pfad __secret/fakebank__ zulässt:

[source,bash,gutter:,true]

$ cat > sample-policy.hcl <<EOF path "secret/fakebank" { capabilities =["read"]} EOF $ export VAULT__TOKEN=<root token> $ vault policy write fakebank-ro ./sample-policy.hcl Success! Uploaded policy: fakebank-ro

Jetzt erstellen wir mit dieser Richtlinie ein Token mit dem folgenden Befehl:

[source,bash,gutter:,true]

$ export VAULT TOKEN=<root token> $ vault token create -policy=fakebank-ro Key Value --- ----- token <token value> token accessor <token accessor value> token duration 768h token renewable true token policies ["default" "fakebank-ro"]identity policies []policies ["default" "fakebank-ro"]----

Lesen wir unsere geheimen Werte mit diesem Token:

$ export VAULT__TOKEN=<token value>
$ vault kv get secret/fakebank
======= Data =======
Key           Value
---           -----
api__key       abc1234
api__secret    1a2b3c4d

So weit, ist es gut. Wir können Daten wie erwartet lesen. Mal sehen, was passiert, wenn wir versuchen, dieses Geheimnis zu aktualisieren:

$ vault kv put secret/fakebank api__key=foo api__secret=bar
Error writing data to secret/fakebank: Error making API request.

URL: PUT https://127.0.0.1:8200/v1/secret/fakebank
Code: 403. Errors:

**  permission denied

Da in unserer Richtlinie das Schreiben nicht explizit zugelassen wird, gibt Vault einen Statuscode 403 - Access Denied zurück.

6.4. Verwenden dynamischer Datenbankanmeldeinformationen

Als letztes Beispiel in diesem Artikel verwenden wir die Database Secret Engine von Vault, um dynamische Anmeldeinformationen zu erstellen. Wir gehen hier davon aus, dass wir lokal einen MySQL-Server haben und mit "root" -Privilegien darauf zugreifen können. Wir werden auch ein sehr einfaches Schema verwenden, das aus einer einzigen Tabelle besteht - account .

Das zum Erstellen dieses Schemas verwendete SQL-Skript und der privilegierte Benutzer sind hier verfügbar.

Nun konfigurieren wir Vault für die Verwendung dieser Datenbank. Die Datenbankgeheimnis-Engine ist standardmäßig nicht aktiviert. Daher müssen wir dies beheben, bevor wir fortfahren können:

$ vault secrets enable database
Success! Enabled the database secrets engine at: database/----

Wir erstellen jetzt eine Datenbankkonfigurationsressource:

[source,bash,gutter:,true]

$ vault write database/config/mysql-fakebank \ plugin name=mysql-legacy-database-plugin \ connection url="{{username}}:{{password}}@tcp(127.0.0.1:3306)/fakebank" \ allowed__roles="** " \ username="fakebank-admin" \ password="Sup&rSecre7!"

Im Pfadpräfix __database/config__ müssen alle Datenbankkonfigurationen gespeichert werden. Wir wählen den Namen __mysql-fakebank__, damit wir leicht herausfinden können, auf welche Datenbank sich diese Konfiguration bezieht. Wie für die Konfigurationsschlüssel:

**  __plugin__name: __ Legt fest, welches Datenbank-Plugin verwendet wird. Das

verfügbare Plugin-Namen werden in beschrieben
https://www.vaultproject.io/docs/secrets/databases/index.html[Vault’s
docs]**  __connection__url__: Dies ist eine vom Plugin verwendete Vorlage, wenn

Verbindung zur Datenbank. Beachten Sie die \ {\ {{Benutzername}} und das \ {\ {{{Passwort}}.
Vorlagenplatzhalter. Wenn Sie eine Verbindung zur Datenbank herstellen, wird Vault dies tun
Ersetzen Sie diese Platzhalter durch tatsächliche Werte
**  __allowed__roles__: Legen Sie fest, welche Vault-Rollen (als nächstes beschrieben) verwendet werden können

diese Konfiguration. In unserem Fall verwenden wir "** ", daher steht es allen zur Verfügung
Rollen
**  __Nutzername

Datenbankoperationen ausführen, z. B. einen neuen Benutzer erstellen und seine Berechtigungen widerrufen

Die letzte Konfigurationstask besteht darin, eine Vault-Datenbankrollenressource zu erstellen, die die zum Erstellen eines Benutzers erforderlichen SQL-Befehle enthält. Wir können beliebig viele Rollen erstellen, je nach unseren Sicherheitsanforderungen.

Hier erstellen wir eine Rolle, die Lesezugriff auf alle Tabellen des __fakebank__-Schemas gewährt:

[source,actionscript3,gutter:,true]

$ vault write database/roles/fakebank-accounts-ro \ db name=mysql-fakebank \ creation statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON fakebank.** TO '{{name}}'@'%';"

Das Datenbankmodul definiert das Pfadpräfix ____Datenbank/Rollen ____ als Speicherort für die Rollen. __fakebank-accounts-ro__ ist der Rollenname, den wir später beim Erstellen dynamischer Anmeldeinformationen verwenden. Wir liefern auch folgende Schlüssel:

**  __db__name__: Name einer vorhandenen Datenbankkonfiguration. Entspricht

der letzte Teil des Pfads, den wir beim Erstellen der Konfiguration verwendet haben
Ressource
**  __creation__statements: __ Eine Liste von SQL-Anweisungsvorlagen von Vault

verwendet, um einen neuen Benutzer zu erstellen

Sobald wir eine Datenbankrolle und die entsprechende Konfiguration vorbereitet haben, generieren wir neue dynamische Anmeldeinformationen mit dem folgenden Befehl:

[source,bash,gutter:,true]

$ vault read database/creds/fakebank-accounts-ro Key Value --- ----- lease id database/creds/fakebank-accounts-ro/0c0a8bef-761a-2ef2-2fed-4ee4a4a076e4 lease duration 1h lease__renewable true password <password> username <username>

Das Präfix __database/creds__ wird verwendet, um Berechtigungsnachweise für die verfügbaren Rollen zu generieren. Da wir die Rolle ____fakebank-accounts-ro ____ verwendet haben, ist der zurückgegebene Benutzername/das Kennwort auf __select__-Vorgänge beschränkt.

Wir können dies überprüfen, indem wir mit den angegebenen Anmeldeinformationen eine Verbindung zur Datenbank herstellen und dann einige SQL-Befehle ausführen:

[source,bash,gutter:,true]

$ mysql -h 127.0.0.1 -u <username> -p fakebank Enter password: MySQL[fakebank]> select ** from account; …​ omitted for brevity 2 rows in set (0.00 sec) MySQL[fakebank]> delete from account; ERROR 1142 (42000): DELETE command denied to user 'v-fake-9xoSKPkj1'@'localhost' for table 'account'

**  Wir können sehen, dass der erste __select__ erfolgreich abgeschlossen wurde, aber die __delete__-Anweisung **  konnte nicht ausgeführt werden. Wenn wir eine Stunde warten und versuchen, eine Verbindung mit denselben Anmeldeinformationen herzustellen, können wir keine Verbindung mehr zur Datenbank herstellen. Vault hat diesem Benutzer automatisch alle Berechtigungen entzogen

===  7. Schlussfolgerung

In diesem Artikel wurden die Grundlagen von Hashicorps Vault erforscht, einschließlich einiger Hintergrundinformationen zu dem Problem, zu dem es versucht, es zu lösen, seiner Architektur und seiner grundlegenden Verwendung.

Nebenbei haben wir eine einfache, aber funktionale Testumgebung geschaffen, die wir in Folgeartikeln verwenden werden.

Im nächsten Artikel wird ein sehr spezieller Anwendungsfall für Vault behandelt: **  Verwendung im Kontext der Spring Boot-Anwendung ** . Bleib dran!