1. はじめに
普段terraformでInfrastructure as codeを実現しています。
ソースコードに触れる機会が増えてから、シークレット情報の取り扱いをより気にするようになってきました。
例えば、シークレット情報はハードコーディングしないという鉄則があるかと思います。
この鉄則に則った時、terraformから実行する際の認証情報をコーディングせずに管理することが難しく感じていました。
そんな中、HashiCorp社のVaultというシークレット管理サービスを見つけました。
特に動的シークレットがとても気になったので具体的に何をしてくれるのか触ってみました。
2. vaultの機能
VaultとはHashiCorp社が開発しているシークレット管理ツールです。
シークレットとは、DBなどのパスワードやAPIキー、証明書、暗号鍵などのことを指します。
Vaultはクライアントサーバーシステム形式で動作します。
主な機能としては以下が挙げられます。
- データ保存前に暗号化してストレージに保存する機能
- AWSやAzureなど一部のシステムに対して動的にシークレットを生成する機能
- シークレットの更新機能
- シークレットの無効化機能
- アクセスポリシーによる権限操作機能
今回はこの中でも動的シークレット生成機能を試していきます。
Azureを使用して検証します。
3. Azure事前準備
Azureで動的シークレットは、サービスプリンシパル自動生成(*)とロール割り当ての自動化が行われます。
そのため以下のロールが必要になります。
- Subscriptionの「所有者」
- Azure ADの「アプリケーションの読み取りと書き込み」
私は今回上記の権限をつけたサービスプリンシパルを作成しました。
今回は検証のためAAD(Azure Active Directory)の権限は強いものをつけています。
後ほど以下の項目を使用するため、環境変数にいれておきます。
ちなみにAzure内のVMでVaultを起動するとclient_idとcilent_secretは不要になります。
- subscription id
- tenant id
- client id
- client secret
export AZURE_SUBSCRIPTION_ID="<subscription_id>"
export AZURE_TENANT_ID="<tenant_id>"
export AZURE_CLIENT_ID="<client_id>"
export AZURE_CLIENT_SECRET="<client_secret>"
(*)既存のサービスプリンシパルのobject_idを指定すると、既存のサービスプリンシパルを使用するよう設定可能ですが、新規作成が推奨されるため、今回は新規作成の方針を採用しています。
4. vaultの環境構築
4.1. vaultのインストール
まずはvaultのインストールです。
以下のどちらかから実施します。
私はmac OS のローカル端末でテストするため、homebrewパターンで実施しました。
OS X homebrew パターン
$ brew install vault
以下サイトから使用端末の環境に合わせダウンロードします。
その後ダウンロードしたファイルを実行します。
https://www.vaultproject.io/downloads
ubuntu OS で実行する場合は以下のコマンドでvaultのインストールが可能です。
# zip fileの取得
wget https://releases.hashicorp.com/vault/1.4.2/vault_1.4.2_linux_amd64.zip
# unzip install
sudo apt install unzip
# unzip
unzip vault_1.4.2_linux_amd64.zip
# mv
sudo mv vault /usr/bin
インストール完了後以下コマンドを入力し、インストールされていることを確認します。
$ vault
# 出力結果
Usage: vault <command> [args]
Common commands:
read Read data and retrieves secrets
write Write data, configuration, and secrets
delete Delete secrets and configuration
list List data or secrets
login Authenticate locally
agent Start a Vault agent
server Start a Vault server
status Print seal and HA status
unwrap Unwrap a wrapped secret
Other commands:
audit Interact with audit devices
auth Interact with auth methods
debug Runs the debug command
kv Interact with Vault`s Key-Value storage
lease Interact with leases
namespace Interact with namespaces
operator Perform operator-specific tasks
path-help Retrieve API help for paths
plugin Interact with Vault plugins and catalog
policy Interact with policies
print Prints runtime configurations
secrets Interact with secrets engines
ssh Initiate an SSH session
token Interact with token
チュートリアルを見ていたら、コマンドライン補完ツールのインストールもおすすめしていたので、実行しておきます。(コマンド実行後アウトプット値はありません。)
$ vault -autocomplete-install
4.2. vaultサーバの起動と環境変数設定
vaultサーバを以下コマンドで起動します。
今回はローカル環境にて検証するため開発モードで起動します。
開発モードで起動すると、TLS接続をしないため、通信が暗号化されません。(HTTP接続)
$ vault server -dev
# 出力結果
==> 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: false, enabled: false
Recovery Mode: false
Storage: inmem
Version: Vault v1.4.2
Version Sha: 18f1c494be8b06788c2fdda1a4296eb3c4b174ce
・・・
You may need to set the following environment variable:
$ export VAULT_ADDR='http://127.0.0.1:8200'
The unseal key and root token are displayed below in case you want to
seal/unseal the Vault or re-authenticate.
Unseal Key: uUdiPMxGuSxizoDtwDBUfgEgiP8T76p9alQPMKZMPYg=
Root Token: s.3uMfZKQLaBDwCsVjBbRBhhTH
・・・
サーバ起動時に環境変数の追加をしてくださいと言われているので、環境変数を追加します。
ついでにアクセスするためのトークンも一緒に環境変数にいれておきます(サーバー起動時に出力されたRoot Tokenの値)。
新しいターミナルを開き、以下コマンドを入力します。
$ export VAULT_ADDR='http://127.0.0.1:8200'
$ export VAULT_DEV_ROOT_TOKEN_ID="s.GIDKI5wPSt1NejCiDauwZRls"
念のため、以下コマンドでサーバーが稼働していることを確認します。
$ vault status
Key Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 1
Threshold 1
Version 1.4.2
Cluster Name vault-cluster-344850dc
Cluster ID f196f039-a6cd-7fc3-b025-8401b087d15b
HA Enabled false
4.3. azure用シークレットエンジン設定
サーバが稼働していることを確認できたら、以下コマンドにてログインします。
$ vault login
Azure のシークレットエンジンを有効化します。
$ vault secrets enable azure
# 出力結果
Success! Enabled the azure secrets engine at: azure/
アカウントの認証情報を構成します。
$ vault write azure/config \
subscription_id=$AZURE_SUBSCRIPTION_ID \
tenant_id=$AZURE_TENANT_ID \
client_id=$AZURE_CLIENT_ID \
client_secret=$AZURE_CLIENT_SECRET
# 出力結果
Success! Data written to: azure/config
# 以下コマンドで入力値の確認が可能
$ vault read azure/config
次にロールを構成します。
失効されるまでの期限(TTL)と作成されるサービスプリンシパルのロールとスコープを定義しています。
今回はサービスプリンシパルを"vault-test"というリソースグループに対して共同作成者権限をつけてみます。
$ vault write azure/roles/test-role ttl=1h azure_roles=-<<EOF
[
{
"role_name": "Contributor",
"scope": "/subscriptions/<subscription_id>/resourceGroups/vault-test"
}
]
EOF
# 出力結果
Success! Data written to: azure/roles/test-role
以下コマンドを実行し、サービスプリンシパルを発行します。
$ vault read azure/creds/test-role
# 出力結果
Key Value
--- -----
lease_id azure/creds/test-role/Dnld7c3osL1OWHeGGsdI43gg
lease_duration 1h
lease_renewable true
client_id df537b41-9ad3-4c72-931b-02c0e115746c
client_secret 88ee84e1-0e64-3197-e910-e641adcd5672
Azure Portalを見てみると以下のようにサービスプリンシパルの作成と権限付与が行われていました。
サービスプリンシパルの発行 権限付与azure cli経由でのログインも確認できました。
一時間後確認すると、サービスプリンシパルは削除されており、azure cli経由でログインができないことまで確認できました。
無事動的シークレットができることがわかりました。
5. まとめ
vaultの概要、インストール方法、動的シークレットの検証内容をまとめました。
動的シークレットはクラウドサービスを使っていくうえでは、とてもありがたい機能だと思いました。
ただ、実際にvaultを運用に使用すると考えると、サーバ構成や権限等検討が必要そうな内容がたくさんあります。
コストパフォーマンスを見極めた上で導入を検討する必要がありそうだと感じました。
その他の基本的な操作はチュートリアルがおすすめなので、基本的な機能を試す際は以下を参照してください。
https://learn.hashicorp.com/vault/getting-started/install
参考資料
- vault チュートリアルサイト
https://learn.hashicorp.com/vault/getting-started/install - vault ダウンロードサイト
https://www.vaultproject.io/downloads - Azure Secrets Engine
https://www.vaultproject.io/docs/secrets/azure