0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vault Cluster の構築

Posted at

最近、HashiCorp 社が OSS として提供する Vault を触る機会があったので、忘れない内に、記事としてまとめることにしました。この記事は 'Vault 1.18.3' を使用しました。

Vault とは

たくさんの記事が投稿されていて、改めてまとまるまでも無い感じですが、簡単に何をするソフトなのかを要約します。

Vaultは、シークレットと暗号化の管理システムです。シークレットには、「トークン、APIキー、パスワード、暗号化キー、証明書」など、大切な情報や守り、IT資源へのアクセスをコントロールするための「文字列」です。これらのシークレットは、第三者に流出して悪用されないために、厳重に管理しなければなりません。この管理は、関わる人が多くなると難しくなっていきます。この問題を解決するのが Vault です。

厳重な管理の方法として、Vaultのワークフローには、4つの段階があります。

  • 認証:クライアントが本人であることを認証すると、トークンが生成され、ポリシーに関連づける。認証方法は、パスフレーズなどから選択可能
  • 検証:クライアントを検証するために、Github,LDAPなどと連携してクライアントを検証
  • 承認:Vault内の特定のPathと操作(作成、読み取り、更新など)を許可または禁止
  • アクセス:クライアントのIDと紐も付いたトークンを発行、これを用いて、シークレット、キー、暗号化機能へのアクセスを許可

Vaultは、安全なシークレットストレージ、動的なシークレット、データの暗号化、有効期限と更新、失効などの機能を提供します。

この様な役割を担うVaultは、複数のシステムから認証/認可のために使用されます。そのため、Vaultが、停止すると、システム全体が使用不能に陥る事が懸念されます。そのことから、Vaultはクラスタ化して可用性を高める必要があります。

Vaultのクラスタ構成

Vaultクラスタの構成は、「自動アンシールのためのVaultサーバー」、「Vaultクラスタのメンバーサーバたち」からなります。

image.png

「自動アンシールのためのVaultサーバー」は、どうして必要なのか?、についての説明から始めます。Vaultサーバーの起動するとシール(封印)された状態で起動します。利用者はシール(封印)を解かなければ、Vaultの機能や保存データにアクセスできません。シールを解くためのキーは、Vaultのサーバープロセスのメモリ上だけに保存されています。そのため、Vaultのサーバープロセスを再起動するだけで、封印されてしまい、利用できなくなってしまいます。

封印を解くキーを外部から与える構造は、セキュリティを高めるために役立つのですが、セキュリティが確保されたエリアで運用するには、手間がかかります。Vaultクラスタのメンバーの一つが再起動すると、人手で封印解除のキーをインプットするまでは、クラスタに復帰できません。その問題を解決するために、提供されているのが、自動アンシール(Auto Unseal)の機能です。このVaultサーバーは、予めトークンを持ったサーバーだけに、アンシールのキーを提供します。

Vaultクラスタのメンバーの間では、Raftアルゴリズムによってリーダーが決められます。データの更新は、リーダーだけが担当して、他のメンバーは更新をフォローして同期します。これによって3重化を実現して、可用性を確保します。VaultクラスタのメンバーのVaultサーバーは、起動過程で自動アンシールのサーバーから封印解除のキーを受け取り、自身で封印を解除して、クラスタのメンバーに参加する仕組みです。

Vaultクラスタのメンバーが、自動アンシールのサーバーから封印解除のキーを受け取るためには、起動時に自動アンシールのVaultサーバーが発行したトークンを持っていなければなりません。また、自動アンシールの役割のVaultサーバーは、起動時の自身の封印解除のキーが必要です。

Vaultのビルド済み実行形式のインストール

HashiCorpのWebサイトから、ビルド済みの実行形式をダウンロードします。

curl -OL https://releases.hashicorp.com/vault/1.18.3/vault_1.18.3_linux_amd64.zip

圧縮を解凍して、/usr/local/bin/vaultとして配置します。このコマンド一つで、サーバーとクライアントを兼ねていますので、自動アンシールのサーバー、クラスタメンバーのサーバー、操作用ワークステーションに、それぞれ一つづ配置すればインストールは完了です。

自動アンシールのVaultサーバーの構築

このサーバーは、スタンドアロンのサーバーとして構築します。そして、初期化後、封印を解いた後、rootでログインして、自動アンシールの設定を実施します。

Configファイル

Vaultを起動するためのコンフィグファイルです。このファイルの中で、シークレットストレージを'/var/vault-data'に置いています。起動前に、予めディレクトリを作成する必要があります。

このサーバーのIPアドレスは172.16.0.9なので、api_addr にアドレスをセットします。また、listenerには、ローカルホスト(127.0.0.1)のアクセスを受けられる様に、0.0.0.0をセットします。
TLSの暗号通信のため、認証局証明書(ca.pem)、サーバー証明書(vault-node1.pem)、証明書鍵(vault-node1-key.pem)をセットします。ここでは、証明書の作り方は扱いません。

UIを使用すると、メニュー構造からシステムのアーキテクチャなども伺い知れるので便利ですから、ui = trueにします。

/etc/vault/config.hcl
storage "file" {
   path    = "/var/vault-data"
}

listener "tcp" {
  address               = "0.0.0.0:8200"
  cluster_address       = "0.0.0.0:8201"
  tls_client_ca_file    = "/etc/vault/ca.pem"
  tls_cert_file         = "/etc/vault/vault-node1.pem"
  tls_key_file          = "/etc/vault/vault-node1-key.pem"
}

ui = true
disable_mlock = true
cluster_name  = "vault-cluster"
api_addr      = "https://172.16.0.9:8200"

Systemdのユニットとして起動するためのファイル

次のvault.servie/lib/systemd/systemの下に配置することで、systemctl start vaultで起動できるようになります。ただし、初回起動時は、未初期化、封印(シール)された状態ですから、クライアントからコマンドを叩いて、利用可能な状態にする必要があります。

/lib/systemd/system/vault.service
[Unit]
Description=vault - Manage Secrets & Protect Sensitive Data
Documentation=https://developer.hashicorp.com/vault
After=network.target
Wants=network-online.target

[Service]
Type=notify
User=root
PermissionsStartOnly=true
ExecStart=/usr/local/bin/vault server -config /etc/vault/config.hcl
Restart=on-abnormal
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

封印解除

systemctl start vaultを実行して、起動できるか確認してみます。無事に起動できたら、次へ進みます。もし失敗するようであれば、ターミナルのコマンドラインから vault server -config /etc/vault/config.hcl を実行することで、エラーメッセージをコマンドの応答として確認できます。

Vaultサーバーの初期化と封印解除

Vaultサーバーの起動が完了したら、Vaultクライアントからサーバーを初期化します。'vault server'とすることでサーバーとして、単にvaultとしてコマンドを実行すると、クライアンで起動します。

クライアントが、サーバーに接続するためには、TLS暗号通信、サーバーのアドレスなど、必要な環境変数をセット視します。

export VAULT_SKIP_VERIFY=1
export VAULT_CA_CERT=/etc/vault/ca.pem
export VAULT_CLIENT_CERT=/etc/vault/vault-node1.pem
export VAULT_CLIENT_KEY=/etc/vault/vault-node1-key.pem
export VAULT_ADDR=https://127.0.0.1:8200

環境変数が効いていれば、サーバーの状態を次のコマンドで確認できます。

vault status

Vaultサーバーを初期化します。
実行結果として、封印解除のキー、root トークンなどが表示されますので、大切に保管しておきます。

vault operator init -format=json -key-shares 1 -key-threshold 1

Vaultは封印された状態で起動します。その封印を解除するために、封印解除のキーが必要です。以下のコマンドで、封印を解除します。

vault operator unseal <UNSEAL KEY> 

Auto unsealサーバーの設定

rootでログインすることで、Vaultサーバーのコマンドを受け付ける様になります。

vault login <ROOT TOKEN>

シークレットの転送機能を有効化して、転送キーをセットいます。

vault secrets enable transit
vault write -f transit/keys/autounseal

転送キー対して、ポリシーを設定します。ポリシーには、可能な操作を記載します。

vault policy write autounseal -<<EOF
path "transit/encrypt/autounseal" {
   capabilities = [ "update" ]
}

path "transit/decrypt/autounseal" {
   capabilities = [ "update" ]
}
EOF

自動封印解除対象のサーバーのために、トークンを生成します。
ここで作成したトークンは、厳重に保存します。

vault token create -orphan -policy="autounseal" \
   -wrap-ttl=120 -period=24h \
   -field=wrapping_token > wrapping-token.txt
vault unwrap -field=token $(cat wrapping-token.txt)
rm wrapping-token.txt

以上で、オートアンシールのためのサーバーの設定は完了です。

Vaultクラスタメンバーのサーバー設定

Vaultクラスタを構成するサーバーを、最初に1つだけ起動して、初期化します。

Systemdから起動するためのファイル

systemd から起動するためのファイルを /lib/systemd/systemの下に配置します。
ポイントは、Environment=VAULT_TOKEN='から始まる行で、前述で取得してたhvs.CAESIB*****`から始まるトークンをセットします。

# /lib/systemd/system/vault.service
[Unit]
Description=vault - Manage Secrets & Protect Sensitive Data
Documentation=https://developer.hashicorp.com/vault
After=network.target
Wants=network-online.target

[Service]
Environment=VAULT_TOKEN=hvs.CAESIB******************************************
Type=notify
User=root
PermissionsStartOnly=true
ExecStart=/usr/local/bin/vault server -config /etc/vault/config.hcl
Restart=on-abnormal
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

VaultのConfigファイル

{{ ansible_facts.all_ipv4_addresses[0] }}の部分は、サーバーのIPアドレスで置き換えます。また、{{ ansible_facts.hostname }}はホスト名で置き換えます。

leader_api_addrから始まる行には、それぞれ、VaultクラスタのメンバーとなるIPアドレスをセットします。

起動前に、Vaultが保存するデータのために、/var/vault-dataのディレクトリを作成しておきます。また、/etc/vaultの下に認証局証明書、サーバー証明書、鍵を配置しておきます。

api_addr      = "https://{{ ansible_facts.all_ipv4_addresses[0] }}:8200"
cluster_addr  = "https://{{ ansible_facts.all_ipv4_addresses[0] }}:8201"
cluster_name  = "vault-cluster"
disable_mlock = true
ui            = true

storage "raft" {
   path       = "/var/vault-data"
   node_id    = "{{ ansible_facts.hostname }}"
   retry_join {
      leader_tls_servername   = "vault-cluster"
      leader_api_addr         = "https://172.16.31.11:8200"
      leader_ca_cert_file     = "/etc/vault/ca.pem"
      leader_client_cert_file = "/etc/vault/vault-node1.pem"
      leader_client_key_file  = "/etc/vault/vault-node1-key.pem"
   }
   retry_join {
      leader_tls_servername   = "vault-cluster"
      leader_api_addr         = "https://172.16.31.12:8200"
      leader_ca_cert_file     = "/etc/vault/ca.pem"
      leader_client_cert_file = "/etc/vault/vault-node1.pem"
      leader_client_key_file  = "/etc/vault/vault-node1-key.pem"
   }
   retry_join {
      leader_tls_servername   = "vault-cluster"
      leader_api_addr         = "https://172.16.31.13:8200"
      leader_ca_cert_file     = "/etc/vault/ca.pem"
      leader_client_cert_file = "/etc/vault/vault-node1.pem"
      leader_client_key_file  = "/etc/vault/vault-node1-key.pem"
   }
}

listener "tcp" {
  address               = "0.0.0.0:8200"
  cluster_address       = "0.0.0.0:8201"
  tls_client_ca_file    = "/etc/vault/ca.pem"
  tls_cert_file         = "/etc/vault/vault-node1.pem"
  tls_key_file          = "/etc/vault/vault-node1-key.pem"
}

seal "transit" {
  address             = "https://172.16.0.9:8200"
  disable_renewal     = "false"
  key_name            = "autounseal"
  mount_path          = "transit/"
  tls_cert_file       = "/etc/vault/vault-node1.pem"
  tls_key_file        = "/etc/vault/vault-node1-key.pem"
  tls_client_ca_file  = "/etc/vault/ca.pem"
  tls_skip_verify    = "true"
}

以上の設定が完了したら、systemctl start vault で起動できるか確認しておきます。

クラスタメンバーの初期化

Vaultクライアントのための環境変数をセットしておきます。

export VAULT_SKIP_VERIFY=1
export VAULT_CA_CERT=/etc/vault/ca.pem
export VAULT_CLIENT_CERT=/etc/vault/vault-node1.pem
export VAULT_CLIENT_KEY=/etc/vault/vault-node1-key.pem
export VAULT_ADDR=https://172.16.31.11:8200

Vaultクライアントが、サーバーと接続できるか確認します。

vault status
Key                      Value
---                      -----
Seal Type                transit
Recovery Seal Type       n/a
Initialized              false
Sealed                   true
<以下省略>

サーバーを初期化します。

vault operator init

表示されたキーを大切に保存しておきます。

Recovery Key 1: vzdo7uWa/q2W2K6HZkN+LdzTWs05kRZn3QkjDImK8J6S
Recovery Key 2: 4hQTImabMwOL1+/JeysACP2UY4xqIZ6JX3F3Bghnm4cU
Recovery Key 3: 5TK3LrcsGtmPuXKzAyozwE6TmsCU7DaQ5SroasiSfdWn
Recovery Key 4: VJcHeofUZyftzdtFzkyLLRroVq59pA5zK/Y69ePSKBsb
Recovery Key 5: DMvsZvtxS3OCTCSz5uGZhD4xk7JniApfUP2x6C6Xwt5R

Initial Root Token: hvs.1x3NPGQV8BkfgIzkcCKVsvDG

Success! Vault is initialized

rootでログインして、クラスタ状態を確認します。

クラスタに参加するvaultサーバーにログインするには、前述の初期化で表示されたInitial Root Token:を使います。

vault login <hvs.から始まるトークン>

クラスタのメンバーをリストできます。

$ vault operator raft list-peers
Node     Address              State     Voter
----     -------              -----     -----
node1    172.16.31.11:8201    leader    true

クラスタメンバーの追加

/etc/vault/config.hcl,/var/vault-data などの設定を実施して、systemctl start vaultを実行することで、参加するメンバーが増えていきます。

vault operator members
Host Name    API Address                  Cluster Address              Active Node    Version    Upgrade Version    Redundancy Zone    Last Echo
---------    -----------                  ---------------              -----------    -------    ---------------    ---------------    ---------
node1        https://172.16.31.11:8200    https://172.16.31.11:8201    true           1.18.3     1.18.3             n/a                n/a
node2        https://172.16.31.12:8200    https://172.16.31.12:8201    false          1.18.3     1.18.3             n/a                2025-02-02T12:46:13Z
node3        https://172.16.31.13:8200    https://172.16.31.13:8201    false          1.18.3     1.18.3             n/a                2025-02-02T12:46:16Z

Vault Clusterの構築は以上です。パブリッククラウドでは、自動アンシールのサービスを実施していますので、使用するクラウドのドキュメントを参照ください。

参考資料

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?