はじめに
AWS Secrets Managerとは
DBMSアクセスなどで利用するユーザ/パスワードを、アプリケーションのコードに埋め込むとか、APサーバに設定ファイルとしてで腹持ちさせて参照させるとか、セキュリティ的に良くないですがやってしまいがちだと思います。
AWS Secrets Manager はそのような、ユーザ/パスワードなどのシークレット情報を、所有する暗号化キーで暗号化し、AWS Key Management Service (KMS) に保管するサービスです。保管しているシークレート情報は、必要都度に取得して利用します。取得はIAMのきめ細かいポリシーを使用して制限できます。
ここではAWS Secrets ManagerをVPC閉塞空間で利用するための設定し、かつリソースポリシーでシークレット情報を取得可能なVPCを制限する手順を説明します。
設定手順(SecretsManagerからの情報取得)
SecretsManager用のKMSの鍵作成
SecretsManagerのデフォルトの鍵で暗号化することもできますが、ここでは独自作成したKMSの鍵で暗号化することとし、事前にKMSの鍵を作成します。
- サービスからKMSのサービス画面に移動する
- KMS鍵の名称を入力します
- 「タグの追加」はスキップ
- キーポリシー設定
- キー管理者の設定:このキーを作成しているユーザのロールを指定します
- キーの使用アクセス許可: 一旦未指定のままにします(後で作成する、SecretsManagerでシークレット情報を取得するロールを指定します)
新しいシークレットの作成
- (1)「新しいシークレットの作成」をクリック
- (2)シークレットの設定
- シークレットタイプの選択
- タイプ: ここでは「RDS データベース認証情報」を選択します
- 対象DBユーザ: 管理したいDBユーザの、ユーザ名とパスワードを入力します。
- 暗号化キーを選択: 作成したKMSの鍵を選択します
- RDS データベースを選択: 対象のRDSを選択します。
- シークレットタイプの選択
- (3)新しいシークレットの保存
- シークレット名称を指定します
- (4)自動ローテーションの設定
- 一旦スキップします
- (5)新しいシークレットの保存
- 設定したシークレットキーを保存します。
VPC PrivateLinkの作成
EC2インスタンスロール
APサーバからSecretsManagerのシークレット情報を取得するためのロールを作成します。ロールにはSecretsManagerからの情報取得のポリシーと、KMSからの鍵取得のポリシーを設定します。
EC2インスタンスから、SecretsManagerからパスワードを取得するIAMロールを作成して、EC2インスタンスにアタッチします。
インラインポリシー*3
下記の2つのポリシーを指定します(ARNは適時修正してください)。
- (1) SecretsManagerからシークレット情報を取得するためのインラインポリシー
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret", "secretsmanager:ListSecrets" ], "Resource": "arn:aws:secretsmanager:ap-northeast-1:445629031529:secret:Prod/System-A/RDS/testuser-6l08Sp" } ] }
- (2) KMSから鍵を取得するためのインラインポリシー
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "kms:DescribeKey" ], "Resource": "arn:aws:kms:ap-northeast-1:445629031529:key/df0849ea-0c1a-44e3-b86b-43ae43396384" } ] }
信頼関係ポリシー
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
作成ロールのSecretsManager用KMS鍵のキーユーザへの登録
作成したEC2インスタンスロールを利用し、KMSのキーを取得できるように、KMS鍵のキーユーザに作成したロールを追加します。
- KMSのサービス画面から「カスタマー管理型のキー」を選択し利用する鍵をクリックする
- 「キーユーザー」に作成したロールを追加する
APサーバ上のAWS CLI設定
AWS CLIにProxy設定をしている場合、Proxyの除外設定にSecretsManagerのエンドポイントのURL(東京リージョンの場合”secretsmanager.ap-northeast-1.amazonaws.com”)を追加します。追加した後は再ログインして環境変数が反映されていることを確認します。
export HTTPS_PROXY=http://10.1.173.17:3128 export HTTP_PROXY=http://10.1.173.17:3128 export NO_PROXY=169.254.169.254,s3.ap-northeast-1.amazonaws.comi,secretsmanager.ap-northeast-1.amazonaws.com
APサーバでのシークレット情報取得テスト
aws CLIコマンドの" aws secretsmanager get-secret-value"を利用しシークレット情報を取得します。
aws secretsmanager get-secret-value --secret-id arn:aws:secretsmanager:ap-northeast-1:445629031529:secret:Prod/System-A/RDS/testuser-6l08Sp
RDBにアクセスできるかを確認します。(この例ではMySQLエンジンを利用しています)
mysql --host=<RDSのエンドポイントDNS> --port=<Port番号> --user=<ユーザID> --password='<パスワード>'
リソースポリシーでシークレット情報取得を許可するVPCを制限する
SecretsManagerは、リソースポリシーを設定することが可能です。ただしマネージメントコンソールでは設定できなず、AWS CLIでの設定が必要になります。(ここではAWS CLIでSecrets Managerの管理設定を行うための準備作業は割愛します)
リソースポリシーの設定
今回は特定のVPC Endpoint以外からのリソース情報取得のためのアクセス(GetSecretValue API)を拒否するリソースポリシーを設定します。
AWS CLIを実行する端末上でリソースポリシー用のjsonファイルを用意します。"aws:sourceVpce"には先に作成した、SecretsManager用のVPC EndpointのARNを指定します。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Principal": "*", "Action": "secretsmanager:GetSecretValue", "Resource": "*", "Condition": { "StringNotEquals": { "aws:sourceVpce": "vpce-0b2b52e1dc7772d50" } } } ] }
設定手順(ローテーションの設定)
RDBのDB管理者ユーザのログイン情報をシークレットに登録
ローテーション用のLambdaの中でDBMSのユーザ&パスワード更新を実行するため、admin権限のあるDBユーザをSecretsManagerに登録します。
リソースポリシーの一時解除
先に設定したリソースポリシーをアタッチしたままでは、ローテーションの設定が一部できないため、リソースポリシーを一時的に解除します。
aws secretsmanager delete-resource-policy --secret-id arn:aws:secretsmanager:ap-northeast-1:445629031529:secret:Prod/System-A/RDS/testuser-6l08Sp
ローテーションの有効化
- 「ローテーションの編集」からローテーション設定を行います
- 自動ローテーションを「有効化」します
- ローテーションの間隔は、1-365日の間で設定します。
- 「新しいLambda関数を作成して・・・」を選択します。これを選択するとCloudFormationからLamdbaやLambda実行に必要なIAMロールなどがデプロイされます
- 「AWSシークレットマネージャで以前保存したシークレットを資料」を選択し、DBのadminユーザのシークレットを選択します。
なお私の環境では、VPC内のLambdaで実行しようとするとLambda実行用のIAMロールのcondition設定がうまく働かずLambdaからSecretsManagerへの情報取得が失敗しました。一旦Condition句を削除して動作させるようにしています。
リソースポリシーの再アタッチ
AWS CLIの”aws secretsmanager put-resource-policy ”を利用し、SecretsManagerのシークレット情報にリソースポリシーを再アタッチします。
aws secretsmanager put-resource-policy --secret-id arn:aws:secretsmanager:ap-northeast-1:445629031529:secret:Prod/System-A/RDS/testuser-6l08Sp --resource-policy file://policy.json
ローテーションの確認
マネージメントコンソールの「すぐにシークレットを更新」か、AWS CLIの"aws secrets manager rotate-secret"を利用しシークレットの更新を行います。
(参考)ローテーション用のLambda関数の作成
ローテーション用のLambda関数を自作することもできます。自作する場合、下記にサンプルのローテーション関数があるのでこちらを参考にするのが良いと思います。