AWS
Security
やってみた
Vault
Hashicorp

Hashicorp Vault 1.0で追加されるauto-unsealを試してみた


はじめに

Ateam Lifestyle x cyma Advent Calendar 2018 の3日目は 株式会社エイチームライフスタイル 技術開発部 / 名古屋開発部 部長 の @tsutorm が担当します!

エンジニアマネージャーとして学んできたこと とか書こうかなーと思ってたんですが、@ihsiek からマイナーネタ好きを振られたので、マイナーネタでお送りします!!!


お品書き


  • Hashicorp Vault 1.0.0で搭載されるauto-unsealを試す

  • AWS KMSをつかうよ


Hashicorp Vaultとは

詳しい説明は以下におまかせしますが、簡単にいうと秘密管理/データ暗号化サーバーです。

Response Wrapping など、より安全性を高める仕組みが搭載されており、同社の 構成管理ツール Terraform や サービスメッシュのConsulと組み合わせて利用することで、アプリケーションの秘密情報を安全に管理することができるスグレモノです。

大きな特徴として、シャミアの秘密分散法 というアルゴリズムを用いてVault内部で利用する秘密鍵を複数の鍵に分散して管理しておくことで、マスターキー管理における安全性を高めています。

そのため、サーバー起動時は Seal(封印) 状態になっており、分散した鍵情報を一定閾値数入力しなければ Unseal(封印解除) せず、サービスを利用することはできません。

核ミサイル発射スイッチの解除みたいで、中二病満載な感じしませんか?こういうの大好きです。

反面、予期しないサーバーダウンなど発生した場合、プロセス自動起動は用意したものの、Seal状態の解除が出来ず、サービス利用に問題がでる懸念があります。

Vault 0.x 系においては Enterprise Edition で 自動的にunsealを行う auto-unseal 機能がありましたが、Opensource Editionでは提供されておりませんでした。

しかし、Vault 1.0 からは Opensource版でもこの auto-unseal が利用できるとのこと。

早速試してみましょう!!


手順の概要


  • AWS KMS側の設定を行い、KMSとそれを利用するためのIAMをセットアップします。

  • Hashicorp Vault 1.0.0-beta2 側に awskms seal 設定を追加します。

  • Vaultを初期化してKMS経由でのauto-unsealができることを確認します。


免責


  • もうすぐVault 1.0が出るっぽいのでほぼ仕様変わらないと思いますが、変わった際の本コンテンツの連動はベストエフォートです

  • ハンズオンなどで色々お試しする際は、tokenやkeyの情報をうっかりgithubに上げないように。


準備

公式のデモ/ハンズオンでは terraform を使ってガッと作ってしまいますが、どうも中身がわからないと気持ち悪いので、私の方でdocker/docker-composeベースのもう少し簡単なお試し環境を用意しました。

$ git pull https://github.com/tsutorm/demo-vault_auto_unseal.git

$ cd demo-vault_auto_unseal

docker-compose upでvaultサーバーが立ち上がります。./scripts/attach_vault.sh でアタッチして、vault status などのコマンドをお試しできます。

基本的には公式の以下ドキュメントに準拠しています。

AWSを利用しますので、アカウント無い方は適当に作っておいてください。


IAMの作成とアクセスキーの振り出し

IAMで適当なユーザーを追加しておきます。

Screenshot 2018-12-02 at 13.36.22.png

ポリシーはkms:Encrypt, kms:Decrypt, kms:DescribeKey の 3つのみで良いので、以下で作成して、アタッチしておきます。

{

"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:DescribeKey"
],
"Resource": "*"
}
]
}

image.png

アクセスキーとシークレットキーを控えておきましょう。


KMSの有効化

KMSコンソールで CreateKey を実施します

Screenshot 2018-12-02 at 13.50.40.png

Define key administrative permissions は追加したIAMではなく、管理者のIAMを選択しておきます。概ね、ご自身のIAMを登録しておけばよいです。

Define key usage permissions では先程追加したIAMを選択してください。

ま、適当にnextしちゃってください。大丈夫。

こんな感じでKeyIDが発行されます。

(以下 key-id は記事公開のタイミングで削除してあります)

Screenshot 2018-12-02 at 13.55.14.png


demo.hclを編集してauto-unsealの設定を追加

以下を demo.hcl へ追加して、auto-unsealできるようにします。

今回はデモなんでvpc endpointは使ってませんが、本運用ではendpointを指定するようにしてください。

seal "awskms" {

region = "ap-northeast-1"
access_key = "{発行したIAMのAccessKey}"
secret_key = "{発行したIAMのSecretKey}"
kms_key_id = "642b1b91-d1bc-45ca-a7cb-10da40b51b23"
endpoint = ""
}


vault operator init を実行してKMS経由で鍵を発行する

では早速vaultを起動してみましょう。

$ docker-compose up

Creating network "demo-vault_auto_unseal_default" with the default driver
Creating demo-vault_auto_unseal_vault_1 ... done
Attaching to demo-vault_auto_unseal_vault_1
vault_1 | Couldn't start vault with IPC_LOCK. Disabling IPC_LOCK, please use --privileged or --cap-add IPC_LOCK
vault_1 | ==> Vault server configuration:
vault_1 |
vault_1 | AWS KMS KeyID: 642b1b91-d1bc-45ca-a7cb-10da40b51b23
vault_1 | AWS KMS Region: ap-northeast-1
vault_1 | Seal Type: awskms

Seal Typeawskmsに変わってますね。

vault operator init してみましょう。KMSで管理する都合、鍵は分散させず1本となります。引数に-stored-shares=1 -recovery-shares=1 -recovery-threshold=1 -key-shares=1 -key-threshold=1 とあるので、追加忘れにご注意ください。

tokenは***としてあります。

# vault operator init -stored-shares=1 -recovery-shares=1 -recovery-threshold=1 -key-shares=1 -key-threshold=1

Recovery Key 1: *****

Initial Root Token: *****

Success! Vault is initialized

Recovery key initialized with 1 key shares and a key threshold of 1. Please
securely distribute the key shares printed above.

vault statusすると...

# vault status

Key Value
--- -----
Recovery Seal Type shamir
Initialized true
Sealed false
Total Recovery Shares 1
Threshold 1
Version 1.0.0-beta2
Cluster Name vault-cluster-ce6d42aa
Cluster ID a4231c7f-9601-e404-814e-5947da0a8ce9
HA Enabled false

むむ!!! Recovery Seal Typeshamirに戻っている...んですが、気にしないでください。これで大丈夫。

この時点で Valutサーバーを再起動します。

$ docker-compose up

Starting demo-vault_auto_unseal_vault_1 ... done
Attaching to demo-vault_auto_unseal_vault_1
vault_1 | Couldn't start vault with IPC_LOCK. Disabling IPC_LOCK, please use --privileged or --cap-add IPC_LOCK
vault_1 | ==> Vault server configuration:
vault_1 |
vault_1 | AWS KMS KeyID: 642b1b91-d1bc-45ca-a7cb-10da40b51b23
vault_1 | AWS KMS Region: ap-northeast-1
vault_1 | Seal Type: awskms
vault_1 | Cgo: disabled
vault_1 | 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")
vault_1 | Log Level: (not set)
vault_1 | Mlock: supported: true, enabled: false
vault_1 | Storage: file
vault_1 | Version: Vault v1.0.0-beta2
vault_1 | Version Sha: 8f61c4953620801477ad40f9d75063659acb5d84
vault_1 |
vault_1 | ==> Vault server started! Log data will stream in below:
vault_1 |
vault_1 | 2018-12-02T05:16:32.956Z [WARN] no `api_addr` value specified in config or in VAULT_API_ADDR; falling back to detection if possible, but this value should be manually set
vault_1 | 2018-12-02T05:16:32.958Z [INFO] core: stored unseal keys supported, attempting fetch
vault_1 | 2018-12-02T05:16:33.099Z [INFO] core: vault is unsealed
vault_1 | 2018-12-02T05:16:33.099Z [INFO] core: post-unseal setup starting
vault_1 | 2018-12-02T05:16:33.099Z [INFO] core: loaded wrapping token key
vault_1 | 2018-12-02T05:16:33.099Z [INFO] core: successfully setup plugin catalog: plugin-directory=
vault_1 | 2018-12-02T05:16:33.100Z [INFO] core: successfully mounted backend: type=kv path=secret/
vault_1 | 2018-12-02T05:16:33.101Z [INFO] core: successfully mounted backend: type=system path=sys/
vault_1 | 2018-12-02T05:16:33.101Z [INFO] core: successfully mounted backend: type=identity path=identity/
vault_1 | 2018-12-02T05:16:33.101Z [INFO] core: successfully mounted backend: type=cubbyhole path=cubbyhole/
vault_1 | 2018-12-02T05:16:33.103Z [INFO] core: successfully enabled credential backend: type=token path=token/
vault_1 | 2018-12-02T05:16:33.103Z [INFO] core: restoring leases
vault_1 | 2018-12-02T05:16:33.103Z [INFO] rollback: starting rollback manager
vault_1 | 2018-12-02T05:16:33.103Z [INFO] identity: entities restored
vault_1 | 2018-12-02T05:16:33.103Z [INFO] expiration: lease restore complete
vault_1 | 2018-12-02T05:16:33.103Z [INFO] identity: groups restored
vault_1 | 2018-12-02T05:16:33.103Z [INFO] core: post-unseal setup complete
vault_1 | 2018-12-02T05:16:33.103Z [INFO] core: starting listener: listener_address=127.0.0.1:8201
vault_1 | 2018-12-02T05:16:33.104Z [INFO] core: serving cluster requests: cluster_listen_address=127.0.0.1:8201
vault_1 | 2018-12-02T05:16:33.103Z [INFO] core: successfully unsealed with stored key(s): stored_keys_used=1

successfully unsealed ってなってますね!! 試しに vault status を見てみましょう。

# vault status

Key Value
--- -----
Recovery Seal Type shamir
Initialized true
Sealed false
Total Recovery Shares 1
Threshold 1
Version 1.0.0-beta2
Cluster Name vault-cluster-bedd5d4f
Cluster ID df5a9ba2-511b-e0f1-cbe3-0724ec33c455
HA Enabled false

Sealed false でちゃんと auto-unseal が成功しています。loginも試してみましょう。

/ # vault login

Token (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 *****
token_accessor 3q5pBW2RPR8rcoEyIkHGtvqa
token_duration ∞
token_renewable false
token_policies ["root"]
identity_policies []
policies ["root"]

大丈夫ですね。


まとめ


  • Vault 1.0.0-beta2とAWS KMSを使ったauto-unsealはOSS版でも簡単にできました。

  • Seal-Keyのローテーションなどもできそうなので、よりVaultサーバーを安全に可用性も担保しながら使えそう。


おわりに

エイチームライフスタイルでは、ナビクル などのWebサービス運営を行っています。これらのサービスでは個人情報などの機密情報を取り扱っており、セキュリティの担保はサービス運営で重要な要素となっています。

今回取り上げたVaultは機能が豊富な反面、マネージドサービスではない事、自分で可用性担保などの構成の面倒を見ないといけないところ、そもそもそんな高度な暗号化機構が必要なの?というところから、Redditでも議論(Hashicorp Vault vs KMS) になっています。

しかし、使ってみて自分たちがどう評価するか。 が大事ではないでしょうか。

今後も色々挑戦して行きたいと思います!


Ateam Lifestyle x cyma Advent Calendar 2018 の4日目は、@matsu06 がお送りします!!どんなネタを用意してくるのか楽しみです!!


そんな"挑戦"を大事にするエイチームグループでは、一緒に働けるチャレンジ精神旺盛な仲間を募集しています。興味を持たれた方はぜひエイチームグループ採用サイトを御覧ください。

https://www.a-tm.co.jp/recruit/