Carpe Diem

備忘録

HashiCorp VaultのSeal/Unseal

概要

Hashicorp Vaultは起動時はsealedというステータスになっており、リストを取得したりKey-Valueの値を取得することができません。
Vaultはセキュリティのため、データにアクセスする手段は知っていても起動時は復号の方法を知らないのです。

そこでUnsealというプロセスで復号用のマスターキーを複数の鍵から生成して復号できるようになっています。

f:id:quoll00:20180707083431p:plain

ref: Rekeying & Rotating Vault | Vault - HashiCorp Learn

なぜこのような仕組みを導入しているのかを説明します。

環境

  • Vault v0.10.3

シャミアの秘密分散法

なぜ単一のマスターキーを使うのでなく、複数の鍵からマスターキーを生成するのかというと、その方がセキュアである&故障に強いためです。
これはシャミアの秘密分散法と呼ばれるものです。

(k,n) しきい値

仕組みは以下です。

  1. 秘密情報をn個に分割する
  2. そのうちk個を使えば秘密情報が復元できる
  3. k-1個以下だと秘密情報が復元できない

これは (k,n) しきい値法と呼ばれます。

具体例

エンジニアが5人いるプロジェクトを想定します。

  • マスターキーを5つのシェアキーに分割する
  • 各エンジニアに1つのシェアキーを渡す
  • シェアキーが3つ揃えば復号できる

ということにします。

全員がマスターキーを持つ場合の問題点

それぞれがマスターキーを持つ場合、メンバーの一人が退職などで入れ替わったときにその人が持つマスターキーが漏洩する可能性があります。
しかしシャミアの秘密分散法ではシェアキーしか持たないため一人では復号できません
退職者のシェアキーだけでは復号できないのでマスターキーの共有よりもセキュアになります。

マネージャーだけがマスターキーを持つ問題点

漏洩リスクを懸念してこのルールにしているケースも往々にしてあります。しかし仮にマネージャーが病気・震災などに遭い動けない時に、マスターキーを持つ人間が居ないせいで復号自体できない問題が起きます。
シャミアの秘密分散法では3つ揃えば復号できるので、一部のメンバーが欠けても問題ありません。故障に強いと呼ばれる所以です。

Vaultで実際に試す

では実際にvaultで試してみましょう。Vaultでは初期化時に5つのシェアキーが発行されます。

$ vault operator init
Unseal Key 1: yIckDpIo7LL2K25QmXOzIJFlAP9AhSxletguC6YgjGIL
Unseal Key 2: msTRvUxT/hxavrd/KwfQke5l3HSr0r85DyWQF7ZcqH99
Unseal Key 3: sE7l5bM2LANUVwl8lrbneE0wXethCiC7bwYZ4TsfJ0vm
Unseal Key 4: bCz+Zk/NoNoM7v6GJbU9ZjOQNPbFovCUcLJtWvFe1y6h
Unseal Key 5: /hPhDKktOIf1PC4mD7F0nu2bVMOLOtlEeukHcbYk9fV/

Initial Root Token: 632d3c97-0966-6977-6d1d-c1047540466b

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.

シェアキーが3つ揃えば復号できる、とありますね。

次に復号のためのunsealコマンドを実行します。

$ vault operator unseal
Unseal Key (will be hidden):
Key                Value
---                -----
Seal Type          shamir
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    1/3
Unseal Nonce       11e96361-3fc6-8ee7-f7b1-bfa30424e3e0
Version            0.10.3
HA Enabled         true

Progressが1/3になりました。
2つめを入れます。

$ vault operator unseal 
Unseal Key (will be hidden): 
Key                Value
---                -----
Seal Type          shamir
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    2/3
Unseal Nonce       11e96361-3fc6-8ee7-f7b1-bfa30424e3e0
Version            0.10.3
HA Enabled         true

Progressが2/3になりました。
3つめを入れます。

$ vault operator unseal 
Unseal Key (will be hidden): 
Key                    Value
---                    -----
Seal Type              shamir
Sealed                 false
Total Shares           5
Threshold              3
Version                0.10.3
Cluster Name           vault-cluster-e6207235
Cluster ID             69bec15a-1e18-fa86-4abc-5bc83bb06ba2
HA Enabled             true
HA Cluster             n/a
HA Mode                standby
Active Node Address    <none>

復号されました!これ以降は自由にVaultで秘密情報の出し入れができるようになります。
今回は自分1人のローカルから実行しましたが、分散環境からでもunsealできます
つまり

  • AさんのPCで1つキーを入力
  • BさんのPCで1つキーを入力
  • CさんのPCで1つキーを入力

でもunsealできます。

注意

ちなみにこのシェアキーの入力はdummy値でもProgress自体は進みます
しかし3つ揃った時にマスターキーが生成できない=不正なシェアキーだとそこでエラーになります。

VaultでのRekey

秘密分散によりセキュアになることは分かりましたが、やはりメンバーの入れ替えが起きた時はキーの更新をしたくなります。
VaultにはRekeyという仕組みがあり、シェアキーを再生成することが可能です。

f:id:quoll00:20180707091206p:plain

ref: Rekeying & Rotating Vault | Vault - HashiCorp Learn

先程の図の左側の再生成ですね。

$ vault operator rekey -init -key-shares=5 -key-threshold=3
WARNING! If you lose the keys after they are returned, there is no recovery.
Consider canceling this operation and re-initializing with the -pgp-keys flag
to protect the returned unseal keys along with -backup to allow recovery of
the encrypted keys in case of emergency. You can delete the stored keys later
using the -delete flag.

Key                      Value
---                      -----
Nonce                    8f9b3127-8669-3d7e-5fc4-c96761718f2e
Started                  true
Rekey Progress           0/3
New Shares               5
New Threshold            3
Verification Required    false

RekeyにもUnseal Keyが必要なので入力していきます。

$ vault operator rekey
Rekey operation nonce: 8f9b3127-8669-3d7e-5fc4-c96761718f2e
Unseal Key (will be hidden): 
Key                      Value
---                      -----
Nonce                    8f9b3127-8669-3d7e-5fc4-c96761718f2e
Started                  true
Rekey Progress           1/3
New Shares               5
New Threshold            3
Verification Required    false

入力するとRekey Progressが進みます。

2つめ。

$ vault operator rekey
Rekey operation nonce: 8f9b3127-8669-3d7e-5fc4-c96761718f2e
Unseal Key (will be hidden): 
Key                      Value
---                      -----
Nonce                    8f9b3127-8669-3d7e-5fc4-c96761718f2e
Started                  true
Rekey Progress           2/3
New Shares               5
New Threshold            3
Verification Required    false

3つめ。

$ vault operator rekey
Rekey operation nonce: 8f9b3127-8669-3d7e-5fc4-c96761718f2e
Unseal Key (will be hidden): 

Key 1: R7PrwQGTrrDUqjoCJAQQ8Hacs0342OlC3vNRh4OHeCt5
Key 2: 0D1kyxR4AtvlxXjXKYsPXntIVtYkXbgsVbKit2L63n1w
Key 3: UbDEvfHj69C5oLJyoO5YQNqtHR90mrycRwyj507kj7sX
Key 4: lZ0fqtv4JnFtFgKX/fTYXVPPnRmiq+XfejkSoGhl3Wo5
Key 5: F4N9ddc9gPVErp9yHGZ5qSWwi+N9bJc40r1EnLxLtfVl

Operation nonce: 8f9b3127-8669-3d7e-5fc4-c96761718f2e

Vault rekeyed with 5 key shares and a key threshold of 3. Please securely
distributed the key shares printed above. When 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.

シェアキーが再生成できました。
これで古いシェアキーは3つ揃えても復号できなくなります。

Q&A

毎回シェアキーで復号するは手間じゃない?

Vaultがsealedステータスになるのは

  • 起動時(再起動含む)
  • vault operator sealコマンドでsealedに変更した時

なので、一度unsealedにすれば不便さは感じません。

unsealed状態のままで侵入されたらシェアキーが漏洩に関わらず秘密情報取れちゃうのでは?

はい、その場合は秘密情報が漏れる可能性があります。
しかしまだVaultサーバ自体にログインする必要がありますし、それを検知した時点でsealedに変更すれば被害を抑えることができます。
sealedになればシェアキーを3つ集めなくてはいけないので。

まとめ

初めてVaultのSeal/Unsealの仕組みを触った時はとても面倒だし、検証中だったので「シェアキーは全部自分が持ってるから意味ないのでは?」と感じました。
しかし仕組みを理解することによって、チーム開発ではちゃんとシェアキーを分散させることでセキュアに管理できることが分かりました。

ソース