はじめに
HashiCorp Vaultは、シークレット管理をする製品です。
"データベースの管理で「パスワードを共有して使ってる」とか、「パスワードを全然変えてない」とか、言われると耳が痛い。"
そんな人が、不安から解放されて、安眠できるようになる製品がVaultです。
有効時間を必要最短に設定し、毎回異なるものが生成される「動的シークレット」は、理屈としては、"それなー"って思うんだけど、"実際どんな感じなん?"と思う人はいると思います。この記事では、そんな方が、"こんな感じに使えるんだ!"と思える程度に詳細な設定は省いて、基本的な設定から、実際に使ってみるところまでを体感できる手順を説明します。
利用する環境
AWS上にRDS (データベース・エンジン: MySQL)とEC2 (Amazon Linux2)を作成し、EC2にVaultを導入します。データベース管理者は、CLIを使ってMySQLを管理する想定です。本来であれば、管理者は物理的に別の場所からVaultにアクセスして使うことになりますが、構成をシンプルにするため、同じEC2からの操作になっています。今回の目的では、そこは重要でないので、そこは簡略化しています。
環境構築
今回、利用するAWSのEC2とRDSのデプロイと設定は省略します。同じ、サブネットに配置して、IP Reachableになっていれば、大丈夫です。
Vaultの導入
Vaultは、下記のサイトを参照して、導入しました。(Amazon Linuxの箇所を参照)
HashiCorp Official: Install Vault
$ sudo yum install -y yum-utils shadow-utils
$ sudo yum-config-manager --add-repo \
https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo
$ sudo yum install vault
Vaultの起動
実際に業務でVaultを利用する場合には、可用性などを検討して、構成を検討する必要があります。そして、その決定された構成に対する構成ファイルを記載してVaultを稼働させます。今回は、Vaultの機能を確認するという目的なので、開発モードで起動させます。画面にも表示されますが、業務ではこのモードで使用しないでください。ここでは、バックグラウンド・プロセスで起動させます。
$ export VAULT_ADDR='http://127.0.0.1:8200'
$ vault server -dev &
この時点で、Vaultは使える状態にはなっています。
Vaultの設定
ここからVaultの運用に必要な設定をしていきます。シークレット管理者(Vault管理者)の作業になります。
Authentication Method(認証方法)の有効化
今回はデータベース管理者になりますが、シークレットを利用者を認証する方法を有効化する必要があります。今回は、一番わかり易いVault自体で認証するuserpassのAuthentication Methodを使います。これは一般的なユーザーIDとパスワードによる認証方式です。
$ vault auth enable userpass
Policyの設定
次に、ポリシーの設定をします。
ポリシーは簡単に言うと、どのシークレットをユーザーにどのように利用させるかを定義するものになります。定義されたポリシーをユーザーに割り当てます。ユーザーは割り当てられた範囲のシークレットに対して、割り当てられた能力(Capability)で利用することができます。
ここでは、この後に作成するデータベース・シークレット・エンジンに対して、dbadmin-policyを作成します。
ここでVaultにおいて、重要な考え方であるPathを説明しておきます。
Vaultでは、色々なものをPathに紐づけて定義します。ここでは、この後で、データベース・シークレット・エンジンを"demo/database"というPathにマウントするので、そのPathにポリシーを関連付けています。
$ vault policy write dbadmin-policy - <<EOF
path "demo/database/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
EOF
データベース・シークレット・エンジンの有効化
次に、データベース・シークレット・エンジンを有効化します。ここで必要なのは、どのシークレット・エンジン(データベース)を有効化するのか、そして、どのPathに設定するのかです。Pathは、ポリシーを定義したPathと一致させる必要があります。
$ vault secrets enable -path=demo/database database
MySQLプラグインのマウント
次に、MySQLプラグインをデータベース・シークレット・エンジンにマウントします。この作業は、有効化したデータベース・シークレット・エンジンの構成することになります。構成する内容は、利用するプラグイン(MySQL)、接続情報、許可するロール、管理者の情報です。コマンド内のHOSTNAME、USERNAME、PASSWORDは、実際のものを設定してください。ロールに関しては、後述します。
$ vault write demo/database/config/mysqldatabase \
plugin_name=mysql-database-plugin \
connection_url="{{username}}:{{password}}@tcp(HOSTNAME:3306)/" \
allowed_roles="demo-long-live" \
username="USERNAME" \
password="PASSWORD"
ロールの作成
次にロールを作成します。これはデータベース管理者が実施する作業に合わせた権限や有効時間(TTL)を設定します。複数のロールを作成することができます。データベース管理者が複数人存在して、それぞれの作業の範囲が異なる場合には、役割の数だけロールを作成して、必要な権限を必要な有効時間(TTL)だけ与えるように作成することが重要です。
今回は、デフォルトで3分間、最長でも6分間だけ有効となるシークレットを生成するロールを作成します。
$ vault write demo/database/roles/demo-short-live \
db_name=mysqldatabase \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED \
BY '{{password}}';GRANT ALL ON my_app.* TO '{{name}}'@'%';" \
default_ttl="3m" \
max_ttl="6m"
ユーザーの作成
次にユーザーを作成します。今回は、userpassで認証する"dbadmin1"というユーザーをパスワード"user123"で作成します。そして、このユーザーには、"dbadmin-policy"が適用されます。
$ vault write auth/userpass/users/dbadmin1 \
password="user123" \
policies="dbadmin-policy"
ここまでが、シークレット管理者(Vault管理者)の作業になります。この後は、実際にシークレットを利用するデータベース管理者の利用手順になります。
データベースの管理作業
ここからは、データベース管理者"Aさん"のデータベース管理作業になります。
Aさんは、データベースの管理作業をするために、Vaultにログインしてます。パスワードを聞かれるので、パスワードを入力します。
$ vault login -method=userpass username=dbadmin1
Password (will be hidden):
データベースのシークレットの生成要求をします。3分間だけ有効なシークレット(usernameとpassword)が生成されます。
$ vault read demo/database/creds/demo-short-live
Key Value
--- -----
lease_id demo/database/creds/demo-short-live/pLJKLEIoMHyFL4lMJGXvKtam
lease_duration 3m
lease_renewable true
password 3Zpo32FmXix-UW367sil
username v-userpass-d-demo-short-5HhxdVry
Aさんは、このシークレットを使って、MySQLにアクセスして、作業を開始します。
$ mysql -u v-userpass-d-demo-short-5HhxdVry \
-p3Zpo32FmXix-UW367sil \
-h(HOSTNAME)
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 953
Server version: 8.0.44 Source distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| performance_schema |
+--------------------+
2 rows in set (0.006 sec)
MySQL [(none)]> quit
3分後、先程生成されたシークレットは無効になります。
2025-MM-DDTHH:MM:SS.sssZ [INFO] expiration: revoked lease:
lease_id=demo/database/creds/demo-short-live/pLJKLEIoMHyFL4lMJGXvKtam
もう一度、同じシークレットでMySQLにアクセスしてみます。シークレットは無効となっているので、アクセスができません。
$ mysql -u v-userpass-d-demo-short-5HhxdVry \
-p3Zpo32FmXix-UW367sil \
-h(HOSTNAME)
ERROR 1045 (28000): Access denied for user
'v-userpass-d-demo-short-5HhxdVry'@'10.0.0.133' (using password: YES)
まとめ
概要は理解いただけたと思います。
この記事では、Vaultで動的シークレットを使ってみることを目的とし、簡易的な構成、設定をしています。しかし、実際には、それぞれの内容を十分に検討した上で構成と設定をしていく必要があります。この記事を理解の参考にして、HashiCorp Vaultでシークレット管理を実装していただけると幸いです。
参考情報
HashiCorp Vault開発者向けドキュメント
MySQL/MariaDB database secrets engine