ビビリフクロウの足跡

いつもお世話になっているインターネットへの恩返し

Hashicorp Vault 触ってみた

前々からHashicorp製品群には興味がありましたが、試そう、試そうと思うだけで中々本格的に手を出せずにいました。なんというか、Hashicorp製品群を本格的に利用しようという考えにまでならないんですよね。。。

Vagrant知ったときはインフラしかできなかったので、「仮想マシン自分で作ればいいじゃない」となってしまい、Terraformに興味を持ったときはOpenStackやAWSにどっぷりだったので、「CloudFormationやHeatでいいじゃない」となってました。NomadやConsulなんかもありますが、コンテナオーケストレータとサービスメッシュはKubernetesとIstion & Linkerdが押さえている状況なので、これも必要に迫られて、というのは中々なさそう。

その中で最近唯一本格的に触ってみたい、触ってみなければ! と思っているのがVaultです。

なんでVaultかというと、自宅プライベートクラウドを作ろうとしたときに各コンポーネントをコンテナで立てるのは良いのですが、コンテナを実行する基盤自体は仮想マシン、もしくは物理マシンになります。OSレイヤ以下をメンテナンスしなくてはならないので構築、運用負荷がそれなりに高いわけですが、なるべく負荷を下げるためにInfrastructure as Codeを積極的に実践していこうと思っています。そうするとコードに機密情報を与えるにはどうすればよいか。。。となったわけです。

クラウド上であればAWS Secrets ManagerやAWS KMSなどのシークレット管理サービスが存在するのでいいのですが、非クラウド環境においては個別にそれらに対応するソフトウェアを探すか、手動に甘んじるしかありません。そこでクラウドネイティブなシークレット管理ソフトウェアを探して真っ先にたどり着いたのがHashicorp Vaultだったということです。

今回は月並みに「触ってみた」ということで、以下の流れで簡単にCLIでシークレットを取得するまでを見ていきます。

  • サーバ構築 - Seal/Unseal
  • シークレットの登録
  • Policyの設定
  • ユーザの設定
  • ログイン - シークレット取得

サーバ構築

構築と言っても公式でdockerコンテナが用意されているので、基本的にはconfigファイルを作成して、server 引数をつけてコンテナを起動するだけです。しかし、Vaultはただ引数を指定して、サーバを初期化しただけではいきなり使えるようにはなりません。使える状態にするためにはUnsealという作業が必要になります。

Vautlは起動直後(再起動時も含む)またはSeal操作後にSeal状態となります。これはシークレットがどこに保存されているかはわかっているが、暗号化されたシークレットを見る、つまり復号化する手段を知らない状態です。したがって、初期化時に生成された復号化するためのキーを閾値の数まで入力して、復号化に必要なマスターキーをVaultに持たせてやる必要があります。

初期化とUnsealを一括して実行できるpythonスクリプトとセットでリポジトリを作成しましたので、よろしければご利用ください。なお検証のため、APIはhttp通信を前提にしておりますので、検証でのご利用か、必要に応じてhttpsに変更してご利用くださいませ。

ちなみにSeal状態の画面をパシャリ。

f:id:bbrfkr:20200419173228p:plain

シークレットの登録

さて、サーバを起動してUnseal状態になったら、secrets/secrets.yaml に書かれた root_token を使ってログインします。

f:id:bbrfkr:20200419173457p:plain

ログインするとこんな画面になるので、早速Key-Valueなシークレットを作っていきましょう!

f:id:bbrfkr:20200419173606p:plain f:id:bbrfkr:20200419173616p:plain f:id:bbrfkr:20200419173651p:plain f:id:bbrfkr:20200419173734p:plain

適当に test-secrets というシークレット名で password: p@ssw0rd という不届きなKey-Valueを登録してみます。

f:id:bbrfkr:20200419173856p:plain f:id:bbrfkr:20200419173915p:plain

これでOK!

Policyの設定

次にPolicyを作成していきます。VautlにおけるPolicyは今の私の理解だとIAM Policyのようなもので、どのシークレット(厳密にはAPIサーバのURLパス)をCRUDできるのかを決めるものです。Policiesメニューから作っていきましょう。

f:id:bbrfkr:20200419174210p:plain

今回は先程作った test-secrets シークレットを読み込めるだけのポリシー test-policy を作ってみます。

f:id:bbrfkr:20200419174314p:plain f:id:bbrfkr:20200419174327p:plain

はい。

ユーザの設定

PolicyはIAMポリシーのようなものといいました。次はポリシーを割り当てるユーザ、IAMユーザのようなものを作っていきます。Accessメニューから行きましょう。

f:id:bbrfkr:20200419174517p:plain f:id:bbrfkr:20200419174545p:plain f:id:bbrfkr:20200419174607p:plain f:id:bbrfkr:20200419174619p:plain

雑に id = test-user, password = test なユーザを作ります。

f:id:bbrfkr:20200419174728p:plain

Policyとユーザとの紐付けは Generated Token's Policies で行います。

f:id:bbrfkr:20200419174816p:plain f:id:bbrfkr:20200419174832p:plain

できました!

ログイン - シークレット取得

これで準備万端(?)です。CLI経由で用意した test-usertest-secrets の中身を見てみます。まずはログイン。

f:id:bbrfkr:20200419180218p:plain

ログインできたらtokenがVaultから渡されるので、VAULT_TOKEN 環境変数にこれをセットして、kv get コマンドを実行します。

f:id:bbrfkr:20200419180406p:plain

ただ p@ssw0rd が取れただけだけどすごく嬉しい。

ちなみに、-format オプションで出力をjsonにできたりもするので、jq ヘビーユーザも大歓喜ですね!

f:id:bbrfkr:20200419180510p:plain

おわりに

一通りVaultの User & Password での使い方を見てきました。他にもApplicationに組み込む形に最適化された AppRole という認証方式や、Key-Valueだけではなくて PKIシークレットなんかも管理できます。またAWXではサーバへの認証キーをVautl側で管理できたり、KubernetesでもAgent-injectorなんてものがあったりと、シークレット情報をVaultで一元管理するために役立つ公式 & 3rd Partyツールが賑わっているようです! この記事をご覧になって興味が湧いた方はまずは以下のリポジトリで体験いただければ幸いです。