Vault

Vault ist ein weiteres Tool aus dem Sortiment von HashiCorp. Ähnlich wie Consul ist es ein Key/Value Store ... allerdings für das sichere Aufbewahren von Geheimnissen (z. B. Username/Password). Hierzu werden die Daten verschlüsselt gespeichert und selbst Vault kann die Daten nur dann lesen, wenn ein Unsealing stattgefunden hat.


Getting Started

Wie so häufig kommt man am schnellsten mit Docker voran:

docker run --cap-add=IPC_LOCK -d --net=host --name=myVault -e VAULT_DEV_ROOT_TOKEN_ID=root vault

oder - meine Präferenz - über eine docker-compose.yml Datei

vault:
    image: vault
    ports:
        - "8200:8200"
    cap_add:
        - IPC_LOCK
    environment:
        VAULT_DEV_ROOT_TOKEN_ID: root

so daß der Container per docker-compose up -d vault im Development Mode gestartet werden kann (von dieser Startvariante gehe ich im folgenden aus). Will man den Container im Server-Mode starten, so verwendet man den Zusatzparameter command im docker-compose.yml File

command: server -config=/vault/config/vault-config.json

ACHTUNG: der Container verliert seine Daten durch einen Restart, da er nur In-Memory Storage - lösbar durch Verwendung anderer Storage Backends (z. B. Consul oder File Storage mit einem persistenten Volume). Ohne den Parameter VAULT_DEV_ROOT_TOKEN_ID wird ein zufälliger Token generiert (z. B. b9f49ccd-aac7-e894-66e3-798a43022c2b) und beim Startup im Log ausgegeben. Die Token Authentication Methode ist per Default eingeschaltet - man benötigt den Token beispielsweise beim Login über die WEB-UI.

Das WEB UI steht dann unter http://localhost:8200/ui zur Verfügung - per root Token kann man sich anmelden.

Developer Mode

Wird Vault im Developer-Mode gestartet, so ist es automatisch unsealed, d. h. eine Eingabe des Master-Keys zum Entschlüsseln des Verschlüsselungs-Keys der Daten ist nicht mehr erforderlich.

Docker Deployment - CLI

Wenn man das Kommandozeilen Interface verwenden möchte, dann erzeugt man am besten per docker exec -it vault sh und exportiert die folgenden Umgebungsvariablen:

export VAULT_ADDR=http://vault:8200
export VAULT_TOKEN=root

Die VAULT_ADDR benötigt man nur, wenn der Container kein https verwendet, sondern nur http unterstützt. Ohne diese Konfiguration bekommt man Fehlermeldungen wie "Error listing secrets engines: Get https://127.0.0.1:8200/v1/sys/mounts: http: server gave HTTP response to HTTPS client". Man kann dann hier die Umgebungsvariable setzen (dauerhaft) oder bei den Befehlen -address=http://vault:8200 angeben.

Den VAULT_TOKEN kann man aus convenience Gründen verwenden - damit umgeht man ein explizites Login ( vault login). ABER ACHTUNG: in der Kammando-History ist dies sichtbar (sicherheitstechnisch bedenklich)!!! Alternativ dazu kann man den Token auch in die Datei /root/.vault-token packen, was den Sicherheitsaspekt nicht weniger kritisch macht. In Entwicklungsumgebungen ist das allerdings i. a. unproblematisch.

Danach kann man Befehle wie diese absetzen:

vault secrets list
vault secrets enable -version=1 my-kv

Docker Deployment - Consul Integration

Man kann das Docker-Deployment über Umgebungsvariablen und Parameter wie --cap-add anpassen. Zusätzlich kann man auch Konfigurationsdateien (json, hcl) über Volumes einbinden. So würde die Docker-Compose Konfiguration aussehen

vault:
    image: vault
    ports:
        - "8200:8200"
    volumes:
        - ./vault-persistence:/vault/file
        - ./vault-config:/vault/config
    cap_add:
        - IPC_LOCK
    environment:
        VAULT_DEV_ROOT_TOKEN_ID: root

Bei dieser Konfiguration würde eine Datei ./vault-config/config.hcl den Vault Container entsprechend konfigurieren. In diesem Beispiel wird Consul (statt der In-Memory Datenbank) als Storage Engine verwendet Consul muß natürlich auch gestartet sein):

storage "consul" {
  address = "consul:8500"
  path    = "vault/"
}

Anschließend sollte man unter Key/Values - vault/logical die Keys sehen. Im Vault WEB-UI sieht man sie auch weiterhin ... macht ja Sinn, d


Konzepte

  • Vault verschlüsselt die Werte bevor sie zum Backend Storage gesendet werden - dementsprechend speichert das Storage nur Bits ... eine Interpretation/Nutzung ist nicht möglich
  • Vault verwaltet sog. Ressourcen - alles ist eine Ressource ... es gibt verschiedene Ressource-Typen (z. B. vault_generic_secret) mit unterschiedlichen Properties (z. B. path). Hier z. B. ein Secret
resource "vault_generic_secret" "mySecret" {
  path = "secret/myService/s1"

  data_json = <<EOT
{
  "s1": "4711"
}

Nutzung

Vault stellt folgende Interfaces zur Verfügung


Authentication Method

Vault unterstützt viele Authentifizierungsmethoden

  • Token
    • im Developer-Mode standardmäßig freigeschaltet - es wird ein Token beim Start generiert und im Log ausgegeben
  • Username/Password
  • TLS Zertifikate
  • AppRole
  • LDAP
  • OpenID Connect
    • Okta
    • GitHub
  • ...

Authorization

ACL (Access Control List) definiert welche Berechtigungen ein User (identifiziert über Token)

Roles


Storage

  • In-Memory
  • Festplatte
  • Consul

Vault selbst speichert die Daten verschlüsselt - Vault hat nur Zugriff, wenn es über den Master-Key verfügt. Die Verschlüsselung erfolgt mit einem Key, der mit dem sog. Master-Key verschlüsselt ist. Dieser Master-Key muß Vault im sog. Unsealing-Prozess übergeben werden - das kann von verschiedenen Endgeräten verteilt erfolgen, um die Sicherheit zu erhöhen.

Master-Key

Vault Verschlüsselung

Der Master-Key ist in Produktivszenarien allerdings kein einzelner Schlüssel, der EINEM Operator zur Verfügung steht. Stattdessen wird dieses Geheimnis in sog. Shared Keys zerteilt ... und zwar so, daß eine bestimmte Anzahl von Shared-Keys ausreicht, um den Master-Key zu restaurieren. Shamir Secret Sharing ist das dahinterliegende Konzept

Beispiel:

Der Master-Key wird in 5 Shared Keys zerteilt Teile und 3 genügen, um den Masterkey wiederherzustellen.

vault operator init -key-shares=5 -key-threshold=3

Auto-Unseal

Um ein Auto-Unseal zu unterstützen (und somit Auto-Setup zu unterstützen) wird das Secret von Personen auf Geräte/Services umverteilt und dann genügt auch nur ein einziger Cloud based key.

Auto-Unsealing mit AWS KMS


Secret Engines

Vault kann verschiedene Secret Engines einbinden:

  • Generischer Key/Value-Store
    • in Version 1
    • in Version 2
      • ein solcher ist defaultmäßig beim Docker-Container (Stand September 2018) instantiiert
  • AWS

Ein URL-Pfad-Prefix (z. B. secret, aws) ist an eine Secret Engine gebunden.

Generischer Key/Value Store

AWS

Der AWS Secret Store wird per vault secrets enable -path=aws aws eingeschaltet.


Provisioning von Key/Values

Terraform

Secrets werden in Terraform - ganz ähnlich wie Konfigurationswerte in Consul - über die Resource vault_generic_secret in Vault abgelegt:

resource "vault_generic_secret" "myservice_smtp_credentials" {
  path = "secret/myservice/smtp/credentials"

  data_json = <<EOT
{
  "username": "user1",
  "password": "password1"
}
EOT
}

Zugriffe auf diese Werte (= Secrets) sind geschützt und man benötigt entsprechende Berechtigungen, um darauf zuzugreifen. In einer sog. vault_policy werden verschiedene Berechtigungsprofile definiert

resource "vault_policy" "myservice_read_policy" {
  name = "myservice"

  policy = <<EOT
path "secret/myservice/*" {
  policy = "read"
}
EOT
}

Beim Zugriff auf Secrets secret/myservice/* (z. B. über ein Consul-Template) benötigt man einen entsprechenden Token, der für den Scope freigegeben ist. In einem Nomad-Job (der auf die Secrets zugreifen muß, um in der Konfiguration die Passwörter zur Hand zu haben) verwendet man deshalb die vault-Stanza, um ein Token on-the-fly auszustellen:

job "myservice_job" {
  group "example" {
    task "myservice_server" {
      vault {
        policies = ["myservice_read_policy"]

        change_mode   = "signal"
        change_signal = "SIGUSR1"
      }
    }
  }
}

Wie bereits erwähnt gibt man den Root-Token niemals weiter - dennoch muß man natürlich die Secrets lesen können (sonst gäbe es keinen Grund sie zu hinterlegen). Deshalb kann man Tokens mit eingeschränkten Berechtigungen ausstellen. Hierzu definiert man sog. Policies, in denen die Berechtigungen auf Basis von Policies definiert sind.


Vault CLI

  • vault token lookup s.566431636764125361235
    • gibt nützliche Informationen zu einem Token aus ... wenn man bespielsweise in Berechtigungsprobleme läuft
      • expire_time
      • issue_time
      • last_renewal
      • policies
      • renewable
        • Secrets haben zumeist nur einen eingeschränkten Gültigkeitszeitraum ... man kann Vault mit der Erneuerung von Secrets beauftragen - in dem Fall muß man dann natürlich auch dafür sorgen, daß die neuen Tokens an die Clients verteilt werden

results matching ""

    No results matching ""