HashiCorpの日本語Vaultハンズオンを実施した!
業務でHashiCorpのVaultを使うかもしれないのでハンズオンをやってみた.GitHubに日本語のハンズオン資料が公開されているのでそれをもとに進めた.
ハンズオンアジェンダ
GitHubで公開されている日本語のハンズオンアジェンダを以下に示す.この中にはハンズオンとしての内容がまだ公開されていないものも含まれている.
- 初めてのVault
- Secret Engine 1: Key Value
- Secret Engine 2: Databases
- 認証とポリシー
- Auth Method 1: LDAP
- Auth Method 2: AppRole
- Auth Method 3: OIDC
- Auth Method 4: GitHub
- Response Rapping
- Secret Engine 3: Public Cloud (AWS, Azure, GCP)
- Secret Engine 4: PKI Engine
- Secret Engine 5: Transit (Encryption as a Service)
- Secret Engine 6: SSH
- 運用系機能色々
- CIツール連携(Concourse, Jenkins)
- Kubernetes連携
- Cloud Foundry連携
- Enterprise機能の紹介
今回は初めてVaultに触るので初めてのVault,Secret Engine 1: Key Value,Secret Engine 2: Databases,認証とポリシーの4つをやってみる.具体的な手順はハンズオンに任せるとして,この記事ではそれぞれのハンズオンで学んだことと,自分が思う重要な概念や押さえるべきポイントについてまとめてみようと思う.
1. 初めてのVault
ここではVaultをインストールしてVaultを立ち上げ,あとのハンズオンの準備をしていく.
このハンズオンで学んだこと
- Vaultのインストール
- Vaultサーバの立ち上げ(開発モード)
- シークレットエンジン
- シークレットの保存・取得
- Vaultサーバの立ち上げ(本番モード)
- Vaultの初期化処理
シークレットエンジン
シークレットエンジンとはkey=valueでデータを格納・生成・暗号化するVaultのコンポーネントである. AWSのIAMのキーやDatabaseへアクセスするシークレットなどさまざまな用途で使えるように,Vaultで専用のコンポーネントが用意されている.例えばkv
シークレットエンジンを新規で使う時はvault secrets enable -path=kv kv
のようにシークレットエンジンを有効にする.さらに,パスを指定してエンドポイントにみたてて,以後そのエンドポイントに操作を実行するのが特徴である.用途にあったシークレットエンジンを使うことでシークレットを適切に扱うことが可能となる.
Vaultの初期化処理
本番モードのVaultではセキュアな設計がされているので,起動直後はsealed
という状態になっておりVaultへログインできない.ログインするにはinit
とunseal
という初期化処理が必要になる.まずinit
処理をする.
$ vault operator init Unseal Key 1: JLYUBHrdwWu2dxwjCazqsCQ4OJPJtiMFsIZeO1osyJ1t Unseal Key 2: nEjGt+rYSOomqmyTsuF7PnKPS+NE3yPEfuo6WDXm/QDR Unseal Key 3: d5nTCzEGKIBPFGCC3ANzKf8gGgwoV8APr6V9KdDcNjOW Unseal Key 4: sd7vzV1FQk/96xQmIuKRKhydy9tGEmORbFyozAKxFc4n Unseal Key 5: JqLGxcvA3gLrwQHIliWvl1ytkMbuDGu/6p2KzGpvnCa9 Initial Root Token: s.Wi5WjPfPHqbFAcXjwsDCHQLd ~~~
init
の処理をすると,Vaultをunseal
するためのUnseal Key
とInitial Root Token
が生成される.試しにこの状態でRoot Token
を使ってログインしてみる.
$ vault login Token (will be hidden): Error authenticating: error looking up token: Error making API request. URL: GET http://127.0.0.1:8200/v1/auth/token/lookup-self Code: 503. Errors: * error performing token check: Vault is sealed
エラーになる.Vaultではsealed
状態になっているといかに強力な権限のあるトークンを使ったとしても操作は受け付けない.unseal
の処理はUnseal Key
を使う.デフォルトだと5つのキーが生成され,そのうち3つのキーが集まるとunsealされる.このアルゴリズムはシャミアの秘密鍵分散法と呼ばれる.3つのUnseal Key
を入れてみる.
$ 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 32d20912-88dd-16e2-28d3-87344abec5fc Version 1.2.3 HA Enabled false $ 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 32d20912-88dd-16e2-28d3-87344abec5fc Version 1.2.3 HA Enabled false $ vault operator unseal Unseal Key (will be hidden): Key Value --- ----- Seal Type shamir Initialized true Sealed false Total Shares 5 Threshold 3 Version 1.2.3 Cluster Name vault-cluster-7815e4aa Cluster ID 12747d60-78d3-8fad-6082-102052ac8c74 HA Enabled false
これでログインができる.
$ vault login s.Wi5WjPfPHqbFAcXjwsDCHQLdToken (will be hidden): Success! You are now authenticated. The token information displayed below is already stored in the token helper. You do NOT need to run "vault login" again. Future Vault requests will automatically use this token. Key Value --- ----- token s.Wi5WjPfPHqbFAcXjwsDCHQLd token_accessor NX8h0laChNLO5oObu2nDtovT token_duration ∞ token_renewable false token_policies ["root"] identity_policies [] policies ["root"]
やや面倒なこの仕組みの何が嬉しいのかということについては以下のブログが参考になった.
2. Secret Engine 1: Key Value
ここではシンプルなKeyValueStore型のシークレットエンジンを使ってデータのCRUD
をするハンズオンを行う.
このハンズオンで学んだこと
- Key Value Store型のシークレットエンジン
- データの
CRUD
- データのバージョニング管理
- 2つのデータ更新パターン
- データの
3. Secret Engine2: Databases
ここではMySQLとVaultを使い,Vaultで発行したシークレットを用いてMySQLにアクセスするハンズオンを行う.
このハンズオンで学んだこと
- Databaseのシークレットエンジン
- Vaultが対応しているDatabaseシークレットエンジン一覧
- Cassandra
- Influxdb
- HanaDB
- MongoDB
- MSSQL
- MySQL/MariaDB
- PostgreSQL
- Oracle
- VaultがMySQLの操作を制限するようなロールを作成し,そのロールの内容に基づいてVaultがアプリケーションへシークレットを生成する流れ
- 動的シークレットの破棄
- Rootユーザのパスワードローテーション
MySQLへのアクセスの流れ
以下の図のような流れでアプリケーションはMySQLへのアクセスを実現する.
それぞれのステップをみていく.
① Vaultに特権ユーザのクレデンシャルとデータベースの接続先を登録する.MySQLのroot
ユーザ(特権ユーザ)を指定してコネクションの設定をする.②で作成するロールもここで指定しておく必要がある.また,ロールは複数指定できる.
$ vault write database/config/mysql-handson-db \ plugin_name=mysql-legacy-database-plugin \ connection_url="{{username}}:{{password}}@tcp(127.0.0.1:3306)/" \ allowed_roles="role-handson" \ username="root" \ password="rooooot"
② MySQLへの権限やシークレットのTTLを記述したロールを定義する
$ vault write database/roles/role-handson \ db_name=mysql-handson-db \ creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON *.* TO '{{name}}'@'%';" \ default_ttl="1h" \ max_ttl="24h"
③ クライアントからVaultに対してシークレットの発行を依頼する
$ vault read database/creds/role-handson Key Value --- ----- lease_id database/creds/role-handson/G3tJu3gN8nGoL8Z8MlVkvD2g lease_duration 1h lease_renewable true password A1a-qIpUomJUoXOiHlQh username v-role-PaKXo1BO1
④ 取得したシークレットでMySQLにアクセス
$ mysql -u v-role-PaKXo1BO1 -p -h 127.0.0.1 Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 9 Server version: 5.7.22 MySQL Community Server (GPL) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. $ mysql>
⑤ ロールによりSelectはできるがInsertはできないことを確認する.
$ mysql> select * from products; +------+-------------+-------+ | id | name | price | +------+-------------+-------+ | 1 | Nice hoodie | 1580 | +------+-------------+-------+ 1 row in set (0.00 sec) $ mysql> insert into products (id, name, price) values (2, "hoge", 1600); ERROR 1142 (42000): INSERT command denied to user 'v-role-PaKXo1BO1'@'127.0.0.1' for table 'products'
動的シークレットの破棄
ロールにシークレットのTTLを設定できる.TTLを過ぎれば当該シークレットではMySQLにログインできなくなる.またrevoke
処理で発行したシークレットを明示的に無効にできる.再びMySQLにログインしたい場合は,再度シークレットを発行するか,シークレットのTTLが切れる前にrenew
処理と呼ばれるTTLを延長する処理のどちらかを実行すればよい.
Rootユーザのパスワードローテーション
VaultにMySQLの特権を持たせているためそのパスワードの扱いが非常にセンシティブである.Vaultにはコンフィグレーションとして登録したデータベースのパスワードをローテーションさせるAPIがある.これを使ってこまめにRootのパスワードをリフレッシュできる.ただし,MySQLのRootユーザがVaultに登録してあるもの1つだけだと,Rootユーザのパスワードのローテーションを行った後はRootのパスワードはVaultしか扱うことができない.そのため通常別の特権ユーザをMySQLに準備してから行う.
4. 認証とポリシー
ここではエンドポイントごとにポリシーを設定してトークンを発行し,アクセスコントロールを試してみるハンズオンを行う.
このハンズオンで学んだこと.
- ポリシーの利用方法
ロールとポリシーの違い
ポリシーの作成方法や使い方はハンズオンで十分学ぶことができる.個人的に思うここでの重要なポイントは1つ前のSecret Engine2: Databasesで学んだロールと今回のポリシーの違いだと思う.利用するアプリケーションのアクセスをコントロールをしているという点においては同じだが,ロールとポリシーではコントロールする対象領域が異なる.1つ前のハンズオンを例にとると,ロールの場合コントロールする対象領域はMySQLだった.つまり,MySQLへアクセスするシークレットが発行された上で,そのシークレットでMySQLにログインするアプリケーションにどんな制限を持たせるかというのを定義するのがロールである.一方,ポリシーはVaultのエンドポイントを対象領域としている.例えば,「kv
タイプのとあるエンドポイントにはread
,write
を持たせるけど,database
タイプのエンドポイントにはアクセスさせない」というようなポリシーを定義をする.もしこの例が適用されたトークンが発行されると,たとえロールの設定にすべてのテーブルへのアクセス許可を書いていたとしても,そもそもdatabase
タイプのエンドポイントにアクセスができないのでシークレットが発行されず,MySQLにログインすることすらできない.まとめると,ポリシーはエンドポイント単位でのアクセスコントロールを制御し,ロールはエンドポイントに対応しているSecret Engineの中でもっと細かいアクセスコントロールを制御するものだと思う.
まとめ
- HashiCorpのVaultハンズオンを一部試してみた
- Vaultの日本語ハンズオンはとても分かりやすかった.Vaultが何か分からない方におすすめ!
- 認証を絡めたハンズオンもいくつかあるのでやっていこうと思う.また,この記事を書いている間にもハンズオンが変更されたり増えていたりしたのでまた試してみようと思う.