tshohe's memo

おぼえたことをかく

HashiCorpの学習プラットフォーム体験(Vault編)

HashiCorpの学習プラットフォームがどんな感じか把握するために、まずは現時点で出来るVaultのをやってみることに。
バージョンは最新のVault 1.0 beta1で試してみました。

learn.hashicorp.com

元の紹介Blog
https://www.hashicorp.com/blog/hashicorp-learn-platform-with-vault

まずは入門編

Install Vault

Linux用のバイナリをダウンロードして適当なディレクトリに配備し、PATHを通します。

$ wget https://releases.hashicorp.com/vault/1.0.0-beta1/vault_1.0.0-beta1_linux_amd64.zip
$ unzip vault_1.0.0-beta1_linux_amd64.zip 
Archive:  vault_1.0.0-beta1_linux_amd64.zip
  inflating: vault      

Starting the server

機能を簡単に試すために、devモードで起動します。

$ vault server -dev
==> Vault server configuration:

             Api Address: http://127.0.0.1:8200
                     Cgo: disabled
         Cluster Address: https://127.0.0.1:8201
              Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
               Log Level: (not set)
                   Mlock: supported: true, enabled: false
                 Storage: inmem
                 Version: Vault v1.0.0-beta1
             Version Sha: ebc733f4ca5d362fdfb302ac75953228585c54a2

WARNING! dev mode is enabled! In this mode, Vault runs entirely in-memory
and starts unsealed with a single unseal key. The root token is already
authenticated to the CLI, so you can immediately begin using Vault.

You may need to set the following environment variable:

    $ export VAULT_ADDR='http://127.0.0.1:8200'

The unseal key and root token are displayed below in case you want to
seal/unseal the Vault or re-authenticate.

Unseal Key: axPVwrt+K79ELEc4lxe8FJQAXgRVJ8vq9WBfkbf8dFU=
Root Token: s.7mWsQehqKQ9C1QvKlFPwF6CO

Development mode should NOT be used in production installations!

==> Vault server started! Log data will stream in below:

UnsealするためのKeyや、Root Tokenが表示されます。

状態確認

$ export VAULT_ADDR='http://0.0.0.0:8200'
$ vault status
Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false
Total Shares    1
Threshold       1
Version         1.0.0-beta1
Cluster Name    vault-cluster-44b32083
Cluster ID      83ca2d85-08a4-5c78-e412-b62be7f1923f
HA Enabled      false

Your First Secret

Secretのread/writeを試します。
devモードでは情報はin-memoryに格納され、永続化はされません。(productionの場合はDisk or Consulに格納) Secretは値を暗号化してからストレージドライバに渡されるので、ストレージの情報だけではどうやっても復号化できないようになっています。

Secretの書き込み

$ vault kv put secret/hello foo=world
Key              Value
---              -----
created_time     2018-10-28T07:43:17.857896039Z
deletion_time    n/a
destroyed        false
version          1

kvはkey value
secret/helloは保存するパス
foo=worldはkey=value

valut kvは強力ですが、stdinから読めてしまうとのこと。 https://www.vaultproject.io/docs/commands/index.html

Secretの取得

$ vault kv get secret/hello
====== Metadata ======
Key              Value
---              -----
created_time     2018-10-28T07:43:17.857896039Z
deletion_time    n/a
destroyed        false
version          1

=== Data ===
Key    Value
---    -----
foo    world

レーニング資料の出力とちょっと違っていて、1.0ではMetadataとDataが完全に別に表示されるようになっています。
出力がspace区切りなのでawkとかで整形しやすい、とのこと。
またJSON outputもあって、jqで整形することもできます。

$ vault kv get -format=json secret/hello | jq -r .data.data.foo
world

フィールドを指定して出力

$vault kv get -field=foo secret/hello
world

削除

$ vault kv delete secret/hello
Success! Data deleted (if it existed) at: secret/hello

Secrets Engines

各エンジンの操作を紹介するTopic。

kv engine以外にも色々

engine summary
aws AWS IAM アクセスキーを生成
database 時間制限付きのデータベースクレデンシャルを生成

様々なパスでSecret Engineを有効化することが出来、各パスは完全に分離しているとのこと。

有効化

$ vault secrets enable -path=kv kv
Success! Enabled the kv secrets engine at: kv/

$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_7b73491b    per-token private secret storage
identity/     identity     identity_5c77b9e7     identity store
kv/           kv           kv_8842fe62           n/a
secret/       kv           kv_fdfd9f35           key/value secret storage
sys/          system       system_89f66b37       system endpoints used for control, policy and debugging

デフォルトパスはsecret engineと同名になるのでkv/としなくてもkv/になります。

無効化
moveも出来るがsecretはパスに紐付いているので消えてしまうとか。

$ vault secrets disable kv/

Dynamic Secrets

読み取るときに生成されるSecret
使用後すぐに失効させることも可能

AWSアクセスクレデンシャルを生成

$ vault secrets enable aws

AWSと通信するときに利用するRoot Accountを登録

$ vault write aws/config/root \
    access_key=[自分のAWSアカウントのアクセスキー] \
    secret_key=[アクセスキーに対応したSecret]

Success! Data written to: aws/config/root

IAMロール作成 aws/roles/[ロール名]でポリシーをマップ

$ vault write aws/roles/my-role policy=-<<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1426528957000",
      "Effect": "Allow",
      "Action": [
        "ec2:*"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}
EOF

キーペア生成

$ vault read aws/creds/my-role
Key                Value
---                -----
lease_id           aws/creds/my-role/8PShhjAzbP8rAPHp8sgs2mNe
lease_duration     768h
lease_renewable    true
access_key         [生成されたアクセスキー]
secret_key         [生成されたSecret]
security_token     <nil>

aws/creds/[ロール名]をreadすることでキーペアを生成出来ます。 デフォルトでは768H後に失効になります。 lease_idは更新、失効、検査に使うので大事。

手動失効

$ vault lease revoke aws/creds/my-role/8PShhjAzbP8rAPHp8sgs2mNe
All revocation operations queued successfully!

Built-in Help

Secret Engineのヘルプや、各パスのヘルプが参照可能

$ vault path-help [path]

Authentication

Vault自体の認証

devだと管理者権限を持つrootユーザーとして自動的にログインします。

vault token

トークン認証はデフォルト有効。rootトークンは最初のVault設定に利用します。

追加で作成する場合
現在のトークンの子トークンとして作成、ポリシーは継承される

$ vault token create
Key                  Value
---                  -----
token                s.61VESdUhJwbhyvtKsXODPLAg
token_accessor       4fNTeZ6OiQGxhYP3b0Op9vkt
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]

Revoke

$ vault token revoke s.61VESdUhJwbhyvtKsXODPLAg

Login

$ vault login s.61VESdUhJwbhyvtKsXODPLAg
Success! You are now authenticated. The token information displayed below
~

実際はToken生成コマンドの使用は推奨されておらず、Github, LDAP, AppRoleとか使ってねとのこと。

$ vault auth enable -path=github github
$ vault write auth/github/config organization=hashicorp
$ vault write auth/github/map/teams/my-team value=default,my-policy
$ vault login -method=github

Policies

ユーザーがアクセス出来るものを定義するためのポリシーの設定方法。

  • ルートポリシー: 管理者権限
  • デフォルトポリシー: デフォルトで付与されるポリシー

JSONと互換性のあるHCL(HashiCorp Configuration Language)形式

フォーマット確認

$ vault policy fmt my-policy.hcl
Success! Formatted policy: my-policy.hcl

ポリシーのアップロード
$ vault policy write my-policy my-policy.hcl
Success! Uploaded policy: my-policy

$ vault policy list
default
my-policy
root

ポリシーを指定してTokenを作成します。(secret/forに対してはread権限しかないので書き込めない)

$ vault token create -policy=my-policy
Key                  Value
---                  -----
token                s.4TeHDA1TjOP5HsadzSMULLMz
token_accessor       nCgkAftm5LEl7GXUvlmx5y39
token_duration       768h
token_renewable      true
token_policies       ["default" "my-policy"]
identity_policies    []
policies             ["default" "my-policy"]

$ vault kv put secret/bar robot=beepboop
Key              Value
---              -----
created_time     2018-10-28T12:34:00.914846589Z
deletion_time    n/a
destroyed        false
version          1
$ vault kv put secret/foo robot=beepboop
Error writing data to secret/data/foo: Error making API request.

URL: PUT http://127.0.0.1:8200/v1/secret/data/foo
Code: 403. Errors:

* 1 error occurred:
    * permission denied

Deploy Vault

Vaultの設定、起動、Seal/Unseal、Scaling

設定

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

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

作業端末からもアクセス出来るように127.0.0.1を0.0.0.0:8200に変更しています。

storageにはinmem(in-memory), file, consulがある。

Consulを起動

$ wget https://releases.hashicorp.com/consul/1.3.0/consul_1.3.0_linux_amd64.zip
$ unzip consul_1.3.0_linux_amd64.zip 
Archive:  consul_1.3.0_linux_amd64.zip
  inflating: consul                  
$ consul agent -dev

設定ファイルを指定してVaultを起動

$ vault server -config=config.hcl
==> Vault server configuration:

             Api Address: http://127.0.0.1:8200
                     Cgo: disabled
         Cluster Address: https://127.0.0.1:8201
              Listener 1: tcp (addr: "0.0.0.0:8200", cluster address: "0.0.0.0:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
               Log Level: (not set)
                   Mlock: supported: true, enabled: true
                 Storage: consul (HA available)
                 Version: Vault v1.0.0-beta1
             Version Sha: ebc733f4ca5d362fdfb302ac75953228585c54a2

==> Vault server started! Log data will stream in below:

初期化

$ vault operator init
Unseal Key 1: AcZqa1USsWoBXNd2a2bK6KzTK1oWF/qPOUZU/RFhjHJb
Unseal Key 2: lbiYiY6223BTwrm4cDCwdVgMcqQujQsr/bfZHX0/TCEX
Unseal Key 3: W/7cB42huTlQzC/bNAkPzKSSHT+8Jv3ZPiKdY4M2dAmr
Unseal Key 4: iMKSypAkMpEJZfpva6BYEp6HWYeYg5gQKqkg83q42nDV
Unseal Key 5: ERjqoCZXs30R7i0ltZ1WHu8+lc5antaAPcdv1qrYU0g9

Initial Root Token: s.2DKlat1pC8HByEdCOi9uvNEj

Vault initialized with 5 key shares and a key threshold of 3. Please securely
distribute the key shares printed above. When the Vault is re-sealed,
restarted, or stopped, you must supply at least 3 of these keys to unseal it
before it can start servicing requests.

Vault does not store the generated master key. Without at least 3 key to
reconstruct the master key, Vault will remain permanently sealed!

It is possible to generate new unseal keys, provided you have a quorum of
existing unseal keys shares. See "vault operator rekey" for more information.

Unsealするためにはキーを3つ以上入れる必要があり、それぞれ別々に管理することによって、単一オペレータだけではUnsealできないように設計されています。

$ vault operator unseal
Unseal Key (will be hidden): 
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    1/3
Unseal Nonce       8ee6ba25-6ccd-95ed-3ef6-4d581ef2c386
Version            1.0.0-beta1
HA Enabled         true

追加で+2つ入力

$ vault operator unseal
Unseal Key (will be hidden): 
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    2/3
Unseal Nonce       8ee6ba25-6ccd-95ed-3ef6-4d581ef2c386
Version            1.0.0-beta1
HA Enabled         true
$ vault operator unseal
Unseal Key (will be hidden): 
Key                    Value
---                    -----
Seal Type              shamir
Initialized            true
Sealed                 false
Total Shares           5
Threshold              3
Version                1.0.0-beta1
Cluster Name           vault-cluster-68c28fd9
Cluster ID             79e183ac-9928-2838-ebac-55c946f0acf1
HA Enabled             true
HA Cluster             n/a
HA Mode                standby
Active Node Address    <none>
  • Sealedがfalseになり、Unseal状態に。
  • 最後にinitial Root tokenを使ってvault loginします。
  • 再びSeal状態に戻すのは単一ユーザのみので可能で、Seal状態に戻るとメモリから全ての状態がクリアされます

Using the HTTP APIs with Authentication

CLI以外にもHTTP APIで利用することが出来ます。

$ export VAULT_TOKEN=s.2DKlat1pC8HByEdCOi9uvNEj

unseal
$ curl \
    --request POST \
    --data '{"key": "AcZqa1USsWoBXNd2a2bK6KzTK1oWF/qPOUZU/RFhjHJb"}' \
    http://host1:8200/v1/sys/unseal

read
$ curl \
    --header "X-Vault-Token: $VAULT_TOKEN" \
http://host1:8200/v1/secret/foo | jq
{
  "request_id": "cc46f5d9-db11-d3f4-544b-b7db66ee7db5",
  "lease_id": "",
  "renewable": false,
  "lease_duration": 2764800,
  "data": {
    "foo": "bar"
  },
  "wrap_info": null,
  "warnings": null,
  "auth": null
}

以上で入門編は終了ですが、色々なユースケースに対応したAdvanced Tracksも大量に存在するのでまだまだ色々出来そうです。

あと個人的にはTerraformのAdvanced Tracksに期待大です。