HashiCorp Vault ServerをAmazon EC2に構築する
はじめに
前回は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機能について