Ubuntu20.04でHashiCorpVaultを使用してシークレットを安全に管理する方法
序章
Vault は、APIキー、アクセストークン、パスワードなどのシークレットを保存および配布するための安全で信頼性の高い方法を提供するオープンソースツールです。 Vaultのようなソフトウェアは、シークレットや機密データの使用を必要とするアプリケーションを展開するときに非常に重要になる可能性があります。
このチュートリアルでは、次のことを行います。
- Vaultをインストールし、システムサービスとして構成します
- 暗号化されたオンディスクデータストアを初期化します
- TLSを介して機密値を安全に保存および取得する
いくつかの追加ポリシーを設定すると、Vaultを使用して、さまざまなアプリケーションやツールの機密データを安全に管理できるようになります。
機密情報を管理する他のサービスと同様に、本番環境のような環境で使用する前に、Vaultの展開のベストプラクティスに関する追加のドキュメントを読むことを検討する必要があります。 たとえば、 Vaultの本番強化ガイドは、ポリシー、ルートトークン、監査などのトピックをカバーしています。
前提条件
このガイドを開始する前に、次のものが必要です。
- Ubuntu 20.04の初期セットアップガイドに従ってセットアップされた1つのUbuntu20.04サーバー(sudo非rootユーザーとファイアウォールを含む)。
- VaultのHTTPAPIを保護するために使用するTLS証明書。 Ubuntu20.04用のこのCertbotスタンドアロンモードチュートリアルに従って無料で入手できます。
注:パッケージを初めてインストールすると、Vaultは自己署名TLS証明書を生成します。 Vaultで使用するドメイン名またはTLS証明書がないが、このチュートリアルの手順を実行したい場合は、TLS検証をスキップして -tls-skip-verify
このチュートリアルのコマンドにフラグを立てるか、 VAULT_SKIP_VERIFY
環境変数。
このオプションは、Vaultの実験にのみ適しており、実稼働環境では使用しないでください。
ステップ1—Vaultをインストールする
HashiCorpはVaultを典型的なDebian/Ubuntuパッケージとして提供しているため、サーバーのパッケージソースのリストにパッケージリポジトリを追加する通常の手順を実行します。
まず、Hashicorpの GPGキーをパッケージマネージャーに追加して、システムがパッケージリポジトリを信頼するようにします。
- curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
次に、リポジトリ自体をパッケージソースのリストに追加して、定期的な更新がチェックされるようにします。
- sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
次に、パッケージをインストールします。
- sudo apt install vault
これで、 vault
指図。 Vaultのバージョンをチェックして、動作することを確認してください。
- vault --version
OutputVault v1.8.5 (647eccfe0bd5817bdd8628f3c3171402dfc8a8fc)
Vault実行可能ファイルはサーバーにインストールされているため、次のステップは、システムサービスとして実行するようにVault実行可能ファイルを構成することです。
ステップ2—Vaultを構成する
Vaultパッケージをインストールすると、自動的に vault
システム上のvaultユーザーであり、Vaultをバックグラウンドで実行するためのシステムサービスをセットアップします。 Let’s Encryptによって生成されたHTTPS証明書を使用するには、デフォルトの構成にいくつかの変更を加える必要があります。
注:このチュートリアルでは、デフォルトで、Vaultはファイルシステムバックエンドを使用して、暗号化されたシークレットをローカルファイルシステムに保存します。 /opt/vault
. これは、複製する必要のないローカルまたは単一サーバーの展開に適しています。 Consulバックエンドなどの他のVaultバックエンドは、暗号化されたシークレットを分散キー/値ストア内に保存します。
Vaultのデフォルト設定はに保存されます /etc/vault.d/vault.hcl
. このファイルを使用して、暗号化されたシークレットが保存されている場所など、Vaultのさまざまなオプションを制御します。
開ける vault.hcl
を使用して nano
またはお気に入りのテキストエディタ。
- sudo nano /etc/vault.d/vault.hcl
を見つける listener "tcp"
下のファイルのセクション #HTTPS listener
このブロックが含まれています。 使用している場合 nano
、を押すことができます Ctrl+W
次に入力します listener “tcp”
その行を直接見つけるには:
...
#HTTPS listener
...
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/opt/vault/tls/tls.crt"
tls_key_file = "/opt/vault/tls/tls.key"
...
}
編集します tls_cert_file
と tls_key_file
Let’sEncryptの証明書とキーファイルを指す行。 強調表示された代わりに、独自のドメイン名に置き換えることを忘れないでください your_domain
各行の一部。
listener "tcp" {
...
tls_cert_file = "/etc/letsencrypt/live/your_domain/fullchain.pem"
tls_key_file = "/etc/letsencrypt/live/your_domain/privkey.pem"
}
注:変更する必要があります address = "0.0.0.0:8200"
に address = “127.0.0.1:8200”
今のところ、このサーバーへの外部接続を防ぐためです。 127.0.0.1
localhost専用の予約済みアドレスです。 これは、サービスが適切に保護される前に、サービスがパブリックインターネットに公開されないようにするためです。 これは後で更新できますが、今のところ、この構成変更により、 vault
コマンドを実行し、HTTPSで保護されたドメイン名を正しく解決します。
ファイルを保存して閉じます。 使用している場合 nano
、 押す Ctrl+X
、 それから Y
ファイルを保存するように求められたら、 Enter
確認するために。
次に、 vault
システムユーザーには、これらの証明書を読み取るためのアクセス許可も必要です。 デフォルトでは、これらの証明書と秘密鍵には、 root
. これらを安全に利用できるようにするために、という特別なグループを作成します pki
これらのファイルにアクセスします。 グループを作成してから、 vault
それにユーザー。
- sudo groupadd pki
内の2つのディレクトリの権限を更新します /etc/letsencrypt
のメンバーを許可するディレクトリ pki
内容を読むためのグループ。
- sudo chgrp -R pki /etc/letsencrypt/archive
- sudo chgrp -R pki /etc/letsencrypt/live
- sudo chmod -R g+rx /etc/letsencrypt/archive
- sudo chmod -R g+rx /etc/letsencrypt/live
次に、 vault
ユーザーから pki
グループ。 これにより、Vaultが証明書にアクセスできるようになり、HTTPSを介して安全にリクエストを処理できるようになります。
- sudo usermod -a -G pki vault
便宜上の最後のステップとして、ルールを追加します /etc/hosts
Vaultへのリクエストを localhost
.
交換 your_domain
次のコマンドで、Let’sEncrypt証明書を取得したドメインを使用します。
- echo 127.0.0.1 your_domain.com | sudo tee -a /etc/hosts
このコマンドは行を追加します 127.0.0.1 your_domain.com
に /etc/hosts
Vaultサーバーで行うHTTPリクエストを your_domain.com
DNSを無視し、に送信されます localhost
直接。
Vaultサービスがセットアップされ、Vault構成ファイルが完成したら、Vaultを起動してシークレットストアを初期化する準備が整いました。
ステップ3—Vaultを初期化する
Vaultを最初に起動すると、初期化されません。つまり、データを受信して保存する準備ができていません。 チュートリアルのこのセクションでは、Vaultサーバーを起動し、Vaultのシークレットストアを開封(開く)するために使用される一連のシークレットキーを使用してサーバーを初期化します。
Vaultを初めて起動すると、暗号化されたシークレットを実際に保存するバックエンドも初期化されません。 Vaultシステムサービスを開始してバックエンドを初期化し、Vault自体の実行を開始します。
- sudo systemctl start vault.service
クイックチェックを実行して、サービスが正常に開始されたことを確認できます。
- sudo systemctl status vault.service
次のような出力が表示されます。
Output● vault.service - "HashiCorp Vault - A tool for managing secrets"
Loaded: loaded (/lib/systemd/system/vault.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2021-11-16 21:55:13 UTC; 22s ago
Docs: https://www.vaultproject.io/docs/
Main PID: 104207 (vault)
Tasks: 7 (limit: 1137)
Memory: 179.3M
CGroup: /system.slice/vault.service
└─104207 /usr/bin/vault server -config=/etc/vault.d/vault.hcl
そのコマンドの出力には、プロセスIDやリソースの使用状況など、実行中のサービスに関するいくつかの情報が含まれている必要があります。 次の行が出力に含まれていることを確認してください。これは、サービスが正しく実行されていることを示しています。
Output. . .
Active: active (running)
. . .
サービスがアクティブでない場合は、コマンドの出力の最後にある付随するログ行を調べて、Vaultの出力を確認してください。これは、問題を特定するのに役立ちます。
次に、環境変数を設定して、 vault
Vaultサーバーへの接続方法をコマンドします。 ステップ1で、ローカルループバックインターフェイスでのみリッスンするようにVaultを設定したため、 VAULT_ADDR
ローカルHTTPSエンドポイントへの環境変数。
- export VAULT_ADDR=https://your_domain:8200
The vault
コマンドがデーモンと通信できるようになりました。 単にではなく、実際のホスト名を定義することに注意してください localhost
また 127.0.0.1
HTTPS証明書を適切に検証するために必要です。
ボールトサーバーのステータスを確認して、ボールトサーバーが初期化されていない状態にあることを確認します。
- vault status
サーバーは、機能しているがまだ初期化されていないことがわかるように、出力を返す必要があります。
Key Value
--- -----
Seal Type shamir
Initialized false
Sealed true
Total Shares 0
Threshold 0
Unseal Progress 0/0
Unseal Nonce n/a
Version 1.8.5
Storage Type file
HA Enabled false
Vaultが初期化時に公開する情報は2つあり、他の時点では利用できません。
- 初期ルートトークン。 これは、Vault展開に対するルート権限に相当し、すべてのVaultポリシー、マウント、およびシークレットの管理を可能にします。
- キーを開封します。 これらは、デーモンの起動時にVaultのシールを解除するために使用されます。これにより、Vaultデーモンがバックエンドシークレットストアを復号化できるようになります。
より具体的には、Vaultの開封プロセスは、キー共有によって形成されたキーを使用してバックエンドを復号化します。 Vaultを最初に初期化するときに、作成する開封キーの数と、Vaultを正常に開封するために開封時に必要な数を選択できます。 Vaultのシーリングメカニズムの詳細については、Vaultのドキュメントを参照してください。
アンシールパラメータの一般的な構成は、3つのキーを作成し、アンシール時にそれらのキーのうち少なくとも2つを必要とすることです。 これにより、重要なキー共有を分離して別々の場所に保存し、侵害したキー共有がVaultの開封に十分でないことを確認できます。
つまり、Vaultを起動するたびに、サービスを使用可能にして使用できるようにするために、少なくとも2つの開封キーが必要になります。 封印されている間、実際のシークレット値を格納するファイルは暗号化されたままになり、アクセスできなくなります。
を使用して3つの開封キーでVaultを初期化します -key-shares=3
オプションであり、ボールトを開封するには少なくとも2つのキーが必要です。 -key-threshold=2
国旗::
- vault operator init -key-shares=3 -key-threshold=2
次のような出力が表示されます。
OutputUnseal Key 1: eZcJeydRrqeSMZ1zTN+VVll9TFT2KvJy7VlnxUgtvuz5
Unseal Key 2: ntmqCKq8rgNnKT1YSLCjVmCCZBAA3NwUeqxIyRpYD4Wm
Unseal Key 3: 3FK1+Hsorh4p8/L9mki3VskaEU2eQhLqGOI/pJkTHMbx
Initial Root Token: s.hY0ieybfDqCadz7JpL88uO3x
必ず各開封トークンと最初のルートトークンを安全な方法で保存してください。 これらのキーとルートトークンを再度取得することはできなくなります。 たとえば、1つのオプションは、1つの開封キーをパスワードマネージャーに保存し、別のキーをUSBドライブに保存し、別のキーをGPG暗号化ファイルに保存することです。
調べたら vault status
繰り返しますが、 Initialized
ステータスがに設定されます true
、 そしてその Total Shares
と Threshold
値は、ボールトを開封するために必要なキーシャードの数とキーの最小数を反映します。
- vault status
Output. . .
Initialized true
Sealed true
Total Shares 3
Threshold 2
Unseal Progress 0/2
. . .
に注意してください Unseal Progess
線は値を示します 0/2
. 新しく作成した開封トークンを使用して、Vaultの開封を開始します。 を実行します vault operator unseal
コマンドを実行し、プロンプトが表示されたら任意のキーを入力します。
- vault operator unseal
コマンドは、開封トークンを要求します。
OutputKey (will be hidden):
入力後、コマンドからの出力は、開封が進行中であることを示しますが、Vaultを使用する準備ができるまでにもう1つの開封キーが必要です。
OutputKey Value
--- -----
Seal Type shamir
Initialized true
Sealed true
Total Shares 3
Threshold 2
Unseal Progress 1/2
Unseal Nonce 0f3a328b-e0c6-6294-d6a2-56da49271dff
Version 1.8.5
Storage Type file
HA Enabled false
どのように Unseal Progress 1/2
出力の行が変更されました。 を実行します unseal
もう一度コマンドします。
- vault operator unseal
そして、すでに使用したものとは異なるキーを入力します。
OutputKey (will be hidden):
コマンドの出力は、開封プロセスが正常に完了したことを示しています。
OutputKey Value
--- -----
Seal Type shamir
Initialized true
Sealed false
Total Shares 3
Threshold 2
Version 1.8.5
Storage Type file
Cluster Name vault-cluster-3042c7bc
Cluster ID c3e9d814-cf2a-2901-f0e4-ebc52d29e5cc
HA Enabled false
これでVaultは開封され、使用できるようになりました。 これらの開封手順は、Vaultを起動または再起動するたびに必要です。
ただし、開封は、トークンによって認証されるVaultとの通常の相互作用(値の読み取りや書き込みなど)とは異なるプロセスです。 次の手順では、シークレット値を保存し、Vaultの特定のパスに対して読み取り/書き込みを行うために必要なアクセストークンとポリシーを作成します。
ステップ4—秘密の読み取りと書き込み
Vaultで使用できるシークレットバックエンドはいくつかありますが、この例では、kvシークレットバックエンドを使用します。 このバックエンドは、単純なキーと値のペアをVaultに格納します。 ただし、デフォルトでは有効になっていません。
チュートリアルのこのセクションでは、 kv
シークレットバックエンド、そしてそれにシークレットを読み書きする方法を学びます。
まず、使いやすさのために、以前に生成されたルートトークンをシェル変数に保存します。
- root_token=your_root_token_here
次に、ルートトークンで認証しているときに、 kv
バックエンド:
- VAULT_TOKEN=$root_token vault secrets enable kv
コマンドが成功すると、次のような出力が表示されます。
OutputSuccess! Enabled the kv secrets engine at: kv/
次に、それが利用可能なシークレットバックエンドのローカルリストに追加されていることを確認できます。
- VAULT_TOKEN=$root_token vault secrets list
次のような出力を受け取るはずです。
OutputPath Type Accessor Description
---- ---- -------- -----------
cubbyhole/ cubbyhole cubbyhole_abc1631b per-token private secret storage
identity/ identity identity_631fe262 identity store
kv/ kv kv_4d5855c8 n/a
sys/ system system_79b13f2f system endpoints used for control, policy and debugging
新しいことを示す強調表示された行に注意してください kv
バックエンドが有効になっています。 これで、このバックエンドを使用していくつかのデータを保存できます。
- VAULT_TOKEN=$root_token vault write kv/message value=mypassword
このコマンドでは、強調表示されています kv/
プレフィックスは、に書き込みを行っていることを示します kv
にマウントされたバックエンド kv
パス、およびキーを保存しています value
パスで message
値で mypassword
. スーパーユーザー権限を持つルートトークンを使用して、一般的なシークレットを記述しました。
を使用して作成した秘密を確認してください vault read
指図:
- VAULT_TOKEN=$root_token vault read kv/message
作成したシークレットの内容とともに、次のような出力を受け取るはずです。
OutputKey Value
--- -----
refresh_interval 768h
value mypassword
ただし、ルートトークンのみを使用してVaultを作成、読み取り、またはその他の方法で操作することは、安全ではなく、チーム設定でスケーラブルであり、シークレットへのきめ細かいアクセス制御を許可しません。 次のセクションでは、ポリシーを定義し、追加のアクセストークンを作成して、ユーザーがVaultを操作する方法を制限する方法を学習します。
ステップ5—承認ポリシーを作成する
実際のシナリオでは、外部ツールが使用できるAPIキーやパスワードなどの値を保存できます。 ルートトークンを使用してシークレット値を再度読み取ることもできますが、単一のシークレットに対する読み取り専用のアクセス許可を持つ特権の低いトークンを生成することを示しています。
チュートリアルのこのセクションでは、シークレットへの読み取り専用アクセスを強制するVaultポリシーを作成します。 ポリシーを作成するには、ファイルを編集してから、を使用してVaultにロードする必要があります。 vault policy
指図。
ポリシーの作成を開始するには、次のファイルを開きます。 policy.hcl
を使用して nano
またはお好みの編集者:
- nano policy.hcl
シークレットパスへの読み取り専用アクセスを定義する次のVaultポリシーをファイルに入力します。
path "kv/message" {
capabilities = ["read"]
}
ファイルを保存して閉じてから、このポリシーをVaultに書き込みます。 次のコマンドは、 policy.hcl
Vaultにファイルし、という名前のポリシーを作成します message-readonly
読み取り専用機能付き
- VAULT_TOKEN=$root_token vault policy write message-readonly policy.hcl
次に、Vaultへの読み取り専用アクセスに使用するトークンを作成します。 追加します -policy=”message-readonly”
にフラグを立てる vault token create
作成した新しいポリシーを使用するコマンド:
- VAULT_TOKEN=$root_token vault token create -policy="message-readonly"
出力は次のようになります。
OutputKey Value
--- -----
token your_token_value
token_accessor your_token_accessor
token_duration 768h0m0s
token_renewable true
token_policies ["default" "message-readonly"]
identity_policies []
policies ["default" "message-readonly"]
ハイライトされたものを保存します your_token_value
と呼ばれる環境変数への値 app_token
:
- app_token=your_token_value
の値を使用できます app_token
パスに保存されているデータにアクセスするには kv/message
(Vaultには他の値はありません)。
- VAULT_TOKEN=$app_token vault read kv/message
OutputKey Value
--- -----
refresh_interval 768h0m0s
value mypassword
この非特権トークンが、Vaultにシークレットを一覧表示するなど、他の操作を実行できないことをテストすることもできます。
- VAULT_TOKEN=$app_token vault list kv/
OutputError reading kv/: Error making API request.
URL: GET https://your_domain:8200/v1/secret?list=true
Code: 403. Errors:
* 1 error occurred:
* permission denied
これにより、特権の低いアプリトークンが、Vaultポリシーで明示的に指定されているもの以外の破壊的なアクションを実行したり、他の秘密の値にアクセスしたりできないことが確認されます。 読み取り専用トークンを引き続き使用する場合は、将来使用できるように安全な場所に記録してください。
結論
この記事では、Ubuntu 20.04にVaultをインストール、構成、およびデプロイしました。 また、Vaultを開封するためのシャードキーを作成し、 kv
バックエンドシークレットストア、およびユーザーがVaultシークレットを操作する方法を制限する読み取り専用ポリシーを定義しました。
このチュートリアルでは、非特権トークンの使用方法のみを示しましたが、Vaultのドキュメントには、シークレットを保存およびアクセスするための追加の方法と代替認証方法の例がさらにあります。
これらの手順は、Vaultのコア機能のいくつかを展開して使用する方法を示しています。 ニーズによっては、他の構成変更やより複雑なポリシーが必要になる場合があります。 必ずVaultのドキュメントを読み、必要に応じて適切な構成変更を行ってください。 本番環境に対応した変更には、次のものが含まれる場合があります。
-
日常的に使用するための特権の低いトークンを生成します。 これらのトークンが使用する必要がある特定のポリシーは、特定のユースケースによって異なりますが、例
app_token
このチュートリアルでは、制限付き特権のトークンとポリシーを作成する方法を説明します。 -
チームが使用するサービスの一部としてVaultを展開する場合は、チームメンバーごとに開封キーを使用してVaultを初期化します。 このアプローチにより、Vaultのストレージは、複数のチームメンバーがプロセスに参加している場合にのみ復号化されます。