ablog

不器用で落着きのない技術者のメモ

Athena で CloudTrail から S3 イベントを集計する

クエリ

select eventname, count(1) cnt from cloudtrail_logs
where eventsource = 's3.amazonaws.com' 
group by eventname
order by cnt desc

実行結果

eventname count
ListObjects 263702
PutObject 200075
GetObject 134911
HeadObject 83034
UploadPartCopy 24569
HeadBucket 11849
CopyObject 2492
CreateMultipartUpload 1903
CompleteMultipartUpload 1870
DeleteObject 1855
GetBucketPublicAccessBlock 207
GetBucketAcl 204
ListBuckets 200
UploadPart 198
GetAccountPublicAccessBlock 194
GetBucketPolicyStatus 191
GetBucketEncryption 180
SelectObjectContent 137
GetBucketVersioning 33
REST.GET.OBJECT_LOCK_CONFIGURATION 21
GetBucketWebsite 19
GetBucketPolicy 18
ListObjectVersions 16
DeleteObjects 15
GetBucketTagging 15
GetObjectAcl 14
CreateBucket 13
GetBucketCors 13
GetBucketLocation 12
GetBucketLogging 9
GetBucketNotification 9
GetBucketLifecycle 9
GetBucketRequestPayment 9
GetBucketReplication 9
DeleteBucket 4
PutBucketPublicAccessBlock 2
PutBucketPolicy 1
PutBucketEncryption 1
GetObjectTagging 1

Amazon Redshift の監査ログの種類

デフォルトで Amazon Redshift の監査ログは設定したバケットに以下のパスで出力されるが、

AWSLogs/AccountID/ServiceName/Region/Year/Month/Day/
AccountID_ServiceName_Region_ClusterName_LogType_Timestamp.gz

LogType は connectionlog、useractivitylog、userlog の3種類ある。

以下は実際のログから LogType を集計した結果。

$ aws s3 ls --recursive redshift-trail-bucket|perl -F/ -lane 'if(/AWSLogs\//){@array=split(q/_/,$F[$#F]);print $array[4]}'|sort|uniq -c
    279 connectionlog
    308 useractivitylog
      1 userlog

参考

Amazon Redshift 監査ログ作成のバケットの構造
デフォルトでは、Amazon Redshift は Amazon S3 バケット内のログファイルの整理に以下のバケットおよびオブジェクト構造を使用します。AWSLogs/AccountID/ServiceName/Region/Year/Month/Day/
AccountID_ServiceName_Region_ClusterName_LogType_Timestamp.gz
例: AWSLogs/123456789012/redshift/us-east-1/2013/10/29/123456789012_redshift_us-east-1_mycluster_userlog_2013-10-29T18:01.gz

Amazon S3 のキープレフィックスを指定すると、キーの冒頭にプレフィックスが挿入されます。
たとえば、myprefix のプレフィックスを指定する場合。myprefix/AWSLogs/123456789012/redshift/us-east-1/2013/10/29/123456789012_redshift_us-east-1_mycluster_userlog_2013-10-29T18:01.gz

Amazon S3 のキープレフィックスは 512 文字を超えることはできません。スペース ( )、二重引用符 (“)、一重引用符 (‘)、バックスラッシュ (\) を含めることはできません。また、許可されない特殊文字、および制御文字もいくつかあります。これらの文字の 16 進コードは次のとおりです。

  • x00 から x20
  • x 22
  • x 27
  • x5c
  • x7f 以上
データベース監査ログ作成 - Amazon Redshift

S3 のアクセスログのオペレーションを集計する

ちょっとした量のS3 のアクセスログのオペレーションを集計する。

$ aws s3 cp --recursive s3://s3-accesslog-az/ ./
  • オペレーションで集計する。
$ find . -type f -print0|xargs -0 -I{} perl -lane 'print $F[7]' {}|sort|uniq -c
    145 REST.GET.ACCELERATE
  20105 REST.GET.ACL
 143117 REST.GET.BUCKET
    178 REST.GET.BUCKETPOLICY
      1 REST.GET.BUCKETVERSIONS
    146 REST.GET.CORS
    104 REST.GET.ENCRYPTION
    145 REST.GET.LIFECYCLE
    144 REST.GET.LOCATION
    147 REST.GET.LOGGING_STATUS
    145 REST.GET.NOTIFICATION
 138823 REST.GET.OBJECT
    145 REST.GET.REPLICATION
    145 REST.GET.REQUEST_PAYMENT
    145 REST.GET.TAGGING
    146 REST.GET.VERSIONING
    147 REST.GET.WEBSITE
  17296 REST.HEAD.BUCKET
  56617 REST.HEAD.OBJECT
      1 REST.PUT.LOGGING_STATUS
 121313 REST.PUT.OBJECT

アカウント毎にアクセス可能な S3 Prefix を制御する S3 バケットポリシー例

やりたいこと

  • データレイクアカウントと連携相手の複数アカウントの間で1対多のクロスアカウントアクセス制御を行う。
  • 連携相手のアカウントから特定S3バケットの特定 prefix 以下のみへの Put/Get/Delete を許可。
  • 連携相手のアカウント毎に Put/Get/Delete 可能な prefix を分け、他アカウントの prefix 配下への Put/Get/Delete 禁止。
  • 自アカウントはVPCエンドポイント経由以外の Put/Get/Delete 禁止。
  • VPCエンドポイント経由以外の Put/Get/Delete 禁止。
  • VPCエンドポイント経由でも許可していないロールからの Put/Get/Delete 禁止。

バケットポリシー例

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Access-to-specific-VPCE-only",
            "Effect": "Deny",
            "Principal": "*",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::test-123",
                "arn:aws:s3:::test-123/*"
            ],
            "Condition": {
                "StringNotEquals": {
                    "aws:sourceVpce": [
                        "vpce-0e6************0a",
                        "vpce-02c************64",
                        "vpce-0a6************67"
                    ]
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:role/EC2RoleA"
            },
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::test-123/dir1/",
                "arn:aws:s3:::test-123/dir1/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:sourceVpce": "vpce-02c************64"
                }
            }
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::234567890123:role/EC2RoleB"
            },
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::test-123/dir2/",
                "arn:aws:s3:::test-123/dir2/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:sourceVpce": "vpce-0a6************67"
                }
            }
        }
    ]
}

確認したこと

  • マネジメントコンソールから Put/Get/Delete できない(設定したVPCエンドポイント経由以外では不可)。以下はダウンロードしようとした場合。
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>867BA8F95B99B06C</RequestId>
<HostId>
ZY9qTP+1ulVOJjYw7gElnIv+BO+2kKE/7wTT6SAYqS3H3TdjFu+yJa9dFKOeRmKin3xumvzUtew=
</HostId>
</Error>
  • 設定しているVPCエンドポイント経由でもバケットポリシーで指定したIAMロール以外からは Put/Get/Delete 不可。
$  aws s3 cp foo s3://test-123/dir1/
upload failed: ./foo to s3://test-123/dir1/foo An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

AWS CLI で IAM Role の Unique ID を取得する

$ aws iam get-role --role-name EC2AdminRole
{
    "Role": {
        "Description": "Allows EC2 instances to call AWS services on your behalf.",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "ec2.amazonaws.com"
                    }
                }
            ]
        },
        "MaxSessionDuration": 3600,
        "RoleId": "AIDAJQABLZS4A3QDU576Q",
        "CreateDate": "2018-09-09T14:43:29Z",
        "RoleName": "EC2AdminRole",
        "Path": "/",
        "Arn": "arn:aws:iam::123456789012:role/EC2AdminRole"
    }
}

参考

一意の ID
IAM がユーザー、グループ、ロール、ポリシー、インスタンスプロファイル、サーバー証明書を作成するとき、各エンティティには次の例のような一意の ID が割り当てられます。

AIDAJQABLZS4A3QDU576Q

ほとんどの場合、IAM エンティティで作業をするときはフレンドリ名と ARN を使用するため、特定のエンティティに対する一意の ID を知る必要はありません。しかしながら、フレンドリ名を用いることが実際的でないときなど、場合によっては一意の ID が役立つこともあります。

(中略)

IAM エンティティに対する一意の ID は、IAM コンソールでは取得できません。一意の ID を取得するには、以下の AWS CLI または IAM API コールを使用します。

IAM ID - AWS Identity and Access Management

特定のVPC EndpointからのみPut/Get/Deleteを許可するS3バケットポリシー

特定のVPC EndpointからのみPut/Get/Deleteを許可するS3バケットポリシーの記述例。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Access-to-specific-VPCE-only",
            "Effect": "Deny",
            "Principal": "*",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::s3-bucket-name",
                "arn:aws:s3:::s3-bucket-name/*"
            ],
            "Condition": {
                "StringNotEquals": {
                    "aws:sourceVpce": [
                        "vpce-*********************",
                        "vpce-*********************"
                    ]
                }
            }
        }
    ]
}