CloudTrailでログの暗号化を簡単に設定する方法考えてみた

セキュリティ要件によりCloudTrailで記録する証跡を暗号化する場合があります。この設定にはS3やKMSも絡み複雑で適切に設定することが難しいです。操作をAWSマネジメントコンソールに寄せてなるべく簡単に設定する方法を紹介します。
2018.04.28

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

こんにちは、臼田です。

CloudTrailはAWS上での操作(APIコール等)の証跡を管理するサービスで、AWSを利用する場合には全ての環境で有効にするべきものです。

ただ有効にするだけなら比較的簡単に設定することが可能ですが、ログの暗号化設定は少し複雑で設定しづらいです。

すべての環境でログの暗号化が必須ではありませんが、セキュリティ要件が高い場合に必要になります。

今回は、なるべく簡単にCloudTrailのログの暗号化設定を行う方法を考えたので共有します。

暗号化設定が複雑なワケ

ログの暗号化は次のような関係で行われています。

CloudTrailは、ログを暗号化するためにKMSで鍵を利用します。鍵を利用するには鍵に設定されているキーポリシーでCloudTrailからの利用を許可する必要があります。

一方で、保存先のS3のバケットでも同じくバケットポリシーが設定されているため、こちらもCloudTrailからのアクセスを許可する必要があります。

各ポリシーはJSON形式で記述されており、うっかり設定を間違えてしまうと大変なことになります。なるべくなら直接触りたくないです。

簡単に設定する方法

AWSマネジメントコンソールからCloudTrailの設定を行う時に、KMSの鍵やS3のバケットを一緒に作成すると、キーポリシーやバケットポリシーを自動的に設定してくれます!すごくありがたい。

というわけで実際にやってみます。

CloudTrailの画面から証跡情報を開き、鍵やバケットを作成したいリージョンになっていることを確認してから「証跡の作成」を押します。全リージョンの証跡について表示されていますが、証跡の作成は右上で選択しているリージョンに作成されます。鍵やバケットも同様にこのリージョンで作成されます。

証跡名は任意のものを入れ、全リージョン取得するか選択し、管理イベント・データイベントそれぞれをどのように取得するか選択します。

全リージョン取得する場合のメリットは1つのバケットで一括してログを管理することにより、管理や分析が楽になることですが、デメリットとしてリージョン間の転送により費用がかかります。作成したリージョン外からのログ転送が多くなりそうな場合には、リージョン毎での証跡作成が推奨です。

管理イベントは基本的にすべて取得することになりますが、データイベントは要件次第です。

S3ではオブジェクトレベルのAPI操作(GetObjectやPutObject等)は管理イベントでは取得されないので、オブジェクトレベルの細かい操作の証跡を取りたい場合有効にします。

LambdaについてはInvoke APIについて記録されるようになります。

これらの操作は一般的に膨大な量のログが出力されるため、必要に応じて設定しましょう。データイベントの詳細はこちら

次にストレージの場所にて「新しいS3バケットを作成しますか」で「はい」を選択し、適切なバケット名を入力した後「詳細」を押して展開します。

「ログファイルを暗号化しますか」で「はい」、「新規のKMSキーの作成」で「はい」を選択してキーのエイリアスを設定します。

右下の「作成」を押して作成完了です。合わせてKMSの鍵とS3のバケットが作成されます。

キーポリシーは下記のようになっています。

{
  "Version": "2012-10-17",
  "Id": "Key policy created by CloudTrail",
  "Statement": [
    {
      "Sid": "Enable IAM User Permissions",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::000000000000:user/user_name",
          "arn:aws:iam::000000000000:root"
        ]
      },
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "Allow CloudTrail to encrypt logs",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Action": "kms:GenerateDataKey*",
      "Resource": "*",
      "Condition": {
        "StringLike": {
          "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:000000000000:trail/*"
        }
      }
    },
    {
      "Sid": "Allow CloudTrail to describe key",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudtrail.amazonaws.com"
      },
      "Action": "kms:DescribeKey",
      "Resource": "*"
    },
    {
      "Sid": "Allow principals in the account to decrypt log files",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "kms:Decrypt",
        "kms:ReEncryptFrom"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "kms:CallerAccount": "000000000000"
        },
        "StringLike": {
          "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:000000000000:trail/*"
        }
      }
    },
    {
      "Sid": "Allow alias creation during setup",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": "kms:CreateAlias",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "kms:ViaService": "ec2.ap-northeast-1.amazonaws.com",
          "kms:CallerAccount": "000000000000"
        }
      }
    },
    {
      "Sid": "Enable cross account log decryption",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "kms:Decrypt",
        "kms:ReEncryptFrom"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "kms:CallerAccount": "000000000000"
        },
        "StringLike": {
          "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:000000000000:trail/*"
        }
      }
    }
  ]
}

バケットポリシーは下記のようになっています。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWSCloudTrailAclCheck20150319",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::cloudtrail-logs-all"
        },
        {
            "Sid": "AWSCloudTrailWrite20150319",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::cloudtrail-logs-all/AWSLogs/000000000000/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        }
    ]
}

これを見ると、それぞれ個別に設定することはあまりやりたくないと感じるかと思います。

まとめ

なるべく簡単にCloudTrailの暗号化を設定する方法について紹介しました。

マネジメントコンソールから操作することにより、自動的にサービスの利用に必要な権限を割り当ててくれる事は他の部分でも多いので、積極的に活用して、設定ミス無く楽に利用しましょう。