HashiCorp Vault で HTTP API を利用する

# はじめに
INTERACTIVE TUTORIALでVaultの基本操作を学習できたので、HTTP APIが利用できる環境を構築しました。

手順や設定は[Deploy Vault \- Getting Started](https://www.vaultproject.io/intro/getting-started/deploy.html)を参考にしてます。

**もくじ**
1. Vault インストール
2. Vault devモード
3. Consul
4. Vault 設定ファイル
5. Vault 起動
6. HTTP API
補足. 外部からアクセス可能にする

**参考**
[HashiCorp Vault の基本操作を INTERACTIV TUTORIAL で学習する \- Qiita](http://qiita.com/NaokiIshimura/items/1aa56e0789d44059b30b)

# 1. Vault インストール

Vaultが利用できる環境を準備します。

## ダウンロード＆解凍

[Download Vault](https://www.vaultproject.io/downloads.html)ページで実行する環境向けに提供されてるVaultのURLを確認してダウンロード＆解凍します。

```shell-session
$ mkdir -p ~/vault/bin
$ cd ~/vault/bin
$ curl -O https://releases.hashicorp.com/vault/0.8.0/vault_0.8.0_linux_amd64.zip
$ unzip vault_0.8.0_linux_amd64.zip
```

## 環境変数

vaultを配置したディレクトリへPATHを設定します。

```shell-session
$ echo export PATH='$PATH:~/vault/bin' >> ~/.bash_profile
$ source ~/.bash_profile
```

## バージョン確認

PATHが通ってることを確認するためにバージョン確認コマンドを実行します。

```shell-session
$ vault version
```

# 2. Vault devモード

Vaultをdevモードで起動してHTTP APIを実行します。

## devモード起動

Vaultをdevモードで起動します。
起動するとCLIの実行に必要な環境変数、`Unseal Key`、`Root Token`が表示されます。

```shell-session
$ 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: true, enabled: false
        Redirect Address: http://127.0.0.1:8200
                 Storage: inmem
                 Version: Vault v0.8.0
             Version Sha: af63d879130d2ee292f09257571d371100a513eb
==> WARNING: Dev mode is enabled!

In this mode, Vault is completely in-memory and unsealed.
Vault is configured to only have a single unseal key. The root
token has already been authenticated with the CLI, so you can
immediately begin using the Vault CLI.

The only step you need to take is to set the following
environment variables:

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

The unseal key and root token are reproduced below in case you
want to seal/unseal the Vault or play with authentication.

Unseal Key: Ne7OUcfKh3RoJXpnuCfoxHE+MrrjORR2JkVTRSB2TE8=
Root Token: 7df8faaf-f7d7-dfa3-ca95-728c9e756eb6
```

## 動作確認

devモードで起動しているVaultに対して機密情報の読み書きができることを確認します。

```shell-session
$ export VAULT_ADDR='http://127.0.0.1:8200'

$ vault write secret/hello value=world
Success! Data written to: secret/hello

$ vault read secret/hello
Key                     Value
---                     -----
refresh_interval        768h0m0s
value                   world
```

## devモード停止

`Ctrl + C`でdevモードを停止させます

# 3. Consul

[Deploy Vault](https://www.vaultproject.io/intro/getting-started/deploy.html)ページにはConsuleと組み合わせて利用する方法で解説されてるため、Consuleをインストールします。

## ダウンロード＆解凍

[Download Consul](https://www.consul.io/downloads.html)ページで実行する環境向けに提供されてるVaultのURLを確認してダウンロード＆解凍します。

```
$ mkdir -p ~/consule/bin
$ cd ~/consule/bin
$ curl -O https://releases.hashicorp.com/consul/0.9.2/consul_0.9.2_linux_amd64.zip
$ unzip consul_0.9.2_linux_amd64.zip
```

## 環境変数

consuleを配置したディレクトリへPATHを設定します。

```shell-session
$ echo export PATH='$PATH:~/consule/bin' >> ~/.bash_profile
$ source ~/.bash_profile
```

## バージョン確認

PATHが通ってることを確認するためにバージョン確認コマンドを実行します。

```shell-session
$ consule version
```

## 起動

Consuleを起動します。

```shell-session
$ consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul -bind 127.0.0.1
```

# 4. Vault 設定ファイル

Vaultの設定ファイルを用意します

## 作成

[Deploy Vault](https://www.vaultproject.io/intro/getting-started/deploy.html)ページで紹介されている設定ファイルはリクエストを`127.0.0.1:8200`で受け付けて、機密情報をConsuleの`-data-dir`に保存する内容のようです。

```shell-session
$ mkdir ~/vault/config
$ cd ~/vault/config
$ vi example.hcl
```

```text:example.hcl
storage "consul" {
  address = "127.0.0.1:8500"
  path = "vault"
}

listener "tcp" {
 address = "127.0.0.1:8200"
 tls_disable = 1
}
```

# 5. Vault 起動

# 起動

設定ファイルを指定してVaultを起動します。

```shell-session
$ cd ~/vault/config
$ vault server -config=example.hcl
```

## 補足

mlockが利用できない環境ではvault起動に失敗するので、mlockを利用しないオプションを設定ファイルに追記した上で起動します。

```shell-session
$ vault server -config=example.hcl
Error initializing core: Failed to lock memory: cannot allocate memory

This usually means that the mlock syscall is not available.
Vault uses mlock to prevent memory from being swapped to
disk. This requires root privileges as well as a machine
that supports mlock. Please enable mlock on your system or
disable Vault from using it. To disable Vault from using it,
set the `disable_mlock` configuration option in your configuration
```

```text:example.hcl
storage "consul" {
  address = "127.0.0.1:8500"
  path = "vault"
}

listener "tcp" {
 address = "127.0.0.1:8200"
 tls_disable = 1
}

disable_mlock = 1
```

#6. HTTP API

## リクエスト

VaultにHTTPでリクエスを送ります。
成功するとレスポンスがjson形式で返ってきます。

```
$ curl http://127.0.0.1:8200/v1/sys/init
{"initialized":false}
```

HTTP APIを利用したリクエストの送信方法については[Using the HTTP APIs with Authentication](https://www.vaultproject.io/intro/getting-started/apis.html)ページに詳しい解説があります。

# 補足. 外部からアクセス可能にする

設定ファイルの`listener address`に`0.0.0.0:80`を指定すると、外部からHTTP APIを利用することができます。その場合は`proxy_protocol_behavior`、`proxy_protocol_authorized_addrs`オプションを利用してリクエストを受け付けるソースIPを制限したほうが安全です。

```text:sample.hcl
storage "consul" {
  address = "127.0.0.1:8500"
  path = "vault"
}
listener "tcp" {
 address = "0.0.0.0:80"
 tls_disable = 1
 proxy_protocol_behavior = "deny_unauthorized"
 proxy_protocol_authorized_addrs = "xxx.xxx.xxx.xxx"
}
```