序章

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

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

  • Vaultをインストールし、システムサービスとして構成します
  • 暗号化されたオンディスクデータストアを初期化します
  • TLSを介して機密値を安全に保存および取得する

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

機密情報を管理する他のサービスと同様に、本番環境のような環境で使用する前に、Vaultの導入のベストプラクティスに関する追加のドキュメントを読むことを検討する必要があります。 たとえば、 Vaultの本番強化ガイドは、ポリシー、ルートトークン、監査などのトピックをカバーしています。

前提条件

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

ステップ1—Vaultをインストールする

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

まず、64ビットLinux用の圧縮されたVaultzipアーカイブをダウンロードします。 最新バージョン(執筆時点では0.9.5)へのリンクは、Vaultのダウンロードページにあります。

  1. wget https://releases.hashicorp.com/vault/0.9.5/vault_0.9.5_linux_amd64.zip

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

  1. wget https://releases.hashicorp.com/vault/0.9.5/vault_0.9.5_SHA256SUMS

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

  1. grep linux_amd64 vault_*_SHA256SUMS | sha256sum -c -

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

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

Output
vault_0.9.5_linux_amd64.zip: OK

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

  1. sudo apt-get update
  2. sudo apt-get install unzip

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

  1. unzip vault_*.zip
Output
Archive: vault_0.9.5_linux_amd64.zip inflating: vault

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

  1. sudo cp vault /usr/local/bin/

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

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

これで、vaultコマンドを使用できます。 Vaultのバージョンをチェックして、動作することを確認してください。

  1. vault --version
Output
Vault v0.7.2 ('d28dd5a018294562dbc9a18c95554d52b5d12390')

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

ステップ2—Vaultユニットファイルを作成する

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

  • Vaultデーモンを次のように実行するためのシステムユーザー
  • Vaultの情報を保存するデータディレクトリ
  • Vaultの構成ファイル
  • systemdユニットファイル自体。

:このチュートリアルでは、ファイルシステムバックエンドを使用して、暗号化されたシークレットを/var/lib/vaultのローカルファイルシステムに保存します。 これは、複製する必要のないローカルまたは単一サーバーのデプロイメントに適しています。 Consulバックエンドなどの他のVaultバックエンドは、暗号化されたシークレットを分散キー/値ストア内に保存します。

まず、vaultシステムユーザーを作成します。

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

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

/var/lib/vaultの所有権をvaultユーザーとvaultグループに排他的に設定します。

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

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

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

  1. 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/example.com/fullchain.pem"
        tls_key_file = "/etc/letsencrypt/live/example.com/privkey.pem"

}

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

ファイルを保存して閉じ、 vault ユーザーにのみ読み取りを許可して、Vault構成ファイルのアクセス許可を保護します。

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

次に、Systemdに永続的なVaultデーモンを管理させるために、/etc/systemd/system/vault.serviceユニットファイルを作成します。

  1. 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グループを作成します。

  1. sudo groupadd pki

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

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

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

  1. sudo gpasswd -a vault pki

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

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

次のコマンドのexample.comを、Let’sEncrypt証明書を取得したドメインに置き換えます。

  1. echo 127.0.0.1 example.com | sudo tee -a /etc/hosts

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

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

ステップ3—Vaultを初期化する

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

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

  1. sudo systemctl start vault

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

  1. sudo systemctl status vault

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

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

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

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

  1. export VAULT_ADDR=https://example.com:8200

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

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

  1. vault status

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

Output
Error 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を初期化します。

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

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

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

  1. vault operator unseal

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

Output
Key (will be hidden):

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

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

unsealコマンドを再実行してください。

  1. vault operator unseal

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

Output
Key (will be hidden):

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

Output
Seal 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を起動または再起動するたびに必要です。

ただし、開封は、トークンによって認証されるVaultとの通常の相互作用(値の読み取りや書き込みなど)とは異なるプロセスです。 最後のステップでは、シークレット値を格納し、Vaultの特定のパスに対して読み取り/書き込みを行うために必要なアクセストークンとポリシーを作成します。

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

Vaultのドキュメントにはいくつかのシークレットバックエンドが列挙されていますが、この例では汎用シークレットバックエンドを使用します。 このバックエンドは、単純なキーと値のペアをVaultに格納します。

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

  1. root_token=your_root_token_here

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

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

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

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

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

  1. nano policy.hcl

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

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

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

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

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

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

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

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

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

  1. app_token=your_token_value

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

  1. VAULT_TOKEN=$app_token vault read secret/message
Output
Key Value --- ----- refresh_interval 768h0m0s value mypassword

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

  1. VAULT_TOKEN=$app_token vault list secret/
Output
Error reading secret/: Error making API request. URL: GET https://example.com:8200/v1/secret?list=true Code: 403. Errors: * permission denied

これにより、特権の低いアプリトークンが、Vaultポリシーで明示的に指定されているもの以外の破壊的なアクションを実行したり、他の秘密の値にアクセスしたりできないことが確認されます。

結論

この記事では、Ubuntu 16.04にVaultをインストール、構成、およびデプロイしました。 このチュートリアルでは、非特権トークンの使用についてのみ説明しましたが、Vaultのドキュメントには、シークレットを保存およびアクセスするための追加の方法代替認証方法に関する詳細情報があります。

これらの手順では、Vaultをかなり基本的な方法で展開および使用する方法の概要を説明しているため、 Vaultのドキュメントを読み、必要に応じて適切な構成変更を行ってください。 本番環境に対応した変更には、次のものがあります。

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

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