HashiCorp Vaultの基礎知識と導入

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

Vaultとは

VaultHashiCorpが2015年4月28日にリリースしたソフトウェアです。リリース時のブログは以下をご参照下さい。

Vaultは、機密情報を管理するためのソフトウェアです。現在の情報システムでは機密情報は多岐にわたり、ユーザー名やパスワードはもちろん、APIキーや証明書など、様々な種類のものが様々な形式で存在します。また保存される場所も違うし、場所が違うってことはアクセス制御のやり方や管理の仕方も違います。こういった機密情報を統合的に一貫して管理しアクセスコントロールするものがVaultです。クライアント/サーバ型で動作し、クライアントで機密情報の保管や取得のコマンドを実行し、機密情報自体はサーバに保管されます。

なお2018年2月5日時点での最新バージョンは0.9.3です。

Vaultの主な機能

Vaultの主な機能は次のとおりです。

  • Secure Secret Storage ... Vaultは機密情報をkey/valueの形で値を格納しますが、サーバのストレージに書き込む前に暗号化しています。このため、そのままストレージにアクセスしても機密情報を取得することは出来ません。
  • Dynamic Secrets ... Vaultは機密情報をオンデマンドで生成することが出来ます。例えばAWSへのアクセスキー等です。アプリケーションがAWSにアクセスする際にVaultにアクセス権を要求すると、Vaultは必要なアクセス権を持つAWSアクセスキーを生成し、アプリケーションに渡します。この動的に生成した機密情報には期間が設定され、期間が過ぎたら自動的に取り消しされます。
  • Data Encryption ... データの暗号化及び復号が出来ます。Vaultがこの処理の際にデータの保存を行いませんので、一時保存されたデータの流出を懸念する必要はありません。
  • Leasing and Renewal ... 機密情報に期限が設定出来ます。期限が過ぎた機密情報は自動的に削除されます。期限を延長することも可能です。
  • Revocation ... 機密情報をRevoke(失効)することが出来ます。Revokeは単一のkeyによる指定だけでなく、特定の機密をまとめて削除することが出来ます。Leaseとrevokeを活用することで、key rolling(機密情報の周期的な更新)を促すことが可能です。
  • Audit Log ... 認証、機密情報へのアクセス、動的生成、Revoke等、全ての処理に対し詳細な監査ログが保存出来ます。

Vaultのライセンス

Vaultには3つのライセンス形態が用意されています。

  • Open Source ... オープンソース版です。上記の主な機能は全て使えます。
  • Pro ... ディザスターリカバリー対策機能があり、Vaultの機密情報が格納されたクラスターが複数のデータセンターで動作し、ストレージはレプリケーションされ、障害発生時にはフェイルオーバーします。商用環境の利用であればDR対策は必須でしょう。またクラスターを管理するためのUIが提供されます。9x5のSLA付きサポートもセットとなっています。
  • Premium ... HSMでの提供がサポートされます。またMFAも使うことが出来ます。大きいのがFIPS 140-2に対応していることで、FIPS 140が必須要件のシステムであればPremiumライセンスを利用することになるでしょう。24x7のSLA付きサポートもセットとなっています。

やってみる

本来であればサーバとクライアントは別々に立てるところですが、今回はまずVaultの動作を確認するところから進めたいと思いますので、ローカルPC上にサーバを立ち上げ、クライアントもローカルPCから使いたいと思います。

Vaultのインストール

Vaultのインストールは、バイナリファイルを使う方法と、githubにあるソースgopath を使う方法があります。今回は後者のソースからのインストールを行います。環境にはGolang(1.9以上)が導入されている必要があります。

$ go version
go version go1.9.3 darwin/amd64

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

$ 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/sasakidaisuke/bin/vault

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

Vaultのコマンド補完のインストール

単にvaultをビルドしインストールした状態だと、Vaultのオプションについてコマンド補完が効きません。

$ vault re
↑ここでtabキーを押しても補完されない

そこでコマンド補完をインストールします。

$ vault -autocomplete-install
$ exec $SHELL

動作確認。

$ vault re
↑ここでtabキーを押すと...↓
$ vault read

補完されました!

開発モードでサーバを起動する

Vaultサーバには、開発モードであるDev Serverが用意されています。Dev Serverはデータを暗号化した上でメモリ上に保管されるため、停止するとデータは消去されます。またデータへの接続はTLSなしで行われますため、通信経路上はセキュアではありません。本番環境や機密情報を保管するためには使えませんが、とりあえず動作確認のために開発モードで立ち上げてみます。

$ vault server -dev
==> Vault server configuration:

                     Cgo: disabled
         Cluster Address: https://127.0.0.1:8201
              Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", tls: "disabled")
               Log Level: info
                   Mlock: supported: false, enabled: false
        Redirect Address: http://127.0.0.1:8200
                 Storage: inmem
                 Version: Vault v0.9.3
(...snip...)

このプロセスはフォアグラウンドで起動するため、コンソールが専有されます。以降のクライアントの操作は別ターミナルを起動して行います。

別ターミナルを起動し、Vaultサーバを起動時に表示されたVAULT_ADDRを設定します。

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

Vaultサーバのステータスを確認します。

$ vault status
Key             Value
---             -----
Seal Type       shamir
Sealed          false
Total Shares    1
Threshold       1
Version         0.9.3
Cluster Name    vault-cluster-XXXX
Cluster ID      XXXX
HA Enabled      false

値を書いてみる

では実際に値を書き込んでみます。writeの箇所で、keyの前に「secret/」と付与する必要があります。詳細は後日アーキテクチャのところで説明できればと思います。

$ vault write secret/sasakidaisuke value=smokeymonkey
Success! Data written to: secret/sasakidaisuke

値を読んでみる

上記で書き込んだ値を読み込みんでみます。writeの箇所で、keyの前に「secret/」と付与する必要があります。詳細は後日アーキテクチャのところで説明できればと思います。

$ vault read secret/sasakidaisuke
Key                 Value
---                 -----
refresh_interval    768h
value               smokeymonkey

JSON形式で読み込むことも出来ます。

$ vault read -format=json secret/sasakidaisuke
{
  "request_id": "20af30ef-0d59-3eff-5bf1-d62a079048f7",
  "lease_id": "",
  "lease_duration": 2764800,
  "renewable": false,
  "data": {
    "value": "smokeymonkey"
  },
  "warnings": null
}

値を削除する

値の削除はdeleteオプションで可能です。

$  vault delete secret/sasakidauske
Success! Data deleted (if it existed) at: secret/sasakidauske

さいごに

とりあえず手を動かしてVaultを知りました。引き続き詳細の調査をしていきたいと思います。