S3 MFA Delete を有効にして CloudTrail ログを保護する

Posted on

CloudTrail の FAQ には、セキュリティについて次のように書かれています。

Q: CloudTrail ログファイルを保護するにはどうすればよいですか?

デフォルトでは、CloudTrail ログファイルは S3 Server Side Encryption(SSE)を使用して暗号化され、S3 バケットに保存されます。 IAM または S3 バケットのポリシーを使用してログファイルへのアクセスを制御できます。さらにセキュリティを追加するには、S3 バケットで S3 Multi Factor Authentication(MFA)Delete を有効にします。

最小権限の原則に従ってバケットポリシーを設定するのはもちろんのことですが、改ざんやうっかりミスによる削除から CloudTrail ログを保護するために S3 MFA Delete を設定したいと思います。

S3 MFA Delete とは

S3 MFA Delete とは、S3 のバージョニング機能のオプションです。このオプションを有効にすると、オブジェクトのバージョンを削除するときに AWS アカウントの MFA デバイスに表示される 6 桁のコード入力が必須になります。

S3 MFA Delete を設定するためには AWS アカウント(ルートアカウント)に 2 段階認証を設定している必要があります。 MFA デバイスはソフトウェア / ハードウェアを問いません。

設定できるのは AWS アカウントだけで、IAM ユーザーでは設定できません(フル権限を持っていてもダメ)。また Management Console では設定できないので、AWS アカウントのアクセスキーを使って AWS CLI や API で設定します。

設定方法

設定する際に必要になる MFA デバイスのシリアル番号を調べます。 AWS アカウントでログインして、セキュリティ認証情報のページで確認できます。

MFA デバイスのシリアル番号

シリアル番号は arn:aws:iam::(アカウント ID):mfa/root-account-mfa-device という形式です。

今回は AWS CLI で設定します。まずは AWS アカウントの認証情報を環境変数にセットします。繰り返しになりますが IAM ユーザーでは設定できません。

$ export AWS_DEFAULT_REGION=ap-northeast-1
$ export AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXX
$ export AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

バケットにバージョニングと MFA Delete を設定します。バケット名と MFA デバイスのシリアル番号は読み替えてください。 --mfa オプションは (シリアル番号)(スペース)(6 桁のコード) です。

$ aws s3api put-bucket-versioning \
--bucket cloudtrail-XXXXXXXXXXXX \
--versioning-configuration MFADelete=Enabled,Status=Enabled \
--mfa "arn:aws:iam::XXXXXXXXXXXX:mfa/root-account-mfa-device (6 桁のコード)"

有効になったか確認してみます。

$ aws s3api get-bucket-versioning --bucket cloudtrail-XXXXXXXXXXXX
{
    "Status": "Enabled",
    "MFADelete": "Enabled"
}

削除できるか試してみる

有効になったので試しに CloudTrail ログを削除してみます。先ほどの環境変数を unset して、IAM ユーザーで AWS CLI を実行します。 S3 のパスは読み替えてください。

$ unset AWS_DEFAULT_REGION AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY

$ aws s3 rm s3://cloudtrail-XXXXXXXXXXXX/path/to/XXXXXXXXXXXX.json.gz
delete: s3://cloudtrail-XXXXXXXXXXXX/path/to/XXXXXXXXXXXX.json.gz

自分もやってみてわかったのですが、このコマンドはエラーにならずに成功します。というのも、S3 MFA Delete を設定したバケットはバージョニング機能が有効になっているので、削除してもマーカーが付くだけで実体は残っています。完全に削除するにはバージョン ID を指定する必要があります。先ほど削除したファイルのバージョン ID を調べます。

$ aws s3api list-object-versions \
--bucket cloudtrail-XXXXXXXXXXXX \
--prefix path/to/XXXXXXXXXXXX.json.gz \
--query "DeleteMarkers[].VersionId"
[
    "Hp27mCX2q0ffmDR0reQ8XXXXXXXXXXXX"
]

バージョン ID を指定してもう一度削除してみます。

$ aws s3api delete-object \
--bucket cloudtrail-XXXXXXXXXXXX \
--key path/to/XXXXXXXXXXXX.json.gz \
--version-id Hp27mCX2q0ffmDR0reQ8XXXXXXXXXXXX
A client error (AccessDenied) occurred when calling the DeleteObject operation: Mfa Authentication must be used for this request

意図したとおり削除できずエラーになりました。もちろん Management Console から削除してもエラーになります。

まとめ

設定がちょっと面倒ですが、一度だけの作業なので CloudTrail の設定とあわせてやるといいと思います。 CloudTrail ログはいざという時に重要になってくるので、S3 MFA Delete を設定してちゃんと保護しましょう。