
CloudWatch LogsのログデータをKMSで暗号化する
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
Amazon CloudWatch Logs は、PCI および FedRamp に準拠しており、データはデフォルトで保管時も転送中も暗号化されます。
コンプライアンスとセキュリティを強化するために、AWS KMS 暗号化を使用してログのグループを暗号化する方法を紹介します。
ポイント
- CloudWatch Logsはデフォルトで暗号化されている
- コンプライアンス、セキュリティ強化のために、AWS KMS CMKで暗号化することも可能
- CloudWatch LogsにCMKの暗号・復号を許可
- KMS暗号を有効にして取り込まれたデータだけが暗号化される。
- CMKの許可を取りやめたり、CMKを削除すると、暗号化済みデータを復号できなくなる
AWS KMS CKMの作成
AWSマネージドキーではCloudWatch Logsを暗号化できません。
CMKを作成し、CloudWatch Logsがその鍵で暗号・復号できるように許可します。
- 新規鍵を作成
- 既存の作成済み鍵を更新
の2パターンで手順を確認します。
ポリシー
AWS KMSの運用では
- 鍵の管理者
- 鍵の利用者
の2種類のポリシーが必要です。
CW Logsの暗号化では鍵の利用者向けポリシーが該当します。
このポリシーの Principal に "Service": "logs.AWS-REGION.amazonaws.com" を追加します。リージョンを含める必要がある点に注意ください。
以下のサンプルポリシーでは
- 鍵の管理者
- IAM ユーザー arn:aws:iam::123456789012:user/kms-admin
- 鍵の利用者
- IAMユーザー arn:aws:iam::123456789012:user/kms-user
- CloudWatch Logs "Service": "logs.ap-northeast-1.amazonaws.com"
となっています。
{
  "Version": "2012-10-17",
  "Id": "clouwatch-logs-kms-policy",
  "Statement": [
    {
      "Sid": "Enable IAM User Permissions",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "Allow access for Key Administrators",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:user/kms-admin"
      },
      "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::123456789012:user/kms-user"
        ],
        "Service": "logs.ap-northeast-1.amazonaws.com"
      },
      "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::123456789012:user/kms-user"
        ]
      },
      "Action": [
        "kms:CreateGrant",
        "kms:ListGrants",
        "kms:RevokeGrant"
      ],
      "Resource": "*",
      "Condition": {
        "Bool": {
          "kms:GrantIsForAWSResource": "true"
        }
      }
    }
  ]
}
AWS KMS CMKの作成
管理コンソールから作成する場合、鍵を作成後、ポリシーの Principal を修正してください。
AWS CLI経由で作成する場合、以下の様になります。
# 鍵の作成
$ aws kms create-key \
  --description 'kms key for CW Logs' \
  --policy file://policy.json  # 先程作成したポリシー
{
    "KeyMetadata": {
        "AWSAccountId": "123456789012",
        "KeyId": "f1221273-b490-4492-991a-fb2a23b8e62a",
        "Arn": "arn:aws:kms:eu-central-1:123456789012:key/f1221273-b490-4492-991a-fb2a23b8e62a",
        "CreationDate": 1545239736.178,
        "Enabled": true,
        "Description": "kms key for CW Logs",
        "KeyUsage": "ENCRYPT_DECRYPT",
        "KeyState": "Enabled",
        "Origin": "AWS_KMS",
        "KeyManager": "CUSTOMER"
    }
}
# エイリアスの設定
$ aws kms create-alias \
  --alias-name alias/cmk-for-cwlogs \
  --target-key-id arn:aws:kms:eu-central-1:123456789012:key/f1221273-b490-4492-991a-fb2a23b8e62a
# CMKの確認
$ aws kms describe-key --key-id f1221273-b490-4492-991a-fb2a23b8e62a
{
    "KeyMetadata": {
        "AWSAccountId": "123456789012",
        "KeyId": "f1221273-b490-4492-991a-fb2a23b8e62a",
        "Arn": "arn:aws:kms:eu-central-1:123456789012:key/f1221273-b490-4492-991a-fb2a23b8e62a",
        "CreationDate": 1545239736.178,
        "Enabled": true,
        "Description": "kms key for CW Logs",
        "KeyUsage": "ENCRYPT_DECRYPT",
        "KeyState": "Enabled",
        "Origin": "AWS_KMS",
        "KeyManager": "CUSTOMER"
    }
}
CloudWatch Logsの暗号化
作成したAWS KMS CMKを利用してCloudWatch Logsを暗号化します。
この操作は管理コンソールからは行えません。AWS CLI/SDK から行います。
暗号化された新規ロググループを作成する場合
logs:create-log-group API を利用して、ロググループの作成とCMKの関連付けを同時に行います。
引数で
- ロググループ名
- CMKのARN
を指定します。
$ aws logs create-log-group \ --log-group-name foo \ --kms-key-id arn:aws:kms:eu-central-1:123456789012:key/f1221273-b490-4492-991a-fb2a23b8e62a
既存のロググループを暗号化する場合
logs:associate-kms-key API を利用してロググループとCMKの関連付けを行います。
引数で
- ロググループ名
- CMKのARN
を指定します。
$ aws logs associate-kms-key \ --log-group-name bar \ --kms-key-id arn:aws:kms:eu-central-1:123456789012:key/f1221273-b490-4492-991a-fb2a23b8e62a
ロググループの設定を確認
$ aws logs describe-log-groups --log-group-name-prefix bar
{
    "logGroups": [
        {
            "logGroupName": "bar",
            "creationTime": 1545258975724,
            "metricFilterCount": 0,
            "arn": "arn:aws:logs:eu-central-1:123456789012:log-group:bar:*",
            "storedBytes": 0,
            "kmsKeyId": "arn:aws:kms:eu-central-1:123456789012:key/f1221273-b490-4492-991a-fb2a23b8e62a"
        }
    ]
}
ロググループに kmsKeyId が設定されているのがわかります。
暗号を無効化する
logs:disassociate-kms-key API を利用します。
引数で
- ロググループ名
を指定します。
$ aws logs disassociate-kms-key \
  --log-group-name foo
$ aws logs describe-log-groups --log-group-name-prefix foo
{
    "logGroups": [
        {
            "logGroupName": "foo",
            "creationTime": 1545258975724,
            "metricFilterCount": 0,
            "arn": "arn:aws:logs:eu-central-1:123456789012:log-group:foo:*",
            "storedBytes": 0
        }
    ]
}
ロググループから kmsKeyId の設定が消えています。
CMKと過去の暗号済みデータとの関係を確認
CloudWatch Logsに関連付けられたCMKへアクセスできなくなると、CloudWatch Logs 内の暗号化されたデータを取得できなくなります。
具体的には、以下の様なケースが考えられます。
- CMKのポリシーが変更され、CloudWatch LogsがCMKを利用できなくなった
- CMKが削除された
一方で、CloudWatch LogsとCMKの関連付けが解除されても、CloudWatch Logsが暗号に利用したCMKにアクセスできる限りは、復号可能です。
この動作を確認してみましょう。
CloudWatch LogsとCMKの関係を解除してログにアクセス
関連付けを解除しただけでは、CMKを利用して暗号化したログにもアクセス可能です。
# 関連付けを解除
$ aws logs disassociate-kms-key \
  --log-group-name foo
# CW Logsにアクセス
$ aws logs get-log-events \
  --log-group-name test \
  --log-stream-name xxx
{
    "events": [
        {
            "timestamp": 1545240920366,
            "message": "...",
            "ingestionTime": 1545240920412
        }
    ],
    "nextForwardToken": "f/34460024035425115495930233232501593720702418250723426304",
    "nextBackwardToken": "b/34460024035425115495930233232501593720702418250723426304"
}
CMKのポリシーを変更
CMK利用者の Principal から CloudWatch Logs("Service": "logs.AWS-REGION.amazonaws.com") を除外します。
    ...
    {
      "Sid": "Allow use of the key",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::123456789012:user/kms-user"
        ]
      },
      "Action": [
        "kms:Encrypt",
        "kms:Decrypt",
        "kms:ReEncrypt*",
        "kms:GenerateDataKey*",
        "kms:DescribeKey"
      ],
      "Resource": "*"
    },
    ...
管理コンソールからイベントログを確認
この状態で暗号化したイベントログが含まれる CloudWatch Logsを確認します。
ログの代わりにエラーメッセージが表示されています。
CLI からイベントログを確認
$ aws logs get-log-events \ --log-group-name test \ --log-stream-name xxx An error occurred (InvalidParameterException) when calling the GetLogEvents operation: Unable to validate if specified KMS key is valid.
エラーが発生します。













