CLOVER🍀

That was when it all began.

Ubuntu Linux 20.04 LTSにVaultをインストールする

これは、なにをしたくて書いたもの?

前々からちょっと気になっていた、Vaultを扱ってみることにしました。

Vault

Vaultのオフィシャルサイトは、こちら。HashiCorpのプロダクトですね。

Vault by HashiCorp

Vaultがどんなものかは、ユースケースを見るのが良い気がします。

  • Secrets Management
    • 機密情報の管理
  • Dynamic Secrets
    • 動的にシークレットを生成、有効期限切れによる破棄
  • Kubernetes Secrets
    • Kubernetes環境における機密情報管理
  • Database Credential Rotation
    • データベースのクレデンシャルのローテーションおよび有効期限管理の自動化
  • Automated PKI Infrastructure
    • 証明書の自動生成
  • Identity-based Access
    • クラウド等のIDプロバイダーを使用したアクセス管理
  • Data Encryption & Tokenization
  • Key Management
    • 様々なKMSプロバイダーをバックエンドとした暗号鍵の配布、ライフサイクル管理

だいたい、雰囲気が感じ取れますね。

ライセンスは、GitHubリポジトリを見るとMozilla Public License 2.0です。

GitHub - hashicorp/vault: A tool for secrets management, encryption as a service, and privileged access management

OSS版、Enterprise版、Cloud版の3形態で提供されています。

HashiCorp Vault: Enterprise Pricing, Packages & Features

ドキュメント、チュートリアルはそれぞれこちら。

Documentation | Vault by HashiCorp

Vault Tutorials - HashiCorp Learn

クライアントライブラリについては、こちらにまとめられています。

HTTP API: Libraries | Vault by HashiCorp

Enterprise版については、ドキュメント内に章が設けられています。

Vault Enterprise | Vault by HashiCorp

自分が利用するのはOSS版ですね。

今回は、Ubuntu Linux 20.04 LTSにインストールしてまずは試してみたいと思います。

環境

今回の環境は、こちら。

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.3 LTS
Release:        20.04
Codename:       foca


$ uname -srvmpio
Linux 5.4.0-91-generic #102-Ubuntu SMP Fri Nov 5 16:31:28 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Ubuntu Linux 20.04 LTSです。

Vaultをインストールする

Vaultをインストールする方法はこちらに書かれていますが、

Install Vault | Vault by HashiCorp

今回はビルド済みのLinuxパッケージを使います。

Downloads | Vault by HashiCorp

$ curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
$ sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
$ sudo apt-get update
$ sudo apt-get install vault

Vault 1.9.1がインストールされました。

$ vault version
Vault v1.9.1

インストールされるファイルは、これだけですね。systemdのサービスユニットファイルもあるじゃないですか。

$ dpkg -L vault
/usr
/usr/bin
/usr/bin/vault
/etc
/etc/vault.d
/etc/vault.d/vault.env
/etc/vault.d/vault.hcl
/usr/lib
/usr/lib/systemd
/usr/lib/systemd/system
/usr/lib/systemd/system/vault.service

ヘルプ。

$ vault -h
Usage: vault <command> [args]

Common commands:
    read        Read data and retrieves secrets
    write       Write data, configuration, and secrets
    delete      Delete secrets and configuration
    list        List data or secrets
    login       Authenticate locally
    agent       Start a Vault agent
    server      Start a Vault server
    status      Print seal and HA status
    unwrap      Unwrap a wrapped secret

Other commands:
    audit          Interact with audit devices
    auth           Interact with auth methods
    debug          Runs the debug command
    kv             Interact with Vault's Key-Value storage
    lease          Interact with leases
    monitor        Stream log messages from a Vault server
    namespace      Interact with namespaces
    operator       Perform operator-specific tasks
    path-help      Retrieve API help for paths
    plugin         Interact with Vault plugins and catalog
    policy         Interact with policies
    print          Prints runtime configurations
    secrets        Interact with secrets engines
    ssh            Initiate an SSH session
    token          Interact with tokens

コマンドごとのオプションは、-hを付けて実行すれば確認できそうです。

$ vault server -h
Usage: vault server [options]

  This command starts a Vault server that responds to API requests. By default,
  Vault will start in a "sealed" state. The Vault cluster must be initialized
  before use, usually by the "vault operator init" command. Each Vault server must
  also be unsealed using the "vault operator unseal" command or the API before the
  server can respond to requests.

  Start a server with a configuration file:

      $ vault server -config=/etc/vault/config.hcl

  Run in "dev" mode:

      $ vault server -dev -dev-root-token-id="root"

  For a full list of examples, please see the documentation.

HTTP Options:

  -address=<string>
      Address of the Vault server. The default is https://127.0.0.1:8200. This
      can also be specified via the VAULT_ADDR environment variable.

〜省略〜

各コマンドに対するドキュメントは、こちら。

Commands (CLI) | Vault by HashiCorp

開発モードのサーバーを起動する

チュートリアルを見ると、まずはサーバーを起動するようです。

Starting the Server | Vault - HashiCorp Learn

開発モードのサーバーを試してみましょう、と。

開発モードのサーバーとは、こういうものみたいです。

  • -devオプションをつけて起動する
  • ローカル開発、テスト、調査目的に使用する
  • セキュアではなく、保護されていない
  • データはメモリ上に保存される
  • プロダクション環境で使用してはならない

確かに"開発モード"ですね。

server - Command | Vault by HashiCorp

開発モードのサーバーは設定済みのものになるようで、そうではない場合は設定ファイルでVaultの設定を行います。

Server Configuration | Vault by HashiCorp

こちらについては、また別の機会に。

では、開発サーバーを起動してみます。

$ vault server -dev

起動すると、Vault自身の情報が表示され

==> Vault server configuration:                                                                                                                                                   
                                                                                                                                                                                  
             Api Address: http://127.0.0.1:8200                                                                                                                                   
                     Cgo: disabled
         Cluster Address: https://127.0.0.1:8201
              Go Version: go1.17.2
              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: info
                   Mlock: supported: true, enabled: false
           Recovery Mode: false
                 Storage: inmem
                 Version: Vault v1.9.1

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

最後にこんな情報が表示されます。

2021-12-21T00:03:02.566+0900 [INFO]  expiration: lease restore complete
2021-12-21T00:03:02.566+0900 [INFO]  core: post-unseal setup complete
2021-12-21T00:03:02.566+0900 [INFO]  core: vault is unsealed
2021-12-21T00:03:02.569+0900 [INFO]  core: successful mount: namespace="\"\"" path=secret/ type=kv
2021-12-21T00:03:02.578+0900 [INFO]  secrets.kv.kv_27c06bad: collecting keys to upgrade
2021-12-21T00:03:02.579+0900 [INFO]  secrets.kv.kv_27c06bad: done collecting keys: num_keys=1
2021-12-21T00:03:02.579+0900 [INFO]  secrets.kv.kv_27c06bad: upgrading keys finished
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: [Unseal Key]
Root Token: [Root Token]

Development mode should NOT be used in production installations!

Unseal KeyとRoot Tokenが表示されています。それから、VAULT_ADDRという環境変数についても書かれていますね。

別のターミナルからアクセスしてみましょう。

そのままだとアクセスできません。

$ vault status
Error checking seal status: Get "https://127.0.0.1:8200/v1/sys/seal-status": http: server gave HTTP response to HTTPS client

開発サーバー起動時に指示されていたとおり、VAULT_ADDR環境変数を設定してみます。

$ export VAULT_ADDR=http://127.0.0.1:8200

今度はアクセスできました。

$ vault status
Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false
Total Shares    1
Threshold       1
Version         1.9.1
Storage Type    inmem
Cluster Name    vault-cluster-5df6d588
Cluster ID      f82dde5c-7ecc-5e71-d7ba-f7b51c72f17e
HA Enabled      false

vault statusは、現在のVaultの状態を出力するコマンドです。

status - Command | Vault by HashiCorp

autocompletionを有効にする

先に進む前に、vaultコマンドのautocompletionを有効にしておきましょう。

Vault Commands (CLI) / Autocompletion

以下のコマンドを実行。

$ vault -autocomplete-install

$HOME/.bashrcファイルに、以下が追加されるようです。

complete -C /usr/bin/vault vault

新しく起動したシェルから、autocompletionが有効になります。

シークレットを登録する

続いて、シークレットを登録してみましょう。

Your First Secret | Vault - HashiCorp Learn

コマンドとしては、vault kvを使うようです。

kv - Command | Vault by HashiCorp

kvとは、VaultのKey Value Secrets Engineを操作するコマンドです。

KV - Secrets Engines | Vault by HashiCorp

KV Secrets Engineにはバージョンが2つあり、開発サーバーではバージョン2が、非開発サーバーではバージョン1が
デフォルトで使われるようです。

Additionally, when running a dev-mode server, the v2 kv secrets engine is enabled by default at the path secret/ (for non-dev servers, it is currently v1).

KV - Secrets Engines | Vault by HashiCorp

アクセスするパスもそれぞれ違うようですね。バージョン1と2の違いは、メタデータや履歴の管理のようです。
バージョン2だと、メタデータの保存や履歴管理が行われます。

では、パスsecret/my-credsにkv putでデータを書き込んでみます。データはkey=value形式で指定するようです。

$ vault kv put secret/my-creds hello=world

コマンドのレスポンスは、このようになります。

Key                Value
---                -----
created_time       2021-12-20T16:40:13.178757588Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

登録したデータは、kv listで指定したパスでキーを表示できます。

$ vault kv list secret
Keys
----
my-creds

データを取得するには、kv getです。

$ vault kv get secret/my-creds
======= Metadata =======
Key                Value
---                -----
created_time       2021-12-20T16:40:13.178757588Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

==== Data ====
Key      Value
---      -----
hello    world

kv putで、同時に複数のデータを書き込むこともできます。

$ vault kv put secret/my-creds foo=bar var=val
Key                Value
---                -----
created_time       2021-12-20T16:44:02.067907299Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            2

データを取得して確認。

$ vault kv get secret/my-creds
======= Metadata =======
Key                Value
---                -----
created_time       2021-12-20T16:44:02.067907299Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            2

=== Data ===
Key    Value
---    -----
foo    bar
var    val

ここで気づくのですが、key=value形式で指定しているからといって、「キーが重複しなかったら追加」というわけでは
ないんですね。

別のパスにも追加してみましょう。

$ vault kv put secret/test-creds name=vault


$ vault kv put secret/my-creds/sub name=terraform


$ vault kv put secret/sub1/sub2/sub3 hello=world

kv listで確認。

$ vault kv list secret
Keys
----
my-creds
my-creds/
sub1/
test-creds

サブパスも確認。

$ vault kv list secret/my-creds
Keys
----
sub

Secrets Engine

Secrets Engineは、データを保存、生成、そして暗号化するコンポーネントです。

Secrets Engines | Vault - HashiCorp Learn

secrets - Command | Vault by HashiCorp

Secrets Engines | Vault by HashiCorp

Secrets Engineは多数あり、データベースやConsulなどのデータストア、AWS、Azureなどのクラウドなどがあります。

Secrets Engineはパスに対して有効化し、無効化や移動ができます。

ここで、vault secrets listというコマンドを実行してみます。

$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_491c1d0f    per-token private secret storage
identity/     identity     identity_2f41def3     identity store
secret/       kv           kv_53b92a41           key/value secret storage
sys/          system       system_faffd04e       system endpoints used for control, policy and debugging

先ほどまで使っていたsecret/というパスが、kvというTypeになっています。

つまり、Key/Value Secrets Engineがパスsecretに対して有効化されていて、vault kvというコマンドは
Key/Value Secrets Engineを扱うコマンドだったことがわかります。

KV - Secrets Engines | Vault by HashiCorp

ここで、さらにKey/Value Secrets Engineを有効にしてみましょう。vault secrets enable [Secrets Engine名]で
有効化します。

$ vault secrets enable kv

デフォルトではSecrets Engineの名前とパスが同じになるようですが、

$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_491c1d0f    per-token private secret storage
identity/     identity     identity_2f41def3     identity store
kv/           kv           kv_f9c9511c           n/a
secret/       kv           kv_53b92a41           key/value secret storage
sys/          system       system_faffd04e       system endpoints used for control, policy and debuggin

-pathオプションを使用することで、パスを指定することもできます。

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


$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_491c1d0f    per-token private secret storage
identity/     identity     identity_2f41def3     identity store
key-value/    kv           kv_4027def6           n/a
kv/           kv           kv_f9c9511c           n/a
secret/       kv           kv_53b92a41           key/value secret storage
sys/          system       system_faffd04e       system endpoints used for control, policy and debugging

有効化したパスには、secretの時と同じように操作ができます。

$ vault kv put kv/p1 key1=value1
Success! Data written to: kv/p1


$ vault kv get kv/p1
==== Data ====
Key     Value
---     -----
key1    value1

なのですが、よく見るとデータが少ないですね。これはKey/Value Secrets Engineのバージョン1を使ったからのようです。

バージョン2を使う場合は、以下のどちらかで指定します。

$ vault secrets enable kv-v2

$ vault secrets enable -version=2 kv

今回はkv-v2で指定してみます。

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

$ vault kv put kv-v2/p1 key1=value1
Key                Value
---                -----
created_time       2021-12-21T16:37:49.90898581Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1


$ vault kv get kv-v2/p1
======= Metadata =======
Key                Value
---                -----
created_time       2021-12-21T16:37:49.90898581Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

==== Data ====
Key     Value
---     -----
key1    value1

最初に使ったvault kvでの操作と同じになりましたね。バージョン1と2の差を見た形になりました。

それにしても、vault secrets listで見ても両者の区別はできないのですが、どうしたらいいんでしょうね?

$ vault secrets list
Path          Type         Accessor              Description
----          ----         --------              -----------
cubbyhole/    cubbyhole    cubbyhole_491c1d0f    per-token private secret storage
identity/     identity     identity_2f41def3     identity store
key-value/    kv           kv_4027def6           n/a
kv-v2/        kv           kv_27428a78           n/a
kv/           kv           kv_f9c9511c           n/a
secret/       kv           kv_53b92a41           key/value secret storage
sys/          system       system_faffd04e       system endpoints used for control, policy and debugging

他のSecrets Engineに目を向けると、有効化したあとはvault write、vault readでデータの読み書きを行うようです。

MySQL/MariaDB - Database - Secrets Engines | Vault by HashiCorp

write - Command | Vault by HashiCorp

read - Command | Vault by HashiCorp

こちらについては、別の機会に試してみましょう。

Web UIを使う

VaultにはWeb UIがあり、開発サーバーでは有効になっています。

Web UI | Vault - HashiCorp Learn

http://localhost:8200またはhttp://localhost:8200/uiにアクセスすると、ログイン画面が現れます。

f:id:Kazuhira:20211222014415p:plain

このページではMethodはTokenのままにして、開発サーバー起動時に表示されていたRoot Tokenの値をTokenに
入力します。

Root Token: [Root Token]

ログインすると、Secrets Engineのリストを見ることができます。

f:id:Kazuhira:20211222014547p:plain

登録したデータを見ることもできるようです。

f:id:Kazuhira:20211222014740p:plain

まとめ

Vaultをまずは試してみました。

触ったばかりで機能もよくわかっていませんが、これから少しずつ慣れていこうかなと思います。