Ubuntu 16.04でHashiCorp Vaultを使用して秘密を安全に管理する方法

前書き

Vaultは、APIキー、アクセストークン、パスワードなどの秘密を保存および配布するための安全で信頼できる方法を提供するオープンソースツールです。 秘密や機密データの使用を必要とするアプリケーションを展開する場合、Vaultなどのソフトウェアは非常に重要です。

このチュートリアルでは、次のことを行います。

  • Vaultをインストールし、システムサービスとして構成する

  • 暗号化されたオンディスクデータストアを初期化する

  • TLSを介して機密値を安全に保存および取得する

いくつかの追加ポリシーを導入すると、Vaultを使用して、さまざまなアプリケーションやツールの機密データを安全に管理できます。

機密情報を管理するサービスと同様に、本番環境で使用する前に、Vaultの展開のベストプラクティスに関する追加のドキュメントを読むことを検討する必要があります。 たとえば、https://www.vaultproject.io/guides/production.html [Vaultの運用強化ガイド]は、ポリシー、ルートトークン、監査などのトピックを扱っています。

前提条件

このガイドを始める前に、次のものが必要です。

ステップ1-Vaultのインストール

HashiCorpはVaultを単一のバイナリとして提供するため、Vaultの実行可能ファイルを手動でダウンロードしてインストールします。

最初に、64ビットLinux用の圧縮されたVault zipアーカイブをダウンロードします。 最新バージョン(執筆時点では0.9.5)へのリンクは、https://www.vaultproject.io/downloads.html [Vaultのダウンロードページ]にあります。

wget https://releases.hashicorp.com/vault//vault__linux_amd64.zip

次に、このファイルのチェックサムをダウンロードして、ダウンロードを確認できるようにします。

wget https://releases.hashicorp.com/vault//vault__SHA256SUMS

次に、zipアーカイブの整合性を確認します。 これは、zipアーカイブの内容が、HashicorpがVaultのバージョン0.9.5でリリースしたものと一致することを確認するためです。

grep linux_amd64 vault_*_SHA256SUMS | sha256sum -c -

+ SHA256SUMS +`ファイルの各行にはチェックサムとファイル名があり、HashiCorpが提供するzipアーカイブごとに1つです。 上記のコマンドの `+ grep +`部分は、64ビットLinuxバイナリのチェックサムとファイル名を含む行を出力し、その行を次のコマンドにパイプ( `+ | +)します。 SHA-256コマンドは、その行のファイル名を持つファイルがその行のチェックサムと一致することを `+ -c +`でチェックします。

コマンドを実行すると、アーカイブが「+ OK +」であることを示す必要があります。 そうでない場合は、ファイルを再ダウンロードしてください。

Outputvault__linux_amd64.zip:

チェックサム検証が完了したら、アーカイブを解凍できるように、 `+ unzip +`コマンドをインストールします。 最初にパッケージリポジトリが最新であることを確認してください。

sudo apt-get update
sudo apt-get install unzip

次に、Vaultバイナリを作業ディレクトリに解凍します。

unzip vault_*.zip
OutputArchive:  vault__linux_amd64.zip
 inflating: vault

Vault実行可能ファイルをシステムの `+ PATH +`のディレクトリに移動して、シェルからアクセスできるようにします。

sudo cp vault /usr/local/bin/

最後に、バイナリにLinux機能フラグを設定します。 これにより、バイナリがその特権を不必要に上げることなくメモリロックを実行できるようになり、セキュリティが強化されます。

sudo setcap cap_ipc_lock=+ep /usr/local/bin/vault

これで、 `+ vault +`コマンドを使用できます。 Vaultのバージョンを確認して、機能することを確認してください。

vault --version
OutputVault v0.7.2 ('d28dd5a018294562dbc9a18c95554d52b5d12390')

Vault実行可能ファイルはサーバーにインストールされているため、次のステップは、システムサービスとして実行するように構成することです。

ステップ2-ボールトユニットファイルの作成

Systemdは、特にシステムのサービスを管理するUbuntuの初期化システムです。 Vaultをシステムサービスとして設定するには、次のものを設定する必要があります。

最初に、* vault *システムユーザーを作成します。

sudo useradd -r -d /var/lib/vault -s /bin/nologin vault

ここでは、ユーザーのホームディレクトリとして「+ / var / lib / vault 」を使用します。 これは、Vaultデータディレクトリとして使用されます。 また、シェルを「 / bin / nologin +」に設定して、ユーザーを非対話型システムアカウントとして制限します。

`+ / var / lib / vault +`の所有権を* vault ユーザーと vault *グループのみに設定します。

sudo install -o vault -g vault -m 750 -d /var/lib/vault

次に、Vaultの設定ファイル「+ / etc / vault.hcl +」をセットアップします。 これを使用して、暗号化されたシークレットの保存場所など、Vaultのさまざまなオプションを制御します。

`+ nano `またはお好みのテキストエディターを使用して、 ` vault.hcl +`を作成します。

sudo nano /etc/vault.hcl

以下をファイルに貼り付け、独自のドメイン名に置き換えてください。

/etc/vault.hcl

backend "file" {
       path = "/var/lib/vault"
}

listener "tcp" {
       tls_disable = 0
       tls_cert_file = "/etc/letsencrypt/live//fullchain.pem"
       tls_key_file = "/etc/letsencrypt/live//privkey.pem"

}

この構成ファイルは、ディスク上の `+ / var / lib / vault +`に暗号化されたシークレットを保存するようVaultに指示し、Let’s Encryptチュートリアルから生成された証明書を使用してHTTPS経由で接続をリッスンする必要があることを示します

ファイルを保存して閉じ、* vault *ユーザーにのみ読み取りを許可することにより、Vault構成ファイルの権限を保護します。

sudo chown vault:vault /etc/vault.hcl
sudo chmod 640 /etc/vault.hcl

次に、Systemdが永続的なVaultデーモンを管理できるように、https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files [unit file]を `+ / etc / systemd /に作成しますsystem / vault.service + `。

sudo nano /etc/systemd/system/vault.service

以下をコピーしてファイルに貼り付けます。 これにより、Vaultは永続的なシステムサービスデーモンとしてバックグラウンドで実行できます。

/etc/systemd/system/vault.service

[Unit]
Description=a tool for managing secrets
Documentation=https://vaultproject.io/docs/
After=network.target
ConditionFileNotEmpty=/etc/vault.hcl

[Service]
User=vault
Group=vault
ExecStart=/usr/local/bin/vault server -config=/etc/vault.hcl
ExecReload=/usr/local/bin/kill --signal HUP $MAINPID
CapabilityBoundingSet=CAP_SYSLOG CAP_IPC_LOCK
Capabilities=CAP_IPC_LOCK+ep
SecureBits=keep-caps
NoNewPrivileges=yes
KillSignal=SIGINT

[Install]
WantedBy=multi-user.target

サービスユニットオプションの完全なリストは広範囲に渡りますが、上記の定義で注意すべき最も重要な構成オプションは次のとおりです。

  • `+ ConditionFileNotEmpty `は、 ` / etc / vault.hcl +`設定ファイルが存在することを保証します。

  • + User`と + Group`は、Vaultデーモンを実行するユーザーの権限を制御します。

  • + ExecStart +。以前にインストールした実行可能ファイルを指し、サービスの実行を開始するものを定義します。

  • + ExecReload +。これは、Vaultがその構成ファイルをリロードするときに呼び出されます(例: `+ systemctl reload vault +`を実行するとき)。

  • + [Install] +。起動時にこのサービスを永続的に実行できるため、再起動後に手動で開始する必要がありません。

最後に、Vaultには、Certbotで作成した証明書を読み取る権限が必要です。 デフォルトでは、これらの証明書と秘密鍵には* root のみがアクセスできます。 これらを安全に利用できるようにするため、 pki という特別なグループを作成してこれらのファイルにアクセスします。 グループを作成してから、それに vault *ユーザーを追加します。

ファイルを保存して閉じてから、* pki *グループを作成します。

sudo groupadd pki

`+ / etc / letsencrypt +`ディレクトリ内の2つのディレクトリのアクセス許可を更新して、* pki *グループがコンテンツを読み取れるようにします。

sudo chgrp pki /etc/letsencrypt/{archive,live}
sudo chmod g+rx /etc/letsencrypt/{archive,live}

次に、* vault ユーザーを pki *グループに追加します。 これにより、Vaultが証明書にアクセスできるようになり、HTTPSを介して安全にリクエストを処理できるようになります。

sudo gpasswd -a vault pki

便宜上、最終ステップとして、「+ / etc / hosts 」にルールを追加して、Vaultへのリクエストを「 localhost +」に転送します。

デフォルトでは、Vaultはループバックインターフェイス( + lo +`またはアドレス `+ 127.0.0.1 +)からのリクエストのみをリッスンします。 これは、サービスが適切に保護される前に、サービスがパブリックインターネットに公開されないようにするためです。 これは後で更新できますが、今のところ、この設定変更により、 `+ vault +`コマンドを使用してHTTPSで保護されたドメイン名を正しく解決できるようになります。

次のコマンドの「++」を、Let’s Encrypt証明書を取得したドメインに置き換えます。

echo 127.0.0.1  | sudo tee -a /etc/hosts

これにより、行 `127.0.0.1 +`が ` / etc / hosts `に追加され、 `+`へのHTTPリクエストが `+ localhost +`にルーティングされます。

Vault実行可能ファイルがセットアップされ、サービスファイルが書き込まれ、Vault構成ファイルが完成したら、Vaultを起動してシークレットストアを初期化する準備ができました。

ステップ3-Vaultの初期化

Vaultを初めて起動すると、初期化されません。つまり、データを取得して保存する準備ができていません。

Vaultを初めて起動したとき、暗号化されたシークレットを実際に保存するバックエンドも初期化されていません。 Vaultシステムサービスを開始してバックエンドを初期化し、Vault自体の実行を開始します。

sudo systemctl start vault

クイックチェックを実行して、サービスが正常に開始されたことを確認できます。

sudo systemctl status vault

そのコマンドの出力には、プロセスIDやリソース使用量など、実行中のサービスに関する情報がいくつか含まれている必要があります。 サービスが正しく実行されていることを示す次の行が出力に含まれていることを確認します。

Output. . .
Active: active (running)
. . .

サービスがアクティブでない場合は、コマンドの出力の最後にある付随するログ行を見て、Vaultの出力を確認してください。これは、問題を特定するのに役立ちます。

次に、環境変数を設定して、 `+ vault `コマンドにVaultサーバーへの接続方法を伝えます。 ここでは、Vaultはローカルループバックインターフェイスのみでリッスンするように設定されているため、 ` VAULT_ADDR +`環境変数をローカルHTTPSエンドポイントに設定します。

export VAULT_ADDR=https://:8200

`+ vault `コマンドはデーモンと通信できるようになりました。 HTTPS証明書を適切に検証するには、単に「 localhost 」または「+127.0.0.1」ではなく、実際のホスト名を定義する必要があることに注意してください。

ステータスを確認して、ボールトが初期化されていない状態であることを確認します。

vault status

サーバーは、サーバーがまだ初期化されていないことを示す400エラーを返します。

OutputError checking seal status: Error making API request.

URL: GET https://example.com:8200/v1/sys/seal-status
Code: 400. Errors:

* server is not yet initialized

初期化時にVaultが公開する2つの情報がありますが、これらは他の時点では利用できません。

  • 初期ルートトークン。 これは、すべてのVaultポリシー、マウントなどの管理を可能にするVault展開のルート権限に相当します。

  • キーの開封。 これらは、デーモンの起動時にVaultを封印解除するために使用されます。これにより、Vaultデーモンはバックエンドシークレットストアを復号化できます。

具体的には、Vaultの開封プロセスは、キー共有で形成されたキーを使用してバックエンドを復号化します。 つまり、Vaultを初期化するときに、作成する開封キーの数と、開封時にVaultを正常に開封するために必要な開封キーの数を選択できます。

封印解除パラメータの一般的な単純な値は、3つのキーを作成し、封印解除時にそれらのキーのうち少なくとも2つを必要とすることです。 これにより、重要なキー共有を個別の場所に分離して保存し、危殆化したキー共有がVaultの封印を解除するのに十分でないことを保証できます。

言い換えると、Vaultを起動するたびに、サービスを利用可能にして使用できる状態にするために、少なくとも2つの封印解除キーが必要になります。 封印されている間、実際のシークレット値を保存するファイルは暗号化されたままで、アクセスできません。

前述のパラメーターを使用してVaultを初期化します。

vault init -key-shares=3 -key-threshold=2

各封印解除トークンと初期ルートトークンを安全な方法で保存します。 たとえば、1つのオプションは、1つの封印解除キーをパスワードマネージャーに保存し、もう1つをUSBドライブに保存し、もう1つをGPG暗号化ファイルに保存することです。

新しく作成した封印解除トークンを使用して、Vaultを封印解除できるようになりました。 1つのキーを使用して開封することから始めます。

vault operator unseal

コマンドは、封印解除トークンを要求します。

OutputKey (will be hidden):

入力後、コマンドからの出力は開封が進行中であることを示しますが、Vaultを使用する準備ができる前にもう1つの開封キーが必要です。

OutputSealed: true
Key Shares: 3
Key Threshold: 2
Unseal Progress: 1
Unseal Nonce: 3bdc838e-1b74-bc13-1d6f-c772f1694d83

`+ unseal +`コマンドを再度実行します。

vault operator unseal

そして、すでに使用したものとは異なるトークンを入力します。

OutputKey (will be hidden):

コマンドの出力は、封印解除プロセスが正常に完了したことを示しています。

OutputSeal Type       shamir
Sealed          false
Total Shares    3
Threshold       2
Version         0.9.5
Cluster Name    vault-cluster-5511b3ff
Cluster ID      53522534-8ee1-8aec-86db-e13e4a499dd0
HA Enabled      false

Vaultの封印が解除され、使用できる状態になりました。 これらの封印解除手順は、Vaultを起動または再起動するたびに必要です。

ただし、封印解除は、_tokens_によって認証されるVaultとの通常の対話(値の読み取りや書き込みなど)とは異なるプロセスです。 最後の手順では、秘密の値を保存し、Vaultの特定のパスの読み取り/書き込みに必要なアクセストークンとポリシーを作成します。

ステップ4-秘密の読み取りと書き込み

Vaultのドキュメントに列挙されている秘密のバックエンドがいくつかありますが、この例ではhttps://www.vaultproject.io/docs/を使用しますsecrets / generic / index.html [generic secret backend]。 このバックエンドは、単純なキー/値のペアをVaultに保存します。

最初に、使いやすくするために、以前に生成されたルートトークンをシェル変数に保存します。

root_token=

まず、Vault内のパスに値を書き込みます。

VAULT_TOKEN=$root_token vault write secret/message value=mypassword

このコマンドでは、プレフィックス「+ secret / 」は、「 secret 」パスにマウントされた「 generic 」バックエンドに書き込みを行い、パス「 message 」にキー「 value 」を格納していることを示します値は「 mypassword +」です。 スーパーユーザー特権を持つルートトークンを使用して、汎用シークレットを記述しました。

実際のシナリオでは、外部ツールが消費できるAPIキーやパスワードなどの値を保存できます。 ルートトークンを使用してシークレット値を再度読み取ることはできますが、単一のシークレットに対する読み取り専用のアクセス許可を持つ、より権限の少ないトークンを生成することは実例です。

`+ policy.hcl +`というファイルを作成します。

nano policy.hcl

ファイルに次のVaultポリシーを入力します。このポリシーは、作業ディレクトリのシークレットパスへの読み取り専用アクセスを定義します。

policy.hcl

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

ファイルを保存して閉じ、このポリシーをVaultに書き込みます。 次のコマンドは、ポリシーの権限を持つ `+ message-readonly +`という名前のポリシーを作成します。

VAULT_TOKEN=$root_token vault policy write message-readonly policy.hcl

これで、ポリシーで指定された権限を持つトークンを作成できます。

VAULT_TOKEN=$root_token vault token create -policy="message-readonly"

出力は次のようになります。

OutputKey             Value
---             -----
token
token_accessor  your_token_accessor
token_duration  768h0m0s
token_renewable true
token_policies  [default message-readonly]

+ token`の値を + id_token`という変数に保存します。

app_token=

`+ app_token `の値を使用して、パス ` secret / message +`に保存されているデータにアクセスできます(Vaultには他の値はありません)。

VAULT_TOKEN=$app_token vault read secret/message
OutputKey                     Value
---                     -----
refresh_interval        768h0m0s
value

また、この非特権トークンがVaultでのシークレットの一覧表示など、他の操作を実行できないことをテストすることもできます。

VAULT_TOKEN=$app_token vault list secret/
OutputError reading secret/: Error making API request.

URL: GET https://example.com:8200/v1/secret?list=true
Code: 403. Errors:

*

これにより、権限の低いアプリトークンが破壊的なアクションを実行したり、Vaultポリシーで明示的に指定された値以外のその他のシークレット値にアクセスしたりできないことが検証されます。

結論

この記事では、Ubuntu 16.04にVaultをインストール、構成、展開しました。 このチュートリアルでは、特権のないトークンの使用についてのみ説明しましたが、Vaultのドキュメントには、https://www.vaultproject.io/docs/secrets/index.html [シークレットを保存およびアクセスする追加の方法]およびhttpsに関する詳細情報があります。 //www.vaultproject.io/docs/auth/index.htm [代替認証方法]。

これらの手順では、かなり基本的な方法でVaultを展開して使用する方法を概説したため、https://www.vaultproject.io/docs/index.html [Vaultのドキュメント]を読み、ニーズに合わせて適切な構成変更を行ってください。 生産準備が整った変更には次のものがあります。

  • 日常的に使用するために、より低い特権のトークンを生成します。 これらのトークンが使用する特定のポリシーは、特定のユースケースによって異なりますが、前述の「+ app_token +」は、特権が制限されたトークンとポリシーの作成方法を示しています。

  • Vaultがチームサービスの一部として展開されている場合、各チームメンバーの封印解除キーを使用してVaultを初期化すると、複数のチームメンバーがプロセスに参加する場合にのみVaultのストレージが復号化されます。

Related