2019年の振り返りと2020年の抱負

2019年も残りわずかとなりましたね。今年は自分の中でもいろいろと変わった年でもあり考えさせられた年でもありました。

こういうのは書いたことないですが、2019年の振り返りと2020年の抱負を書きなぐっていきたいと思います。

2019年の振り返り

とりあえず、自分の中で大きく変わったことだけ。

転職

9月に転職をしました。前職ではwebのシステム開発をしたりしていましたが、現在はゲーム開発に携わっており、インフラエンジニアとして働いています。 もともとゲーム作りたい、という思いもあり思い切って転職しました。よく「ゲーム作りたいのにインフラしてるの?」って聞かれますが、インフラもゲーム開発の一部だと思っています。

既存のタイトルにアサインされ運用保守やったり、インフラの改善業務とか、スクリプト書いたりとかいろいろやっています。web業界からゲーム業界に変わったことでインフラに対する目線は変わったところもありますが基本は一緒ですね。結局は動いてるシステムに応じてインフラをいい感じにする仕事なので、前職の経験も活かして仕事できています。

会社規模もだいぶでかくなりました。前職は50名程度だったんですが現職は2000人以上、ほとんど知らない人状態です。 廊下ですれ違っても「誰だろう、、、」っという人ばっかり。もちろん顔と名前が一致してる人は同じチームの人か一緒に仕事する人だけですね。

日ごろ運動しないのでせめて歩くぐらいはしようと思い、毎日1時間ぐらい歩いて通勤してます。 ちょうどいい運動ですし、考え事するのにちょうどいい時間です。

二度目の転職(来年入社)

今書くことではない気がしますが、、、今年やったこととして11月中旬から転職活動をし、無事に内定をもらいました。来年の2月から心機一転、新しい会社で頑張ります。

そう、転職したばっかりですが来年の1月いっぱいで辞めます。転職して数か月、自分の中でのもやもやとかいろいろとあり、短い期間ではありますが転職することを決意しました。

現職場において環境ですとか、仕事に対する考え方とか、いろんなものが自分とは合わないと感じました。 そして3年後、5年後、自分がここに残っているのか、残ってたとしてどうなっているのかと将来的なことを考えたときに不安もありました。

次の会社ではどうなるかわからないですが、楽しく仕事できるよう頑張ります。 ちなみに次もゲーム会社でインフラやります。インフラ頑張ります。

2020年の抱負

「ちゃんとここに書いたことを実践するんだぞ」っと将来の自分に向けて、、、書いていこうかと思います。

2020年のテーマ

なんとなくですが、2020年はテーマを持って勉強していこうかと思います。

  • 品質
  • 数学
  • インフラ

この3つを中心にいろいろやっていこうかと思います。

品質、数学

「数学を勉強することで作るものの品質があがる」っと思ったので数学を勉強しようかと思います。 また品質についてもより質の高いアウトプットをしたいので考え方や品質に対するアプローチの仕方、技法とかを勉強していきたいと思います。 具体的には下記のものを勉強していこうかと思います。

  • 品質工学
  • テスト
  • 設計
  • 数理論理学
  • 離散数学、集合
  • 形式手法
  • モデル検査

形式手法とかモデル検査で数理論理学が出てきたりするので、ここら辺を重点的にやっていこうと思います。 テストについてはざっくりですが、JSTQBとかテスト関係の書籍読んだりとか、方向性は決まっていないですが手広く勉強していくつもりです。

インフラ

インフラを勉強するにあたって下記のことを意識しながら勉強していこうかと思います。

  • 可用性
  • 性能・拡張性
  • 運用・保守性
  • 移行性
  • セキュリティ

インフラやってるなら、セキュリティも意識しておきたいですし、可用性、性能などはサービスの品質に関係してくるところなのでここら辺を重点的にやっていこうかと思います。 可用性とか拡張性についてはk8sを中心にやっていこうかと思います。GKEとかCI/CD周りもやっていきたいですね。あとはAWSGCPもやっていこうかと思います。 セキュリティでは基礎的な部分ももう一度勉強しなおしたいですし、Vaultとか、コンテナのセキュリティ周りも勉強していこうかと思います。

具体的な行動

まだざっくりとしか決まっていませんが、上記の内容を具体的にどうやって進めていくかですが、「インプット」と「アウトプット」に分けて進めていきます。

インプット

月に「品質」「数学」「インフラ」関係の本を1冊ずつ読む

それぞれの本を一冊以上 (合計三冊以上) は読んでいこうと思います。

品質についてはまずは品質工学の基礎的なものから読んでいき、テスト関係の本や設計関係の本を読んでいきたいと思います。

数学はその時に必要と思った知識(上記に記載しているものに関係する)の本を読んでいきます。とりあえずは離散数学とか集合とかからやっていきます。

インフラ関係はその都度その都度決めていきます(雑)

技術系のブログやニュースのチェック(毎日)

今も行っていますが、技術系のブログやニュースをチェックしていきます。これは定常的にやっていこうかと思います。 特にインフラ関係の記事を中心にみていこうかと思います。

アウトプット

ブログを一ヵ月で10本以上書く

勉強したことをブログに書いていきます。10本って割と多い気がしますが(今までほとんど書いてなかった)、、、勉強したことをそのままブログに書くっという感じでやっていこうかと思います。 なのでアウトプットができればちゃんとインプットができてる証拠だと思うのでブログは多めに書いていきたいと思います。

もしかしたら途中で下方修正するかもしれないですが、、、できるだけないように頑張ります。

プログラムを書く(不定期)

数学を勉強してるとプログラムと結び付けて考えたほうがより分かりやすかったりもするので、実際にプログラムを書いていこうかと思います。 言語はHaskellで。理由はなんとなく。 っというかHaskellはいつか勉強しておきたいと思っていたのでこの機会にやっておこうかと思います。 あとは形式手法やるのでAlloyとかモデル検査だとSPINとかあるのでそこもプログラム書いて理解していこうかと思います。

書いたコードはブログに書いたり、Qiitaに書いたりしようかな。

終わりに

今年一年いろんな方にお世話になりました。ありがとうございました。 いっちょ前にいろいろと書きましたが、あまり気張らず、気負いせず、来年も楽しくいろいろとやっていこうかと思います。

VaultのメトリクスをPrometheusで可視化する

目次

  1. 初めに
  2. 環境情報
  3. Vaultでの設定
  4. Prometheusの設定
  5. 終わりに

1. 初めに

今回は小ネタとしてVaultのメトリクスをPrometheusで可視化するために設定した内容を記載していきたいと思います。 VaultとPrometheusの説明はここではしませんので気になる方は下記サイトを参考にしてくださいな。

knowledge.sakura.ad.jp

dev.classmethod.jp

2. 環境情報

  • Vault : 1.3.0
  • Golang: 1.13.5
  • Prometheus: 2.15.1

3. Vaultでの設定

まずは対象となるVaultの設定をしていきます。Vaultではもともとメトリクスを取得するようなAPIが用意されており、HTTPリクエストで取得することができます。

$ curl --header "X-Vault-Token: s.F8NdXgXa4AJLLYcq9Mc19ez6" http://192.168.33.161:8200/v1/sys/metrics
{"Timestamp":"2019-12-29 06:29:00 +0000 UTC","Gauges":[{"Name":"vault.expire.num_leases","Value":0,"Labels":{}},
・・・

このように curl で取得することが可能になります。今回Vaultは 192.168.33.161 のサーバで起動し 8200 のポートで待ち受けています。

ちなみに、VaultのHTTP APIへのリクエストにはTokenが必要になり、ヘッダーに追加しないといけません。

--header "X-Vault-Token: s.F8NdXgXa4AJLLYcq9Mc19ez6" これがTokenの指定になります。

またVaultではPrometheusからメトリクスを取得するためPrometheus用のformatも用意されており、 format=prometheus をパラメータとしてつけてあげるとPrometheus用のフォーマットで取得することができます。

試しに取得してみたいと思います。

$ curl --header "X-Vault-Token: s.F8NdXgXa4AJLLYcq9Mc19ez6" http://192.168.33.161:8200/v1/sys/metrics?format=prometheus
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 6.678e-06
go_gc_duration_seconds{quantile="0.25"} 7.358e-06
go_gc_duration_seconds{quantile="0.5"} 8.21e-06
go_gc_duration_seconds{quantile="0.75"} 1.6864e-05
・・・

またVaultではPrometheus以外でもメトリクス監視をすることができます。下記のドキュメントに記載されていますので、気になる方は見てみてください。

www.vaultproject.io

では、ここからVaultの設定をしていきたいと思います。

設定としてはconfigに telemetry を追加し、Prometheus用の設定を入れてあげます。

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

telemetry {
  prometheus_retention_time = "30s",
  disable_hostname = true
}

listener には外部からリクエストを受け付けられるよう設定を入れておきましょう。

prometheus_retention_time を入れてあげれば設定完了です。非常に簡単ですね。

先ほどの HTTP APIformat=prometheus のパラメータはprometheus_retention_time を入れてあげることで使えるようになります。 prometheus_retention_time が設定されてない場合は、 format=prometheus は使うことができません。

4. Prometheusの設定

では次にPrometheusの設定をしていきます。Prometheus側では監視対象としてVaultの設定を入れてあげれば完了となります。下記が設定内容になります。

scrape_configs:
・・・
  - job_name: 'vault'
    metrics_path: /v1/sys/metrics
    params:
      format: ['prometheus']
    bearer_token: s.F8NdXgXa4AJLLYcq9Mc19ez6
    static_configs:
      - targets: ['192.168.33.161:8200']
・・・

こちらも非常にシンプルですね。

targets の部分に監視対象のVaultのIPとポートを指定してあげます。 metrics_path にはパスを指定してあげ、params にPrometheusのフォーマットでリクエストするよう設定を入れてあげます。 bearer_token にはメトリクスを取得するリクエストを許可しているTokenを設定します。 これで一通り準備が完了しました。

実際にPrometheusの画面で見てみましょう。

f:id:bakotako:20191229154229p:plain

項目にVaultのメトリクスが表示されていますね。 これで設定が完了となります。

5. 終わりに

PrometheusでVaultのメトリクスが見れるようになりました。正直ここから何を監視するのか決めおらず、ただただ「監視したい !!」っという思いで設定しました。 試しでやってみただけなので何を監視して、どうなったらアラートを飛ばすのかは全然決めていませんので、もし「こういうの監視したほうがいいのでは」っというご意見があればコメントしていただけると幸いです。

なんとなくですけとHA構成を組んだ時はそこら辺を見ておくのがいいかなぁっとは思っていますけど、、、そこらへんもおいおい設定していきたいと思います。

またVaultのメトリクス一覧がドキュメントに記載されていますので、気になる方は見てみてくださいな。

www.vaultproject.io

Cloud KMSをVaultで使ってみる

目次

  1. 初めに
  2. 動作環境
  3. 環境の事前準備
  4. Cloud KMSとService Accountの作成
  5. Vaultに設定を入れていく
  6. 終わりに

1. 初めに

Vaultではマスターキーを生成するためにShared Keyを利用していますが、Shared KeyはVaultを初期化したときに出力され、その情報を保存しておかないといけません。またVault Serverを起動しなおすたびにそのShared Keyを入力しないといけないので手間になってしまいます。

そのためShared Keyの代わりにCloud KMSを利用することでその手間を省く仕組みがありますので、今回はそれを試したいと思います。

2. 動作環境

3. 環境の事前準備

まずはStorage Backendの設定からしていきます。以前Storage BackendをGCPに設定したことがあるのでそのまま使ってみたいと思います。Storageの設定は下記記事に記載していますが、実施したコマンドだけここに乗せておきます。

kobatako.hatenablog.com

$ gsutil mb gs://kobaru-vault-sample-bucket
Creating gs://kobaru-vault-sample-bucket/...
$ gcloud iam service-accounts create vaultstorage
$ gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member="serviceAccount:vaultstorage@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" --role="roles/storage.objectAdmin"
$ gcloud iam service-accounts keys create vaultstorage-key.json --iam-account=vaultstorage@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com

Storage Backendの設定が完了したので次はCloud KMSの設定をしていこうと思います。

4. Cloud KMSとService Accountの作成

Cloud KMSでは最初にキーリングと鍵を作成していきます。

$ gcloud kms keyrings create vault-ring --location asia-northeast1
$ gcloud kms keys create vault-key --location asia-northeast1 --keyring vault-ring --purpose encryption

--purpose はどのような鍵を生成するかを指定するオプションで、Vaultでは対象暗号化の鍵を利用するので encryption を指定し対象暗号化の鍵を作成します。

次にService Accountを作成していきます。

$ gcloud iam service-accounts create vaultkey
Created service account [vaultkey].

Cloud KMSへのアクセスするためのRoleを作成します。ドキュメントにCloud KMSを利用するための最低限の権限が乗っているのでそれを参考に作成します。

$ gcloud iam roles create vaultKey --permissions="cloudkms.cryptoKeyVersions.useToEncrypt,cloudkms.cryptoKeyVersions.use
ToDecrypt,cloudkms.cryptoKeys.get" --project=${GOOGLE_CLOUD_PROJECT}
Created role [vaultKey].
etag: BwWaumyuAiI=
includedPermissions:
- cloudkms.cryptoKeyVersions.useToDecrypt
- cloudkms.cryptoKeyVersions.useToEncrypt
- cloudkms.cryptoKeys.get
name: projects/sample-project/roles/vaultKey
stage: ALPHA
title: vaultKey

ちなみに下記がRoleに割り当てた権限になります。

  • cloudkms.cryptoKeyVersions.useToEncrypt : 対象暗号鍵を使って暗号化する
  • cloudkms.cryptoKeyVersions.useToDecrypt: 対象暗号鍵を使って復号する
  • cloudkms.cryptoKeys.get: 暗号鍵を取得する

作成したRoleをService Accountに割り当てたいと思います。

$ gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member="serviceAccount:vaultkey@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" --role="projects/${GOOGLE_CLOUD_PROJECT}/roles/vaultKey"

Roleまで割り当てることができたので次にvaultkey Service Accountのクレデンシャルを取得します。

$ gcloud iam service-accounts keys create vaultkey-key.json --iam-account=vaultkey@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com

作成が完了しました。これで一通りGCP上での作業は終了になります。 次にVaultの設定をしていきます。

5. Vaultに設定を入れていく

まずはVaultのconfig設定に seal を追加します。

seal "gcpckms" {
  credentials = "/home/hogehoge/credentials/vaultkey-key.json"
  project     = "sample-project"
  region      = "asia-northeast1"
  key_ring    = "vault-ring"
  crypto_key  = "vault-key"
}

credentials にはService Accountの鍵のJSONファイルのパスを指定してあげます。

project にはキーリングを作成したプロジェクトを指定します。

region にもキーリングを作成したリージョンを指定します。

key_ringcrypto_key には先ほど作成したキーリングと鍵の名前を入れます。

設定は異常になりますので起動させてみます。

$ vault server -config=config/config.hcl
==> Vault server configuration:

      GCP KMS Crypto Key: vault-key
        GCP KMS Key Ring: vault-ring
         GCP KMS Project: sample-project
          GCP KMS Region: asia-northeast1
               Seal Type: gcpckms
                     Cgo: disabled
              Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
               Log Level: info
                   Mlock: supported: true, enabled: false
           Recovery Mode: false
                 Storage: gcs (HA disabled)
                 Version: Vault v1.3.0
             Version Sha: 4083c36aa0630faafb7c04be62c4940299880bc9+CHANGES

==> Vault server started! Log data will stream in below:

2019-12-28T03:17:51.591Z [INFO]  proxy environment: http_proxy= https_proxy= no_proxy=
2019-12-28T03:17:52.513Z [WARN]  no `api_addr` value specified in config or in VAULT_API_ADDR; falling back to detection if possible, but this value should be manually set
2019-12-28T03:17:52.817Z [INFO]  core: stored unseal keys supported, attempting fetch
2019-12-28T03:17:53.129Z [WARN]  failed to unseal core: error="stored unseal keys are supported, but none were found"

起動できましたね。ちなみに failed to unseal core: error="stored unseal keys are supported, but none were found" っと出てますが失敗してるわけではありません。WARNですし。

後で vault operator init をすれば問題なく消えるのでご安心を。自分はこれが出まくって焦ってました。。。

では別ターミナルを立ち上げてVaultの初期化処理をします。

$ export VAULT_ADDR='http://127.0.0.1:8200'
$ vault operator init
Recovery Key 1: r7CoxTUKzGkSbRGIl7aKiFdfk72o4CKlYejLK9b2qr6W
Recovery Key 2: WtzJLIkHvSgsMlZ3u3aOBvuhtd9SEXJYVd5m4VcqVaTN
Recovery Key 3: AppF9fDFocx9/oCq0U9f/CEmxCcwDXWc+WDsO22qO5si
Recovery Key 4: 2sTgtPhtq1940WHQDKGnVQz//5xEQcd1UnBjeHF/jMC/
Recovery Key 5: eoWxLfMYQhF7IKmf4/4VaEFCN7exRUDzm65rL+Q5N69k

Initial Root Token: s.F8NdXgXa4AJLLYcq9Mc19ez6

Success! Vault is initialized

Recovery key initialized with 5 key shares and a key threshold of 3. Please
securely distribute the key shares printed above.

Root Tokenを使ってログインをします。

$ vault login s.F8NdXgXa4AJLLYcq9Mc19ez6
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                s.F8NdXgXa4AJLLYcq9Mc19ez6
token_accessor       cHwLgO59RteazOjNhxG0TZLn
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]

無事にログインできましたね。Cloud KMSを使わずに起動させた場合は Unseal Keyを入力する必要があったのですが、Cloud KMSを利用することでその手間が省けるようになりました。

6. 終わりに

今回はCloud KMSの設定をしていきました。設定としては非常に簡単ですしk8s上でVaultを動かすときなどはCloud KMSを使うことで非常に使い勝手がよくなるので今回やってみようと思いました。 いつかk8s上でVaultを動かしたいので機会があればやってみたいと思います。

VaultのStorage BackendにGCSを使ってみる

目次

  1. 初めに
  2. 動作環境
  3. VaultのStorage Backend
  4. GCSを使ってみる
  5. 終わりに

1. 初めに

VaultにはStorage Backendっというものがあります。今回はそのStorage BackendにGCSを利用してみたいと思います。 下記がVaultのStorage Backendのドキュメントになりますので、より詳しく知りたい方はドキュメントを見てみてください。

www.vaultproject.io

www.vaultproject.io

2. 動作環境

3. VaultのStorage Backend

まずはVaultのStorage Backendについてですが、簡単に説明するとSecretなどの情報を保存しておく場所になります。 仮にdev modeで起動したときのStorage Backendはin memoryとなります。こうしたデータの保存場所をVaultでは指定することができ、例えばファイル、S3、ConsulやEtcdにも保存することができます。

保存されたデータは暗号化してあるので直接データを見に行っても中を見ることができない状態になっています。

4. GCSを使ってみる

早速GCSを使ってみようと思います。GCSを使うにあたって一般的にはGCSを使えるよう権限を与える必要があります。 ですので権限周りについて詳しく見ていきましょう。

GCSバケットの作成

まずは保存先となるGCSのバケットを作成していきます。

$ gsutil mb gs://my-storage-bucket

これだけで作成完了です。

GCSをStorage Backendとして扱うにはVaultからGCSに対してアクセスできる権限がないといけないので専用のService Accountを作成したいと思います。

Service Accountの作成

GCSにアクセスするためService AccountにはGCSへのアクセス権限を割り当てる必要があります。

アクセス権限はVaultのドキュメントに書いてある通り、 roles/storage.objectAdmin のロールを割り当ててあげれば大丈夫でしょう。

今回は vaultstorage っという名前でService Accountを作成します。

$ gcloud iam service-accounts create vaultstorage

ロールの割り当て

$ gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member="serviceAccount:vaultstorage@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com" --role="roles/storage.objectAdmin"

作成が終わったら次は作成したService Accountの鍵を作成していきます。

$ gcloud iam service-accounts keys create vaultstorage-key.json --iam-account=vaultstorage@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com

次に作成した鍵のパスをGOOGLE_APPLICATION_CREDENTIALS環境変数に保存しましょう。

export GOOGLE_APPLICATION_CREDENTIALS=/home/hogehoge/vaultstorage-key.json

これで準備が完了しました。次にVaultを起動していきます。

Vaultの起動

Vaultの起動する際にGCSをStorage Backendとして使うようconfigに記載していきます。

storage "gcs" {
  bucket = "my-storage-bucket"
}

・・・

storagegcs としていしてあげます。bucketは先ほど作成したバケット名を入れてあげます。 configの設定はこれだけあれば十分ですので実際に起動させてみたいと思います。

$ vault server -config=config/config.hcl
==> Vault server configuration:

                     Cgo: disabled
              Listener 1: tcp (addr: "127.0.0.1:8200", cluster address: "127.0.0.1:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
               Log Level: info
                   Mlock: supported: true, enabled: false
           Recovery Mode: false
                 Storage: gcs (HA disabled)
                 Version: Vault v1.3.0
             Version Sha: 4083c36aa0630faafb7c04be62c4940299880bc9+CHANGES

==> Vault server started! Log data will stream in below:

Vaultの初期化処理

起動が完了したら別のターミナルを立ち上げてvault CLIで操作していきましょう。 ただ、CLIで操作する前にVAULT_ADDR環境変数にVault Serverのエンドポイントを指定してあげる必要があります。

$ export VAULT_ADDR=http://127.0.0.1:8200

では初期化処理です。ここでVault Serverは起動したばかりでSealed状態になっているのでUnsealにしていきます。

$ vault operator init
Unseal Key 1: UK7ktKGdZldIjiwZtVYVDKIl8GeZaeKS+joCjBc5eaYJ
Unseal Key 2: auZJoO8HRUYYQ553BY8aecyA2UjrO1X/jY3eeF8aiDFx
Unseal Key 3: LvN54zcqTctERCEnKvX7xPbpous9QraLu5453WRE59NH
Unseal Key 4: uAQb//JNOMvwXhrtDAK9Kvxz02+yIbiMBxanPrxdorRG
Unseal Key 5: yjItUqqRvn1wrUmqbFmRdjP8xP6CUGzgf/2YHdkaAvRd

Initial Root Token: s.MAXpmLCdMGUBqWGMyyAU4DSF

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.
$ vault operator unseal
Unseal Key (will be hidden):
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    1/3
Unseal Nonce       ea5a56b5-5044-3f6a-d7a2-af25bc0ac7f3
Version            1.3.0
HA Enabled         false

$ vault operator unseal
Unseal Key (will be hidden):
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    2/3
Unseal Nonce       ea5a56b5-5044-3f6a-d7a2-af25bc0ac7f3
Version            1.3.0
HA Enabled         false

$ vault operator unseal
Unseal Key (will be hidden):
Key             Value
---             -----
Seal Type       shamir
Initialized     true
Sealed          false
Total Shares    5
Threshold       3
Version         1.3.0
Cluster Name    vault-cluster-4769ee3e
Cluster ID      a5994982-e32d-459e-bf27-d5f4eaec10bc
HA Enabled      false

初期化処理もすべて完了しました。 ここで一度バケットの中を見てみて実際にデータが入っているか見てみましょう。

$ gsutil ls gs://my-storage-bucket/
gs://my-storage-bucket/core/
gs://my-storage-bucket/logical/
gs://my-storage-bucket/sys/

実際に値が入っていますね。 ちなみに中のデータはちゃんと暗号化されていました。

ではここでVault CLIでVault Serverにログインしてみましょう。

# root tokenを指定
$ export VAULT_TOKEN= s.MAXpmLCdMGUBqWGMyyAU4DSF
$ vault login ${VAULT_TOKEN}
WARNING! The VAULT_TOKEN environment variable is set! This takes precedence
over the value set by this command. To use the value set by this command,
unset the VAULT_TOKEN environment variable or set it to the token displayed
below.

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                s.MAXpmLCdMGUBqWGMyyAU4DSF
token_accessor       EHkhj5RZZyo9qlg6xcKrPV5A
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]

ログインまで完了した。 試しにKV Secrets Engineを許可し、値を入れてみてみましょう。

$ vault secrets enable -path=kv kv
Success! Enabled the kv secrets engine at: kv/
$ vault write kv/hello foo=bar
Success! Data written to: kv/hello

$ vault read kv/hello
Key                 Value
---                 -----
refresh_interval    768h
foo                 bar

値も無事に入っているのが確認できました。ではここでVault Serverを停止させ、もう一度保存したデータが取得できるか確認してみましょう。 一度Vault Serverは起動しなおした時はSealed状態で立ち上がっているのでもう一度Unsealにする必要があります。

初期化処理をした時と同様 vault operator unseal コマンドでUnseal処理をした後は今まで通りコマンドからVaultを操作することができます。

停止する前に入れたデータが残っているか確認してみましょう。

$ vault read kv/hello
Key                 Value
---                 -----
refresh_interval    768h
foo                 bar

無事にデータが残っていることが確認でき、閲覧するところまで確認できました。

5. 終わりに

Storage BackendにGCSを使ってみました。実際にデータが保存されるところまで確認でき再起動後もデータが残っていることまで確認でました。GCSの中のデータ自体は暗号化されているので直接Secret情報が見られることがないので安心ですね。

ただ、このままですと中の情報は見られることはないですが、GCSのデータ自体は削除や直接追加などできてしまうので、 実運用するときはVault Serverだけバケットにアクセスできるような制限なども必要かもしれないですね。

S3や別のストレージにも保存するやり方があるので機会があるときにそちらも試してみたいと思います。

Vault を Deployしてみる

目次

  1. 初めに
  2. 動作環境
  3. Deploy用の設定
  4. Vaultの初期化
  5. 終わりに

1. 初めに

今までVaultを dev modeで動作させていろいろとしてきました。今回はVaultを実際に運用することを見据えた環境設定をしていこうと思います。 また今回もHashiCorp Learnを参考に進めていきます。

Deploy Vault | Vault - HashiCorp Learn

2. 動作環境

3. Deploy用の設定

まずはどんなことよりもVaultをDeployする必要がありますね。そしてDeployするにあたってVaultの起動設定が必要になってきます。 下記がVaultの起動設定になります。

storage "consul" {
  address = "127.0.0.1:8500"
  path    = "vault/"
}

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

この設定項目だけでVaultは起動します。

storage は Vaultで利用するbackendを指定します。backendは暗号化されたストレージ部分になります。ちなみにdev modeの場合はインメモリで動作してたため、停止して再度起動させたらSecret情報などがすべて消えてしまいます。

listener はVaultでAPI Requestをリッスンする設定になります。

HashiCorp LearnではstorageをConsulを使っているのでConsulを動かしてみたいと思います。

$ consul agent -dev

次にVaultを実行してみたいと思います。上記の設定を config.hcl ファイルに記述し実行してみます。

$ vault server -config=config/config.hcl
==> Vault server configuration:

             Api Address: http://127.0.0.1:8200
                     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", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
               Log Level: info
                   Mlock: supported: true, enabled: false
           Recovery Mode: false
                 Storage: consul (HA available)
                 Version: Vault v1.3.0
             Version Sha: 4083c36aa0630faafb7c04be62c4940299880bc9+CHANGES

==> Vault server started! Log data will stream in below:

ただ、実際に実行してみると下記のようなエラーができました。

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
file.

今回実行してるのがroot権限がないため、mlockを呼べない状態でした。 ですのでconfigに下記の設定を追加しました。

disable_mlock=true

詳しい説明は下記のドキュメントに記載されています。

Server Configuration - Vault by HashiCorp

4. Vaultの初期化

次にVaultの初期化処理を行います。初期化処理はconfigで指定したbackendに対してVaultが初めて実行したときに行う処理になります。 初期化処理で暗号化キーとunseal キーを作成し、Root Tokenの作成を行います。

初期化処理は vault operator init コマンドで実行できます。

$ vault operator init
Unseal Key 1: fVKpSklNiVPwRjhVE+WnVRJuO8FYWfYaecOJ5eOQg0Zy
Unseal Key 2: 4W9KvNuDFoz/icFfEYuT1GbklpiFq11AHxspNYIi+07X
Unseal Key 3: Fy0URxcq4fHsJbShgOu0JkBNP0BkLX7sg++iaW35O1RP
Unseal Key 4: amZCQR3PPQIcmkd6GkgqEhdplkHaO/CxK0rwMLq1W+gt
Unseal Key 5: zjn7oOGYi9fsKoGqt5dwj1PhENtYRfVXflQJf/2BBPvn

Initial Root Token: s.Vjlc2B2UGFvd7c3Wjc87ZQmF

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.

出力内容で重要となるのは Unseal Key の一覧と Root Token になりますので、メモを取っておきましょう。 初期化した後のVaultは Sealed 状態となっています。これはSecretなどの情報をBackendから取り出した時に復号できない状態になっています。 ではどうやって復号する方法を手に入れるかというと、マスターキーを作成する必要があります。

Vaultはデータを暗号化するため、暗号化キーを利用します。そしてその暗号化キーを読み取るためにマスターキーを利用する構成になっています。

ではマスターキーを作成するにはどうすればいいか、それは vault operator unseal コマンドを実行し初期化処理のときに出力された Unseal Keyを3つ利用します。3つ利用するということで vault operator unseal コマンドを3回実行すれば完了となります。

まずは1回目実行してみます。

$ vault operator unseal
Unseal Key (will be hidden):
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    1/3
Unseal Nonce       0edf2205-083e-b4fd-fd71-69db2ddb779f
Version            1.3.0
HA Enabled         true

2回目

$ vault operator unseal
Unseal Key (will be hidden):
Key                Value
---                -----
Seal Type          shamir
Initialized        true
Sealed             true
Total Shares       5
Threshold          3
Unseal Progress    2/3
Unseal Nonce       0edf2205-083e-b4fd-fd71-69db2ddb779f
Version            1.3.0
HA Enabled         true

最後に3回目

$ vault operator unseal
Unseal Key (will be hidden):
Key                    Value
---                    -----
Seal Type              shamir
Initialized            true
Sealed                 false
Total Shares           5
Threshold              3
Version                1.3.0
Cluster Name           vault-cluster-99ad46ab
Cluster ID             af61b226-4599-8e7e-2272-0d332b88f058
HA Enabled             true
HA Cluster             n/a
HA Mode                standby
Active Node Address    <none>

Sealedfalse になったら準備完了になります。

では、Root Tokenでログインしてみます。

$ vault login s.Vjlc2B2UGFvd7c3Wjc87ZQmF
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                s.Vjlc2B2UGFvd7c3Wjc87ZQmF
token_accessor       nF4cBXxkvNWDRmO4YDTQjQct
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]

ログインが完了しました。

また、unseal状態となりましたが seal状態に戻すこともできます。

$ vault operator seal
Success! Vault is sealed.

5. 終わりに

実際に本番で扱うような感じでVaultを動かしてみました。鍵を使っての暗号化、復号化についてはAWS のKMSやGCPのKMSを使ってもできるそうなので実際に運用するとなるとクラウドサービスを使ったほうがいいかと思います。これもどこかのタイミングで試してみて記事にしたいと思います。

VaultのPolicyに入門する

目次

  1. 初めに
  2. 動作環境
  3. Policyの追加
  4. 終わりに

1. 初めに

今回はPolicyについて書いていきたいと思います。 今回もHashiCorp Learnにそって進め、その都度調べたことなどを書いていきます。

learn.hashicorp.com

2. 動作環境

3. Policyとは

まずはPolicyについて説明したいと思います。Policyはログインしたアカウントに対してアクセス制限をかけるものになります。

アクセス制限は読み込み、書き込み制限などを行うことができSecretのパスごとに制限をかけることができます。

下記がPolicyのフォーマットになります。

path "secret/*" {
  capabilities = ["create"]
}
path "secret/foo" {
  capabilities = ["read"]
}

path "secret/data/*" {
  capabilities = ["create"]
}
path "secret/data/foo" {
  capabilities = ["read"]
}

このPolicyは secret/ 配下にSecretの書き込みはできますが、secret/foo に対しては読み込みしかできません。

Policyはデフォルトで拒否の設定となるため指定されてないパスに対してはアクセスができないようになっています。

また、capabilities には下記のものが指定できます。

  • create
  • read
  • update
  • delete
  • list

ざっくりではありますがPolicyについて説明しましたので次は実際にPolicyを使ってアクセス制限をしていきたいと思います。

4. Policyの追加

では実際にPolicyを追加したいと思います。下記のコマンドで追加することができます。

$ vault policy write my-policy my-policy.hcl
Success! Uploaded policy: my-policy

無事にPolicyを追加することができました。Policyは下記のコマンドで確認することができます。

$ vault policy list
default
my-policy
test
root

また、Policyの情報は read コマンドで確認することができます。

$ vault policy read my-policy
path "secret/*" {
  capabilities = ["create"]
}

path "secret/foo" {
  capabilities = ["read"]
}

path "secret/data/*" {
  capabilities = ["create"]
}

path "secret/data/foo" {
  capabilities = ["read"]
}

PolicyはTokenに割り当てることでそのTokenでログインしたアカウントに対してPolicyでのアクセス制限をすることができます。 では早速、新規にTokenを作成しPolicyを割り当ててみたいと思います。

$ vault token create -policy=my-policy
Key                  Value
---                  -----
token                s.78IsL4osG8n7wslFIOu5stAS
token_accessor       CIshIIuaE2xLedKkHopdG3b6
token_duration       768h
token_renewable      true
token_policies       ["default" "my-policy"]
identity_policies    []
policies             ["default" "my-policy"]

$ vault login  s.78IsL4osG8n7wslFIOu5stAS
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                s.78IsL4osG8n7wslFIOu5stAS
token_accessor       CIshIIuaE2xLedKkHopdG3b6
token_duration       767h59m37s
token_renewable      true
token_policies       ["default" "my-policy"]
identity_policies    []
policies             ["default" "my-policy"]

作成し、ログインすることまでできましたのでPolicyのアクセス制限がされているか確認してみます。

$ vault kv put secret/bar robot=beepboop
Key              Value
---              -----
created_time     2019-12-24T12:44:02.999777645Z
deletion_time    n/a
destroyed        false
version          1

$ vault kv put secret/foo robot=beepboop
Error writing data to secret/data/foo: Error making API request.

URL: PUT http://127.0.0.1:8200/v1/secret/data/foo
Code: 403. Errors:

* 1 error occurred:
        * permission denied

Policy通り、 secret/foo への追加は権限でエラーとなりました。 想定通りの動きとなりますね。

ちなみに、作成したPolicyを既存のRoleなどに適用することもできます。

$ vault write auth/gcp/role/gcp-role policies=my-policy
$ vault read auth/gcp/role/gcp-role
Key                        Value
---                        -----
add_group_aliases          false
allow_gce_inference        true
bound_projects             [sandbox-262701]
bound_service_accounts     [user01@sample-project.iam.gserviceaccount.com]
max_jwt_exp                900
policies                   [my-policy]
token_bound_cidrs          []
token_explicit_max_ttl     0s
token_max_ttl              0s
token_no_default_policy    false
token_num_uses             0
token_period               0s
token_policies             [my-policy]
token_ttl                  0s
token_type                 default
type                       iam

4. 終わりに

簡単ではありますが、Policyを作成し実際のアクセス制限についてみてみました。 アクセス制限をすることでread onlyのアカウントを作成したり、特定の環境にだけSecretを作成できるようにしたりすることができます。

Policyもまだパラメータの設定などを細かく指定することができるみたいなので、機会があるときにやってみたいと思います。

Vault の認証について入門してみる

目次

  1. 初めに
  2. 環境情報
  3. Vault Authenticationとは
  4. Tokenでの認証
  5. GCPで認証
  6. 終わりに

1. 初めに

これまで Secretについて触れてきました。今回はVaultのAuthenticationについてやっていこうと思います。 ちなみに下記のものがSecretの記事になるので合わせてどうぞ。

kobatako.hatenablog.com

kobatako.hatenablog.com

今回もHashiCorp Learnの内容にそって進めていき、調べた内容などを備忘録として残していきます。

Authentication | Vault - HashiCorp Learn

2. 環境情報

3. Vault Authenticationとは

まず、Authenticationとは何なのかについて説明したいと思います。AuthenticationはVaultを利用するために認証する仕組みです。 dev modeで起動したときにRoot TokenをVAULT_DEV_ROOT_TOKEN_ID環境変数として設定しましたが、これはToken認証をするために設定したものです。 Vaultは様々なAuthenticatuonをサポートしており、Token認証以外でもGitHubAWSGCPなどがあります。

Token認証はデフォルトでenableになっており、これはdisabledにすることはできません。必須のものとなります。

4. Tokenでの認証

ざっくりとAuthenticationについて説明したので、Tokenを作って認証をしたいと思います。 コマンドでTokenを作ることができるので早速作ってみましょう。

$ vault token create
Key                  Value
---                  -----
token                s.b52A1xP2YGDWbZ71eE5qkPMw
token_accessor       rQyxtgb35LXZDIryQLCJaG3G
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]

作成が完了しました。Tokenの大事な要素としてTokenは親子関係があります。新規に作成されたTokenはログイン中のアカウント、いわゆるログイン中のTokenの子Tokenとして作成されたことになります。

policiesのところに ["root"] とありますが、これはログイン中のTokenのポリシーになり、子Tokenには同じポリシーが当たるようになっています。 ポリシーとはVaultを構成する要素の一つです。ここでは詳しくは記載しませんが、下記リンクを見てもらえばわかりやすいかと思います。

HashiCorp Vaultのポリシーを使いこなす | Developers.IO

ここで、大事なのが作成された子Tokenは親となるTokenが削除されたときに一緒に削除されてしまいます。なのでTokenを扱うときは親子関係を意識しながら扱うよう気を付けましょう。 補足としてTokenを作成するときに -orphan オプションを指定すれば親をなしの状態でTokenを作成できます。

では先ほど作成したTokenでログインしてみたいと思います。

$ vault login  s.b52A1xP2YGDWbZ71eE5qkPMw
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                s.b52A1xP2YGDWbZ71eE5qkPMw
token_accessor       rQyxtgb35LXZDIryQLCJaG3G
token_duration       ∞
token_renewable      false
token_policies       ["root"]
identity_policies    []
policies             ["root"]

ちなみに lookup サブコマンドでログイン中のToken情報が確認できます。

$ vault token lookup
Key                 Value
---                 -----
accessor            rQyxtgb35LXZDIryQLCJaG3G
creation_time       1577099915
creation_ttl        0s
display_name        token
entity_id           n/a
expire_time         <nil>
explicit_max_ttl    0s
id                  s.b52A1xP2YGDWbZ71eE5qkPMw
issue_time          2019-12-23T11:18:35.458299285Z
meta                <nil>
num_uses            0
orphan              false
path                auth/token/create
policies            [root]
renewable           false
ttl                 0s
type                service

無事にログインすることができました。 次にTokenを削除してみたいと思います。

$ vault token revoke s.b52A1xP2YGDWbZ71eE5qkPMw
Success! Revoked token (if it existed)

これでTokenの削除が完了しました。 ちなみに、Tokenの削除はログインしているTokenでも削除することが可能です。

5. GCPで認証

管理サービスアカウントの作成

Tokenでの認証について記述してきました。ただこれからVaultを運用していくとなると毎回Tokenを作成するのは面倒ですし、管理が煩雑になるかと思います。 ですのでここからはGCPを使って認証をしたいと思います。

GCPで認証を行うには二つの方法があります。IAMでの認証とGCEでの認証とあります。今回はローカル環境でVaultを動かしているのでIAMでの認証をしてみたいと思います。 IAMで認証するために作成するリソースは以下のものになります。

* GCP
  * Service Account
    * 管理用Service Account
    * 認証用Service Account
  * IAM Role
    * 管理用Service AccountのRole
* Vault
  * Policy
  * GCP認証
    * config
    * role

認証用Service AccountはこのService Accountを使ってVaultに対して認証、ログインをします。 管理用Service AccountはログインしてきたSerivce Accountが正しいかどうかをGCPに対してリクエストを送ります。それで問題なければ認証成功となります。

では早速、認証の準備をしていきましょう。 下準備としてGCPで認証をするためにAMI APIアクセスを許可あげないといけません。

$ gcloud services enable iam.googleapis.com

APIアクセスが許可できたら早速GCP上にIAMを作成していきます。

まずは管理用のService Accountを作成していきます。これはVault ServerがGCPに対して

$ gcloud iam service-accounts create vaultadmin
$ gcloud iam service-accounts keys create vaultadmin-key.json --iam-account=vaultadmin@sample-project.iam.gserviceaccount.com

次に管理Service Account用のRoleを作成し、関連付けます。

$ gcloud iam roles create vaultAdmin --permissions="iam.serviceAccounts.get,iam.serviceAccountKeys.get" --project="sample-project"
$ gcloud projects add-iam-policy-binding sample-project --member="serviceAccount:vaultadmin@sample-project.iam.gserviceaccount.com" --role="projects/sample-project/roles/vaultAdmin"

認証用サービスアカウントの作成

では、次は実際に認証で使うService Accountを作っていきましょう

$ gcloud iam service-accounts create user01
gcloud iam service-accounts keys create user01-key.json --iam-account=user01@sample-project.iam.gserviceaccount.com

認証用で利用するService AccountはJWTの署名をすることができる権限が必要になります。ですので iam.serviceAccountTokenCreator をRoleとして指定してあげましょう。

$ gcloud iam service-accounts add-iam-policy-binding user01@sample-project.iam.gserviceaccount.com --member="serviceAccount:user01@sample-project.iam.gserviceaccount.com" --role="roles/iam.serviceAccountTokenCreator"

ここまでで最低限のGCP上での準備ができました。次はVault側の設定を進めていきます。

GCP認証の設定

まずは認証をenableにします

$ vault auth enable gcp
Success! Enabled gcp auth method at: gcp/

次にGCP認証のConfigに管理用Service Accountの認証情報を追加します。

$ vault write auth/gcp/config credentials=@vaultadmin-key.json

ここで認証用のアカウントのPolicyを作り、Roleの追加をします。

$ vault write sys/policy/test policy=-<<EOF 
path "secret/data/test/*" {
  capabilities = ["read"]
}
EOF

$ vault write auth/gcp/role/my-role type="iam" project_id=sample-project policies="test" bound_service_accounts=user01@sample-project.iam.gserviceaccount.com

これで一通り準備が完了しました。

実際に認証してログインしてみましょう。

$ vault login -method=gcp role="gcp-role" credentials=@user01-key.json project="sample-project" service_account="user01@sample-project.iam.gserviceaccount.com"
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                               s.kJSMSVXWsiCsd03hVXuE0lmt
token_accessor                      StawLc2yWqhX47QPhEnuVpzX
token_duration                      768h
token_renewable                     true
token_policies                      ["default" "test"]
identity_policies                   []
policies                            ["default" "test"]
token_meta_project_id               sample-project
token_meta_role                     gcp-role
token_meta_service_account_email    user01@sample-project.iam.gserviceaccount.com
token_meta_service_account_id       115673907101952887930

無事にログインすることができました。

最後に作成したリソースを確認してみましょう。

* GCP
  * Service Account
    * 管理用Service Account: vaultadmin@sample-project.iam.gserviceaccount.com
    * 認証用Service Account: user01@sample-project.iam.gserviceaccount.com
  * IAM Role
    * 管理用Service AccountのRole: vaultAdmin
* Vault
  * Policy: sys/policy/test
  * GCP認証
    * config: auth/gcp/config
    * role: auth/gcp/role/my-role

6. 終わりに

今回は認証を行ってみました。HashiCorp LearnではGitHubで認証をしていたのですが、GCPでの認証に挑戦してみました。途中Service Accountの権限周りでうまく進めることができませんでしたが、最終的にはちゃんとログインするところまで持っていけました。

VaultをKubernetes上でサイドカーとして動かすこともでき、その時にKubernetesで認証することができます。マイクロサービス化が進むことでAPIキーやユーザ/パスワードなどの機密情報をVaultに持たせ、サイドカーとして実装することで機密情報をアプリケーションに持たせることなく実装することができるのでより機密情報をセキュアに管理できるんじゃないかと思います。

認証をKubernetesで行い、Kubernetes上でサイドカーかし動かす実装もいつかやってみようと思います。