RedshiftからのS3オブジェクトアクセスをCloudTrailでロギングしてみる
はじめに
好物はインフラとフロントエンドのかじわらゆたかです。 虎塚のエントリーでS3のオブジェクトアクセスをCloudTrailでロギングできる用になったとのことです。 【新機能】CloudTrailでS3オブジェクトレベルのアクセスをロギングする | Developers.IO
この機能を用いることでRedshiftでCopy/Unloadを実行したIAM Roleの情報も習得できるのではと思い、 確認してみました。
下準備
上記の記事はAWS CLIを用いて作成していましたが、Management Consoleからでも作成・設定することが可能です。 今回の例ではManagement Consoleから作成・設定をしております。
Management Consoleより、CloudTrailを選択し、TrailsからAdd new trailを押下し、Trailの作成を行います。 その際に注意点としては、監視対象のバケットのRegionとTrailのRegionをあわせておく必要があります。 異なるRegionのバケットを監視対象にすることはできるのですが、その場合ロギング対象のイベントが全く取れないと言った挙動となるので注意が必要です。 なお、Regionの指定はTrail作成時に行うのではなく、Management Consoleの右上から変更する必要があります。
Create Trailの画面では、Trail名を指定し、ロギング結果を格納するS3 Bucketを指定します。 格納結果のバケットはこの画面から作成することも可能です。 Create を押下すると一覧に作成したTrailが表示されます。
一覧から作成したTrailを選択し、設定を行なっていきます。
まずTrailのInclude global serviceをNoにしておきます。 これは、Management Consoleの操作ログ等の情報をこのTrailの監視対象外にするためです。
次に、Event Selectorsで監視対象としたいS3バケットとprefixを指定します。 今回の例では、Bucketそのものを監視対象としました。
ここで先ほども書いた内容の注意が必要です。 RedshiftへCopyを行う際にはRedshiftと異なるRegionのS3を指定することが可能なため、Trailと監視対象のS3が同一であれば問題ないのですが、 Unloadの場合は、Redshiftと同一Regiondである必要があります。 上記でも書いた通りTrailも同じリージョンである必要があるため、Unloadを行うS3の監視を行う際には、 Redshift/CloudTrail/S3 のリージョンが共通である必要があります。
もう一点、これは要確認なのですが、Event Selectorの選択として、Read/Write eventをAllにしておく必要がありました。 この設定をしないとRedshift からのIAM Roleを用いてのアクセスのロギングが行なえませんでした。
RedshiftからのS3オブジェクトのアクセスをロギングしてみる
実際にRedshiftからCopyコマンド・Unloadコマンドを実行し、ロギングされたかを確認してみます。 今回はredshift-trailcheck-roleというRoleをRedshiftに付与し、Copy Unload時は当該のRoleを用いて実行しました。
UNLOAD ('SELECT * FROM 顧客情報') to 's3://cm-kajiwara-redshift-unload-us-standard/trailtest_1201_2000.tsv' CREDENTIALS 'aws_iam_role=arn:aws:iam::123456789012:role/redshift-trailcheck-role'; COPY 顧客情報 FROM 's3://cm-kajiwara-redshift-load/customer0.tsv' CREDENTIALS 'aws_iam_role=arn:aws:iam::123456789012:role/redshift-trailcheck-role' DELIMITER AS '\t' TIMEFORMAT AS 'auto' region AS 'ap-northeast-1';
現状、Event selectorsで設定したロギング情報はS3に配置される情報を参照するしかできないため、S3からログを確認してみます。
Unload
{ "eventVersion": "1.05", "userIdentity": { "type": "AssumedRole", "principalId": "AROAJRURSPCMQFU46CCAC:RedshiftIamRoleSession", "arn": "arn:aws:sts::123456789012:assumed-role/redshift-trailcheck-role/RedshiftIamRoleSession", "accountId": "123456789012", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROAJRURSPCMQFU46CCAC", "arn": "arn:aws:iam::123456789012:role/redshift-trailcheck-role", "accountId": "123456789012", "userName": "redshift-trailcheck-role" }, "attributes": { "creationDate": "2016-12-01T11:01:21Z", "mfaAuthenticated": "false" } } }, "eventTime": "2016-12-01T11:01:21Z", "eventSource": "s3.amazonaws.com", "eventName": "CreateMultipartUpload", "awsRegion": "us-east-1", "sourceIPAddress": "52.3.56.32", "userAgent": "[]", "requestParameters": { "bucketName": "cm-kajiwara-redshift-unload-us-standard", "x-amz-server-side-encryption": "AES256", "key": "trailtest_1201_2000.tsv0000_part_00", "uploads": "" }, "responseElements": { "x-amz-server-side-encryption": "AES256" }, "additionalEventData": { "x-amz-id-2": "BReVu53V5+7GpB8h4x3KS83OkijeJzOcMHC5JpUi5+rn4NDG/B0YzsbaWF8JdlZhx1q+kePFf6c=" }, "requestID": "B83764D2B10528F3", "eventID": "eed98bfa-3c1b-4424-b104-5d45a7745ffb", "readOnly": false, "resources": [{ "type": "AWS::S3::Object", "ARN": "arn:aws:s3:::cm-kajiwara-redshift-unload-us-standard/trailtest_1201_2000.tsv0000_part_00" }, { "accountId": "123456789012", "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::cm-kajiwara-redshift-unload-us-standard" }], "eventType": "AwsApiCall", "recipientAccountId": "123456789012" }, (省略) { "eventVersion": "1.05", "userIdentity": { "type": "AssumedRole", "principalId": "AROAJRURSPCMQFU46CCAC:RedshiftIamRoleSession", "arn": "arn:aws:sts::123456789012:assumed-role/redshift-trailcheck-role/RedshiftIamRoleSession", "accountId": "123456789012", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROAJRURSPCMQFU46CCAC", "arn": "arn:aws:iam::123456789012:role/redshift-trailcheck-role", "accountId": "123456789012", "userName": "redshift-trailcheck-role" }, "attributes": { "creationDate": "2016-12-01T11:01:21Z", "mfaAuthenticated": "false" } } }, "eventTime": "2016-12-01T11:01:21Z", "eventSource": "s3.amazonaws.com", "eventName": "UploadPart", "awsRegion": "us-east-1", "sourceIPAddress": "52.3.56.32", "userAgent": "[]", "requestParameters": { "bucketName": "cm-kajiwara-redshift-unload-us-standard", "partNumber": "1", "uploadId": "kxPGRhJsyv9FAmPKLuvnW2Jt5R3iFYgDhK2pma3chb2F.oMUTapwpJ3sfdsQv3EzJnOnInidWPGvGAqpi978NN.rn74giCLCS1TOND3vUHQ941dVNkdGF2LJZQQJGqeM5ORj.iIQGRD5dH25RIMaWg--", "key": "trailtest_1201_2000.tsv0000_part_00" }, "responseElements": { "x-amz-server-side-encryption": "AES256" }, "additionalEventData": { "x-amz-id-2": "CLZKQaIhwCt5kkhc6QhF2nVYIlNeos9gUkzBfJrF2Z+RJ8Ui4rzeKpjaFJBvhXefIwQhO1euiHc=" }, "requestID": "32C1AF777E23C7BB", "eventID": "a9c277c2-00ba-4766-b7dd-423da266cde9", "readOnly": false, "resources": [{ "type": "AWS::S3::Object", "ARN": "arn:aws:s3:::cm-kajiwara-redshift-unload-us-standard/trailtest_1201_2000.tsv0000_part_00" }, { "accountId": "123456789012", "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::cm-kajiwara-redshift-unload-us-standard" }], "eventType": "AwsApiCall", "recipientAccountId": "123456789012" }, (省略) { "eventVersion": "1.05", "userIdentity": { "type": "AssumedRole", "principalId": "AROAJRURSPCMQFU46CCAC:RedshiftIamRoleSession", "arn": "arn:aws:sts::123456789012:assumed-role/redshift-trailcheck-role/RedshiftIamRoleSession", "accountId": "123456789012", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROAJRURSPCMQFU46CCAC", "arn": "arn:aws:iam::123456789012:role/redshift-trailcheck-role", "accountId": "123456789012", "userName": "redshift-trailcheck-role" }, "attributes": { "creationDate": "2016-12-01T11:01:21Z", "mfaAuthenticated": "false" } } }, "eventTime": "2016-12-01T11:01:21Z", "eventSource": "s3.amazonaws.com", "eventName": "CompleteMultipartUpload", "awsRegion": "us-east-1", "sourceIPAddress": "52.3.56.32", "userAgent": "[]", "requestParameters": { "bucketName": "cm-kajiwara-redshift-unload-us-standard", "uploadId": "kxPGRhJsyv9FAmPKLuvnW2Jt5R3iFYgDhK2pma3chb2F.oMUTapwpJ3sfdsQv3EzJnOnInidWPGvGAqpi978NN.rn74giCLCS1TOND3vUHQ941dVNkdGF2LJZQQJGqeM5ORj.iIQGRD5dH25RIMaWg--", "key": "trailtest_1201_2000.tsv0000_part_00", "CompleteMultipartUpload": { "Part": { "PartNumber": 1.0, "ETag": "5935c2d29748e69f3318413648afc264" } } }, "responseElements": { "x-amz-server-side-encryption": "AES256" }, "additionalEventData": { "x-amz-id-2": "u7fGoJiav29yZXuZoPZNzet37J6SJCXJ2dbweKFG7yVAH2KgrY+2RZtLD3fvCDPgd+PUHzDgDO8=" }, "requestID": "4656C486D6214D08", "eventID": "999dc6b6-5669-45bd-8066-e2d94d61c9a8", "readOnly": false, "resources": [{ "type": "AWS::S3::Object", "ARN": "arn:aws:s3:::cm-kajiwara-redshift-unload-us-standard/trailtest_1201_2000.tsv0000_part_00" }, { "accountId": "123456789012", "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::cm-kajiwara-redshift-unload-us-standard" }], "eventType": "AwsApiCall", "recipientAccountId": "123456789012" },
Unload時にはCreateMultipartUpload 〜 UploadPart 〜 CompleteMultipartUpload で配置していることがわかります。
COPY
{ "eventVersion": "1.05", "userIdentity": { "type": "AssumedRole", "principalId": "AROAJRURSPCMQFU46CCAC:RedshiftIamRoleSession", "arn": "arn:aws:sts::123456789012:assumed-role/redshift-trailcheck-role/RedshiftIamRoleSession", "accountId": "123456789012", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROAJRURSPCMQFU46CCAC", "arn": "arn:aws:iam::123456789012:role/redshift-trailcheck-role", "accountId": "123456789012", "userName": "redshift-trailcheck-role" }, "attributes": { "creationDate": "2016-12-01T11:01:28Z", "mfaAuthenticated": "false" } } }, "eventTime": "2016-12-01T11:01:29Z", "eventSource": "s3.amazonaws.com", "eventName": "ListObjects", "awsRegion": "ap-northeast-1", "sourceIPAddress": "52.55.154.215", "userAgent": "[]", "requestParameters": { "bucketName": "cm-kajiwara-redshift-load", "max-keys": "1000", "prefix": "customer0.tsv", "marker": "" }, "responseElements": {}, "additionalEventData": { "x-amz-id-2": "LW1oQvsqqL2pqfqjDr/lDa1ESS8TkkyrtBTvIQ0u8+kElUu7Pd7sZUuZO6KP9snZM5UoNkE1zdI=" }, "requestID": "0A96DFEF54236788", "eventID": "b5bbfbf7-51a6-4adf-b58f-6176da8bd706", "readOnly": true, "resources": [{ "type": "AWS::S3::Object", "ARNPrefix": "arn:aws:s3:::cm-kajiwara-redshift-load/customer0.tsv" }, { "accountId": "123456789012", "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::cm-kajiwara-redshift-load" }], "eventType": "AwsApiCall", "recipientAccountId": "123456789012" }, { "eventVersion": "1.05", "userIdentity": { "type": "AssumedRole", "principalId": "AROAJRURSPCMQFU46CCAC:RedshiftIamRoleSession", "arn": "arn:aws:sts::123456789012:assumed-role/redshift-trailcheck-role/RedshiftIamRoleSession", "accountId": "123456789012", "sessionContext": { "sessionIssuer": { "type": "Role", "principalId": "AROAJRURSPCMQFU46CCAC", "arn": "arn:aws:iam::123456789012:role/redshift-trailcheck-role", "accountId": "123456789012", "userName": "redshift-trailcheck-role" }, "attributes": { "creationDate": "2016-12-01T11:01:30Z", "mfaAuthenticated": "false" } } }, "eventTime": "2016-12-01T11:01:30Z", "eventSource": "s3.amazonaws.com", "eventName": "GetObject", "awsRegion": "ap-northeast-1", "sourceIPAddress": "52.3.56.32", "userAgent": "[]", "requestParameters": { "bucketName": "cm-kajiwara-redshift-load", "key": "customer0.tsv" }, "responseElements": {}, "additionalEventData": { "x-amz-id-2": "2m/yH+VXN9AZ0NKKo30FfnTTz/n9sd2EYHAWsB3BGAwc34ghAGlj10aDofP+RGM4nDfL49BGyvk=" }, "requestID": "F3E01F2B37207FC9", "eventID": "0734353a-f798-408b-b7c9-dead8e31429f", "readOnly": true, "resources": [{ "type": "AWS::S3::Object", "ARN": "arn:aws:s3:::cm-kajiwara-redshift-load/customer0.tsv" }, { "accountId": "123456789012", "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::cm-kajiwara-redshift-load" }], "eventType": "AwsApiCall", "recipientAccountId": "123456789012" }
また、sessionIssuerをみるとRoleで動いていることもわかります。
まとめ
RedshiftからのS3操作のロギングも行えることがわかりました。 今まではRedshiftのManagement ConsoleではどのCredentialを用いてS3にアクセスしたかわかりませんでしが、 これを用いることで、どのIAM User/IAM Roleを用いてアクセスしたかも調べることができます。