HashiCorp Vault ServerをAmazon EC2に構築する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

前回はHashiCorp Vaultについての基礎知識を確認し、ローカルPC(MacBook Pro)にDev Serverとして導入してみました。

今回はAmazon EC2上にHashiCorp Vault Serverを構築し、ローカルPCから接続してみます。

やってみた

サーバ側作業

Amazon EC2を起動します。OSはAmazon Linux 2017.09です。まずはビルドに必要となるGolangをインストールします。

$ sudo yum install go

ところが、ここでインストールされるGolangは1.8.4で、HashiCorp Vaultに必要な1.9以上ではありません。

$ go version
go version go1.8.4 linux/amd64

そこで、最新バージョンであるGolang 1.9.3を取得し、/usr/local下に展開します。

$ sudo wget https://storage.googleapis.com/golang/go1.9.3.linux-amd64.tar.gz
$ tar xvzf go1.9.3.linux-amd64.tar.gz
$ sudo mv go /usr/local

goコマンドのシンボリックリンクを張り替えます。

$ sudo mv /usr/bin/go /usr/bin/go.org
$ sudo ln -s /usr/local/go/bin/go /usr/bin/go

確認。1.9.3が動作しています。

$ go version
go version go1.9.3 linux/amd64

$GOPATHの設定と、$GOPATH/binにパスが通っていないとコンパイルでエラーが発生しますので、設定しておきます。

$ export GOPATH=~
$ export PATH=$PATH:$GOPATH/bin

必要なディレクトリを作成し、そこにgithubからソースをcloneしてきます。

$ mkdir -p $GOPATH/src/github.com/hashicorp
$ cd $GOPATH/src/github.com/hashicorp
$ git clone https://github.com/hashicorp/vault.git
$ cd vault

make bootstrapし、必要なビルドルールを入手します。

$ make bootstrap

Installing/Updating github.com/mitchellh/gox
Installing/Updating github.com/kardianos/govendor
Installing/Updating github.com/client9/misspell/cmd/misspell

makeでビルドします。devを付与することで、クロスコンパイルなしの、ローカルPCのみのバイナリを作成します。

$ make dev

ビルドが終わったら動作確認します。

$ which vault
/Users/ec2-user/bin/vault

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

前回起動したDev Serverは一切設定が要りませんでしたが、今回はConfigファイルの作成が必要になります。内容の詳細は後日ブログにします。まずは以下のように、ストレージをインメモリに、TLSをdisableにすれば、とりあえず起動します。

$ vi ~/config.hcl
storage "inmem" {}

listener "tcp" {
 address     = "EC2のプライベートIPアドレス:8200"
 tls_disable = true
}

そしてConfigファイルを指定して起動します。

$ sudo ./bin/vault server -config=config.hcl

クライアント側の作業

さて、Vaultがインストールされたクライアント側での作業です。Vault Serverのアドレスを環境変数に設定します。

$ export VAULT_ADDR='http://EC2のパブリックIPアドレス:8200'

この状態でコマンドを投げると...以下のようにエラーになります。

$ vault secrets list
Error listing secrets engines: Error making API request.

URL: GET http://EC2のパブリックIPアドレス:8200/v1/sys/mounts
Code: 503. Errors:

* Vault is sealed

これはVaultのSeal/Unsealという仕組みによるものです。以下の図はHashiCorp VaultのサイトのArchitectureページからの引用です。

Vaultはデータを格納する際に暗号化キーを使いますが、その暗号化キー自体がマスターキーというもので暗号化されています。そしてマスターキーはVault上には保存されません。このため、Vaultに不正にアクセスしたとしても、それだけではデータを復号することは不可能です。更にマスターキーは5つに分割された状態になっており、必要な分だけ入手しないと復号できません。

Vaultが起動した時には、何ら操作が出来ない状態になっています。これをSeal(封印状態)と言います。マスターキーによってUnseal(開封状態)にすることで初めて操作が可能になります。

まず、作成したVault Serverを初期化します。このコマンドを実行することで、5つに分割したマスターキーと、RootのTokenが入手出来ます。これらの値は別途保存しておいて下さい。

$ vault operator init
Unseal Key 1: hguhi+/2/Jr003ZNnBL4sL46+MGrPvAFjZNN2nkXpOUH
Unseal Key 2: GW/IvXDn/ZcYDgKO2EV5iVrAnUptdsSdokQ74AoYwrVD
Unseal Key 3: qoBgM3a/ScGeJm9eO4GOAbqQSaJ0E6I1LIFo8oCzR6pX
Unseal Key 4: Q+wCpTJC+ck+uJ5NQdsWfSI7Y4wm9Ei6Rrirn5GjkhjL
Unseal Key 5: UWyNe8mLySNksn/72mG/5nLm4IPQ4Ubi+WZ9+PwEZ7BE

Initial Root Token: d66539e9-db8f-a929-d7b9-493eb9ed0797

Vault initialized with 5 key shares an a key threshold of 3. Please securely
distributed 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 rekey" for more information.

Vault Serverの状態確認。Sealedがtrueなので封印状態になっていることが分かります。またTotal Sharesがマスターキーの分割数、ThresholdがUnsealするための必要数です。この場合、分割されたマスターキーを3つ入力すれば、Unsealにすることが出来ます。

$ vault status
Key                Value
---                -----
Seal Type          shamir
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    0/3
Unseal Nonce       n/a
Version            0.9.3
HA Enabled         true
HA Mode            sealed

ではUnesealしていきます。まずは1つめのマスターキーを入力します。Unseal Progressが0/3から1/3になったことが分かります。

$ 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       c1dfe7bd-242c-2845-7d87-15f8e3ba7d3e
Version            0.9.3
HA Enabled         true
HA Mode            sealed

続いて2つめ。

$ vault operator unseal
Unseal Key (will be hidden):
(...snip...)
Unseal Progress    2/3
(...snip...)

3つめ。Sealedがfalseになりました。

$ vault operator unseal
Unseal Key (will be hidden):
(...snip...)
Sealed          false
(...snip...)

Root Tokenを使ってloginします。

$ vault login d66539e9-db8f-a929-d7b9-493eb9ed0797
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              d66539e9-db8f-a929-d7b9-493eb9ed0797
token_accessor     87087659-856b-f3ed-cf4a-e67e9e213985
token_duration     ∞
token_renewable    false
token_policies     [root]

コマンドを投げてみます。

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

コマンドが通りました!

さて、再度Sealにしてみます。

$ vault operator seal
Success! Vault is sealed.

この状態でコマンドを投げると失敗します。ちゃんとUnsealからSealになっていることが分かります。

$ vault secrets list
Error listing secrets engines: Error making API request.

URL: GET http://13.113.132.40:8200/v1/sys/mounts
Code: 503. Errors:

* Vault is sealed

さいごに

これでHashiCorp Vault Serverを立ち上げることができました。今後確認したいことは以下の通りです。

  • サーバ起動時のConfigについて
  • データの保存先について
  • 認証について
  • 監査ログについて
  • Dynamic Secrets機能について
  • LeaseとRenewal機能について