CLIによる「KMS」構築


この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。

皆様こんにちは。
今回はCLIを利用して高可用性アーキテクトの構築をしていきます。
この記事ではKMSで暗号化鍵の作成を行います。
このブログはCLIによる暗号化鍵の作成をする上での知識を記事としてまとめ再確認し、皆様と共有するため作成します。

1.高可用性アーキテクト構築目次

目次はこちら

2.KMSとは

AWS Key Management Service (AWS KMS) は、データの保護に使用される暗号化キーの作成と制御を容易にするマネージドサービスです。AWS KMS はハードウェアセキュリティモジュール (HSM) を使用して AWS KMS keys を保護し、FIPS 140-2 暗号化モジュール検証プログラムで検証します。
引用:AWS Key Management Service

カスタマーマネージドキー(CMK)

私たち(ユーザーサイド)が作成、管理するキーです。
AWS Management Console のカスタマーマネージドキーページに表示されます。

AWS マネージドキー

AWS側でユーザーに代わって作成、管理、使用する、アカウントの KMS キーです。
AWS Management Console の AWS マネージドキー ページに表示されます。

AWS 所有のキー

AWS 所有のキー は、AWS のサービスが複数の AWS アカウント で使用するために所有および管理するキーであり、ユーザーが触れることはありません。

類似サービスにはマネージド型ハードウェアセキュリティモジュール の「AWS CloudHSM」があげられます。

今回はEBS,EFS,RDSの3つのAWSリソースの暗号化をしたいためカスタマーマネージドキーを作成します。

3.フロー図

file
KMSでCMKを作成し、それを利用してEBS,EFS,RDSの3つのAWSリソースのデータの暗号化をします。
CDK(Customer Data key)の作成と暗号化は作成したCMKをAWSリソースにアタッチ後、自動的に行われます。

4.KMSで暗号化鍵の生成

まず暗号化鍵に使用するキーポリシーをjson形式で以下のように自前に作成します。

ファイル名:keypolicy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[アカウントID]:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },
        {
            "Sid": "Allow access for Key Administrators",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[アカウントID]:user/[IAMユーザー]"
            },
            "Action": [
                "kms:Create*",
                "kms:Describe*",
                "kms:Enable*",
                "kms:List*",
                "kms:Put*",
                "kms:Update*",
                "kms:Revoke*",
                "kms:Disable*",
                "kms:Get*",
                "kms:Delete*",
                "kms:TagResource",
                "kms:UntagResource",
                "kms:ScheduleKeyDeletion",
                "kms:CancelKeyDeletion"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow use of the key",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[アカウントID]:user/[IAMユーザー]"
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
            ],
            "Resource": "*"
        },
        {
            "Sid": "Allow attachment of persistent resources",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[アカウントID]:user/[IAMユーザー]"
            },
            "Action": [
                "kms:CreateGrant",
                "kms:ListGrants",
                "kms:RevokeGrant"
            ],
            "Resource": "*",
            "Condition": {
                "Bool": {
                    "kms:GrantIsForAWSResource": "true"
                }
            }
        }
    ]
}

ポリシーの作成は公式ドキュメントを参考にしました。
Resourceが "*"を指定している理由としては、

キーポリシーでは、Resource 要素の値が "" になります。これは「この KMS キー」を意味します。アスタリスク ("") は、キーポリシーがアタッチされた KMS キーを識別します。
引用:キーポリシー内の要素

とのことですので"*"を指定しています。

ステートメントごとに内容を見ていきましょう。

まずこのステートメントではrootユーザに対し、KMSに関する全ての権限を付与しています。
KMS キーへのアクセスを 1 人のユーザーだけに付与するキーポリシーを作成し、その後そのユーザーを削除すると、キーは管理不能になってしまい、それを防ぐためこの設定をしています。

 {
            "Sid": "Enable IAM User Permissions",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[アカウントID]:root"
            },
            "Action": "kms:*",
            "Resource": "*"
        },

このステートメントは指定のユーザにKMSキーを管理する権限を付与しています。
キーの作成、一覧、削除、削除スケジュールの無効化、有効化、無効化などです。
今回の場合、特定のユーザーとは私のIAMユーザーです。

 {
            "Sid": "Allow access for Key Administrators",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[アカウントID]:user/[IAMユーザー]"
            },
            "Action": [
                "kms:Create*",
                "kms:Describe*",
                "kms:Enable*",
                "kms:List*",
                "kms:Put*",
                "kms:Update*",
                "kms:Revoke*",
                "kms:Disable*",
                "kms:Get*",
                "kms:Delete*",
                "kms:TagResource",
                "kms:UntagResource",
                "kms:ScheduleKeyDeletion",
                "kms:CancelKeyDeletion"
            ],
            "Resource": "*"
        },

このステートメントは指定のユーザにKMSキーを使用する権限を付与しています。
キーを使ったAWSリソースのデータの暗号化や復号のことです。
今回の場合、特定のユーザーとは私のIAMユーザーです。

 {
            "Sid": "Allow use of the key",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[アカウントID]:user/[IAMユーザー]"
            },
            "Action": [
                "kms:Encrypt",
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
            ],
            "Resource": "*"
        },

このステートメントはAWSリソースがKMSキーを使用する権限を付与しています。
kms:GrantIsForAWSResourceをtrueに設定することにより、
AWSリソースがユーザーに代わって権限を作成し、AWSリソースが KMSキーを使用してユーザーのデータを暗号化するようにしています。

 {
            "Sid": "Allow attachment of persistent resources",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::[アカウントID]:user/[IAMユーザー]"
            },
            "Action": [
                "kms:CreateGrant",
                "kms:ListGrants",
                "kms:RevokeGrant"
            ],
            "Resource": "*",
            "Condition": {
                "Bool": {
                    "kms:GrantIsForAWSResource": "true"
                }
            }
        }
    ]
}

次に、KMSで暗号化鍵を生成するために、[aws kms create-key]コマンドを使用します。

使用するオプション 設定値 説明
--policy file://C:\policies\keypolicy.json 使用するkeypolicy.jsonのパスを指定
--tags TagKey=Name,TagValue=umemoto_KMS 暗号化鍵にネームタグを設定

入力

aws kms create-key `
    --policy file://C:\policies\keypolicy.json `
    --tags TagKey=Name,TagValue=umemoto_KMS

出力

{
    "KeyMetadata": {
        "AWSAccountId": "xxxxx",
        "KeyId": "xxxxx-xxxx-xxxx-xxxx-xxxxx",
        "Arn": "arn:aws:kms:ap-northeast-2:xxxxx:key/xxxxx-xxxx-xxxx-xxxx-xxxxx",
        "CreationDate": "2022-05-06T15:31:42.181000+09:00",
        "Enabled": true,
        "Description": "",
        "KeyUsage": "ENCRYPT_DECRYPT",
        "KeyState": "Enabled",
        "Origin": "AWS_KMS",
        "KeyManager": "CUSTOMER",
        "CustomerMasterKeySpec": "SYMMETRIC_DEFAULT",
        "KeySpec": "SYMMETRIC_DEFAULT",
        "EncryptionAlgorithms": [
            "SYMMETRIC_DEFAULT"
        ],
        "MultiRegion": false
    }
}

次に生成した暗号化鍵にエイリアスを設定します。

エイリアスは、AWS KMS key のわかりやすい名前です。例えば、エイリアスを使用すると、1234abcd-12ab-34cd-56ef-1234567890ab の代わりに KMS キーを test-key として参照できます。公式ドキュメント

次に生成した暗号化鍵にエイリアスを設定するため、[aws kms create-alias]コマンドを使用します。

使用するオプション 設定値 説明
--alias-name alias/umemoto_KMS 設定したいエイリアスネームを入力
--target-key-id xxxx-xxxx-xxxx-xxx-xxxxxx 先ほど生成した暗号化鍵のIDを入力

入力

aws kms create-alias --alias-name alias/umemoto_KMS --target-key-id xxxx-xxxx-xxxx-xxx-xxxxxx

出力なし

最後にエイリアスが設定できたかを確認するため、[aws kms list-aliases]コマンドを使用します。

使用するオプション 設定値 説明
--key-id xxxx-xxxx-xxxx-xxx-xxxxxx 先ほど生成した暗号化鍵のIDを入力

入力

aws kms list-aliases --key-id xxxx-xxxx-xxxx-xxx-xxxxxx

出力

{
    "Aliases": [
        {
            "AliasName": "alias/umemoto_KMS",
            "AliasArn": "arn:aws:kms:ap-northeast-2:xxxxx:alias/umemoto_KMS",
            "TargetKeyId": "xxxx-xxxx-xxxx-xxx-xxxxxx",
            "CreationDate": "2022-05-06T15:33:09.587000+09:00",
            "LastUpdatedDate": "2022-05-06T15:33:09.587000+09:00"
        }
    ]
}

エイリアスの確認ができました。

これで暗号化鍵の作成を完了しました。

5.感想

キーポリシーを理解するのが少し大変でしたが、良い経験になりました。
次回も公式ドキュメントをしっかりと読みながら進めていきたいと思います。

6.参照

AWS CLI Command Reference – kms
https://awscli.amazonaws.com/v2/documentation/api/latest/reference/kms/index.html

Last modified: 2022-06-09

Author