HashiCorp Vaultをバックエンド・ストレージをMySQLにして試してみた

概要

HashiCorpが提供しているVaultというツールを使ってみました。
Vault by HashiCorp


VaultはパスワードやAPIキーなど機密情報を安全に読み出したり保存出来るツールです。
今回機密情報をMySQLに保存する方法を試してみました。
データをMySQLに保存することによってデータのレプリケーションなどRDBMSの恩恵を受けることが出来ます。

環境

Vault v0.2.0
MySQL 5.6.23-1

Vaultサーバー

まずはVaultサーバーを起動します。
起動する前に設定ファイル(vault.json)を用意します。
設定ファイルはjson形式で記述します。

vault.json

MySQLの情報、待ち受けるIPアドレスとポート番号が書いてあります。

backend "mysql" {
  username = "dbadmin"
  password = "dbadminpassword"
  address = "127.0.0.1:3306"
  path = "vault"
}

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

telemetry {
  statsite_address = "127.0.0.1:8125"
  disable_hostname = true
}


Vaultサーバー起動

先ほど作成した設定ファイルを読み込ませてVaultサーバーを起動します。

vault server -config=./vault.json


表示例

[root@tsunokawa ~]# vault server -config=./vault.json
==> Vault server configuration:

         Log Level: info
             Mlock: supported: true, enabled: true
           Backend: mysql
        Listener 1: tcp (addr: "127.0.0.1:8200", tls: "disabled")

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


Vaultサーバーが起動するとvaultという名前のDBが作成されています。

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
| vault              |
+--------------------+
5 rows in set (0.00 sec)

mysql>


vaultというテーブルも作成されています。

mysql> show tables;
+-----------------+
| Tables_in_vault |
+-----------------+
| vault           |
+-----------------+
1 row in set (0.00 sec)

mysql> 


vaultテーブルの情報です。

mysql> show create table vault\G
*************************** 1. row ***************************
       Table: vault
Create Table: CREATE TABLE `vault` (
  `vault_key` varchar(512) NOT NULL DEFAULT '',
  `vault_value` mediumblob,
  PRIMARY KEY (`vault_key`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> 


vaultテーブルの中身は何もありません。

mysql> select * from vault;
Empty set (0.00 sec)

mysql> 


クライアント

次にVaultサーバーに接続するクライアント側の設定を行います。
環境変数を渡します。

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


vault init
vault init

ここで表示されるKey1からKey5そしてInitial Root Tokenは必ず控えておいてください。


表示例

[[root@tsunokawa ~]# vault init
Key 1: ef64384393543d24e1268911b2973fc4f74ccc960c2d48a77d19c639aeed407601
Key 2: a2a8e084e54e7467c8cc561ae9a970e1e9ee0e6d832863ecc6cd00f1830f120d02
Key 3: 902194f180f709ab89269c7de9c75205a0bd4265442f07c2ed7d89d55d36fb2f03
Key 4: 4f4c043299b53dddf5dd3710735f63f129a1d1c2021e98a7581dd278c6eb179204
Key 5: 7dc57047fc0c4011b437fd777335411560f2a5cac519fc8973ad5b5c18d2feb005
Initial Root Token: 41e2f7a6-62ed-d241-647b-1ee166a0a6e3

Vault initialized with 5 keys and a key threshold of 3. Please
securely distribute the above keys. When the Vault is re-sealed,
restarted, or stopped, you must provide at least 3 of these keys
to unseal it again.

Vault does not store the master key. Without at least 3 keys,
your Vault will remain permanently sealed.
[root@tsunokawa ~]# 


vault unseal
vault unseal

このvault unsealを3回繰り返します。
Keyを求められたら先ほどのvault initで表示されたKey1からKey5のうち3つ選んで入力します。

1回目

[root@tsunokawa ~]# vault unseal
Key (will be hidden): 
Sealed: true
Key Shares: 5
Key Threshold: 3
Unseal Progress: 1


2回目

High-Availability Enabled: false
[root@tsunokawa ~]# vault unseal
Key (will be hidden): 
Sealed: true
Key Shares: 5
Key Threshold: 3
Unseal Progress: 2


3回目

[root@tsunokawa ~]# vault unseal
Key (will be hidden): 
Sealed: false
Key Shares: 5
Key Threshold: 3
Unseal Progress: 0
[root@tsunokawa ~]# 

これでSealが解除されました。

vault authを実行
vault auth

Tokenを求められたらInitial Root Tokenで表示された値を入力してください。
※これ実行しないと後々の操作でpermission deniedとなります。


表示例

[root@tsunokawa ~]# vault auth
Token (will be hidden): 
Successfully authenticated! The policies that are associated
with this token are listed below:

root
[root@tsunokawa ~]# 


permission deniedの表示例

[root@tsunokawa ~]# vault policy-write secret acl.hcl
Error: Error making API request.

URL: PUT http://127.0.0.1:8200/v1/sys/policy/secret
Code: 403. Errors:

* permission denied
[root@tsunokawa ~]#


ACL設定

ACLを設定するため設定ファイル(acl.hcl)を作成しそれを読み込ませます。

acl.hclの中身

path "sys/*" {
  policy = "deny"
}

path "secret/*" {
  policy = "write"
}

この設定ファイルではsecret/以下の書き込みを許可させています。


読み込み

vault policy-write secret acl.hcl


表示例

[root@tsunokawa ~]# vault policy-write secret acl.hcl
Policy 'secret' written.
[root@tsunokawa ~]# 


ポリシーの確認

先ほど設定したACLのポリシーを確認します。

[root@tsunokawa ~]# vault policies
secret
root
[root@tsunokawa ~]#


情報の書き込み

実際に機密情報を書き込んでみます。

今回は

ID secret/password
hogehoge

を書き込みます。

vault write secret/password value=hogehoge


表示例

[root@tsunokawa ~]# vault write secret/password value=hogehoge
Success! Data written to: secret/password
[root@tsunokawa ~]# 


情報の読み出し

先ほど書きこんだ情報を読み出します。

vault read secret/password


表示例

[root@tsunokawa ~]# vault read secret/password
Key                Value
lease_id           secret/password/6b56c1cf-4043-1139-44fg-c93afe7cfb02
lease_duration     2592000
lease_renewable    false
value              hogehoge
[root@tsunokawa ~]#

ちゃんと値のhogehogeが返ってきているのが分かります。

TIPS

valueのみ表示させることも可能です。
vault read -field=value secret/password


表示例

[root@tsunokawa ~]# vault read -field=value secret/password
hogehoge
[root@tsunokawa ~]#


リモートのVaultサーバーに接続する場合

addreessを指定することでリモートのVaultサーバーに接続することが出来ます。

vault read -address='http://10.0.0.1:8200' secret/password