CloudTrail을 사용하여 Amazon S3 요청 식별 - Amazon Simple Storage Service

CloudTrail을 사용하여 Amazon S3 요청 식별

Amazon S3에서는 AWS CloudTrail 이벤트 로그를 사용하여 요청을 식별할 수 있습니다. AWS CloudTrail은 Amazon S3 요청을 식별하는 기본 방법이지만, Amazon S3 서버 액세스 로그를 사용하는 경우 Amazon S3 서버 액세스 로그를 사용하여 요청 식별 섹션을 참조하십시오.

CloudTrail 로그에서 Amazon S3에 대한 요청 식별

버킷으로 이벤트를 전달하도록 CloudTrail을 설정한 후 Amazon S3 콘솔에서 객체가 대상 버킷으로 이동하는지 확인해야 합니다. 형식은 다음과 같습니다.

s3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/Region/yyyy/mm/dd

CloudTrail에서 기록한 이벤트는 S3 버킷에 gzipped JSON 객체로 저장됩니다. 요청을 효율적으로 찾으려면 Amazon Athena와 같은 서비스를 사용하여 CloudTrail 로그를 인덱싱하고 쿼리해야 합니다.

CloudTrail 및 Athena에 대한 자세한 내용은 Amazon Athena 사용 설명서파티션 프로젝션을 사용하여 Athena에서 AWS CloudTrail 로그에 대한 테이블 생성을 참조하십시오.

CloudTrail을 사용하여 Amazon S3 서명 버전 2 요청 식별

CloudTrail 이벤트 로그를 사용하여 Amazon S3의 요청에 서명하는 데 사용된 API 서명 버전을 식별할 수 있습니다. 서명 버전 2에 대한 지원이 중단(사용되지 않음)될 예정이므로 이 기능은 중요합니다. 그 이후 Amazon S3는 더 이상 서명 버전 2를 사용하는 요청을 수락하지 않으며 모든 요청은 서명 버전 4 서명을 사용해야 합니다.

CloudTrail을 사용하여 워크플로에서 서명 버전 2 서명을 사용하고 있는지 확인하는 것이 좋습니다. 비즈니스에 영향을 미치지 않도록, 라이브러리와 코드가 서명 버전 4를 사용하도록 업그레이드하여 문제를 해결하십시오.

자세한 내용은 AWS re:Post의 Announcement: AWS CloudTrail for Amazon S3 adds new fields for enhanced security auditing(공지: Amazon S3용 CloudTrail, 향상된 보안 감사를 위해 새로운 필드 추가)를 참조하십시오.

참고

Amazon S3에 대한 CloudTrail 이벤트에는 'additionalEventData' 키 이름 아래에 요청 세부 정보의 서명 버전이 포함되어 있습니다. GET, PUT, DELETE 요청 등 Amazon S3 객체에 대한 요청의 서명 버전을 찾으려면 CloudTrail 데이터 이벤트를 활성화해야 합니다. (이 기능은 기본적으로 꺼져 있습니다.)

서명 버전 2 요청을 식별하는 데 사용되는 기본 방법은 AWS CloudTrail입니다. Amazon S3 서버 액세스 로그를 사용하는 경우 Amazon S3 액세스 로그를 사용하여 Signature Version 2 요청 식별 섹션을 참조하십시오.

Amazon S3 서명 버전 2 요청을 식별하기 위한 Athena 쿼리 예제

예 - 모든 서명 버전 2 이벤트 선택, EventTime, S3_Action, Request_Parameters, Region, SourceIP, UserAgent만 인쇄

다음 Athena 쿼리에서 s3_cloudtrail_events_db.cloudtrail_table을 Athena 세부 정보로 대체하고 필요에 따라 한도를 늘리거나 제거합니다.

SELECT EventTime, EventName as S3_Action, requestParameters as Request_Parameters, awsregion as AWS_Region, sourceipaddress as Source_IP, useragent as User_Agent FROM s3_cloudtrail_events_db.cloudtrail_table WHERE eventsource='s3.amazonaws.com' AND json_extract_scalar(additionalEventData, '$.SignatureVersion')='SigV2' LIMIT 10;
예 - 서명 버전 2 트래픽을 보내는 모든 요청자 선택

SELECT useridentity.arn, Count(requestid) as RequestCount FROM s3_cloudtrail_events_db.cloudtrail_table WHERE eventsource='s3.amazonaws.com' and json_extract_scalar(additionalEventData, '$.SignatureVersion')='SigV2' Group by useridentity.arn

서명 버전 2 데이터 분할

쿼리할 데이터가 많은 경우 분할된 표를 생성하면 Athena의 비용과 실행 시간을 줄일 수 있습니다.

이를 위해 다음과 같이 파티션이 있는 새 테이블을 만드십시오.

CREATE EXTERNAL TABLE s3_cloudtrail_events_db.cloudtrail_table_partitioned( eventversion STRING, userIdentity STRUCT< type:STRING, principalid:STRING, arn:STRING, accountid:STRING, invokedby:STRING, accesskeyid:STRING, userName:STRING, sessioncontext:STRUCT< attributes:STRUCT< mfaauthenticated:STRING, creationdate:STRING>, sessionIssuer:STRUCT< type:STRING, principalId:STRING, arn:STRING, accountId:STRING, userName:STRING> > >, eventTime STRING, eventSource STRING, eventName STRING, awsRegion STRING, sourceIpAddress STRING, userAgent STRING, errorCode STRING, errorMessage STRING, requestParameters STRING, responseElements STRING, additionalEventData STRING, requestId STRING, eventId STRING, resources ARRAY<STRUCT<ARN:STRING,accountId: STRING,type:STRING>>, eventType STRING, apiVersion STRING, readOnly STRING, recipientAccountId STRING, serviceEventDetails STRING, sharedEventID STRING, vpcEndpointId STRING ) PARTITIONED BY (region string, year string, month string, day string) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.orc.OrcSerde' STORED AS INPUTFORMAT 'org.apache.hadoop.hive.ql.io.SymlinkTextInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/';

그런 다음 개별적으로 파티션을 만듭니다. 생성하지 않은 날짜의 결과는 가져올 수 없습니다.

ALTER TABLE s3_cloudtrail_events_db.cloudtrail_table_partitioned ADD PARTITION (region= 'us-east-1', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/us-east-1/2019/02/19/' PARTITION (region= 'us-west-1', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/us-west-1/2019/02/19/' PARTITION (region= 'us-west-2', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/us-west-2/2019/02/19/' PARTITION (region= 'ap-southeast-1', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/ap-southeast-1/2019/02/19/' PARTITION (region= 'ap-southeast-2', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/ap-southeast-2/2019/02/19/' PARTITION (region= 'ap-northeast-1', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/ap-northeast-1/2019/02/19/' PARTITION (region= 'eu-west-1', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/eu-west-1/2019/02/19/' PARTITION (region= 'sa-east-1', year= '2019', month= '02', day= '19') LOCATION 's3://DOC-EXAMPLE-BUCKET1/AWSLogs/111122223333/CloudTrail/sa-east-1/2019/02/19/';

그런 다음 이 파티션을 기반으로 요청할 수 있으며 전체 버킷을 로드할 필요가 없습니다.

SELECT useridentity.arn, Count(requestid) AS RequestCount FROM s3_cloudtrail_events_db.cloudtrail_table_partitioned WHERE eventsource='s3.amazonaws.com' AND json_extract_scalar(additionalEventData, '$.SignatureVersion')='SigV2' AND region='us-east-1' AND year='2019' AND month='02' AND day='19' Group by useridentity.arn

CloudTrail을 사용하여 S3 객체에 대한 액세스 식별

AWS CloudTrail 이벤트 로그를 사용하여 GetObject, DeleteObjectPutObject와 같은 데이터 이벤트에 대한 Amazon S3 객체 액세스 요청을 식별하고 해당 요청에 대한 추가 정보를 검색할 수 있습니다.

다음 예제는 AWS CloudTrail 이벤트 로그에서 Amazon S3에 대한 모든 PUT 객체 요청을 가져오는 방법을 보여줍니다.

Amazon S3 객체 액세스 요청을 식별하기 위한 Athena 쿼리 예제

다음 Athena 쿼리 예제에서 s3_cloudtrail_events_db.cloudtrail_table을 Athena 세부 정보로 대체하고 필요에 따라 날짜 범위를 수정합니다.

예 - PUT 객체 액세스 요청이 있는 모든 이벤트 선택, EventTime, EventSource, SourceIP, UserAgent, BucketName, object, UserARN만 인쇄
SELECT eventTime, eventName, eventSource, sourceIpAddress, userAgent, json_extract_scalar(requestParameters, '$.bucketName') as bucketName, json_extract_scalar(requestParameters, '$.key') as object, userIdentity.arn as userArn FROM s3_cloudtrail_events_db.cloudtrail_table WHERE eventName = 'PutObject' AND eventTime BETWEEN '2019-07-05T00:00:00Z' and '2019-07-06T00:00:00Z'
예 - GET 객체 액세스 요청이 있는 모든 이벤트 선택, EventTime, EventSource, SourceIP, UserAgent, BucketName, object, UserARN만 인쇄
SELECT eventTime, eventName, eventSource, sourceIpAddress, userAgent, json_extract_scalar(requestParameters, '$.bucketName') as bucketName, json_extract_scalar(requestParameters, '$.key') as object, userIdentity.arn as userArn FROM s3_cloudtrail_events_db.cloudtrail_table WHERE eventName = 'GetObject' AND eventTime BETWEEN '2019-07-05T00:00:00Z' and '2019-07-06T00:00:00Z'
예 - 특정 기간 내 버킷으로의 모든 익명 요청자 이벤트 선택, EventTime, EventName, EventSource, SourceIP, UserAgent, BucketName, UserARN, AccountID만 인쇄
SELECT eventTime, eventName, eventSource, sourceIpAddress, userAgent, json_extract_scalar(requestParameters, '$.bucketName') as bucketName, userIdentity.arn as userArn, userIdentity.accountId FROM s3_cloudtrail_events_db.cloudtrail_table WHERE userIdentity.accountId = 'anonymous' AND eventTime BETWEEN '2019-07-05T00:00:00Z' and '2019-07-06T00:00:00Z'
예 - 인증을 위해 ACL이 필요한 모든 요청 식별

다음 Amazon Athena 쿼리 예제에서는 인증을 위해 액세스 제어 목록 (ACL)이 필요한 S3 버킷에 대한 모든 요청을 식별하는 방법을 보여줍니다. 승인을 위해 요청에 ACL이 필요한 경우, additionalEventDataaclRequired 값은 Yes입니다. ACL이 필요하지 않은 경우 aclRequired가 표시되지 않습니다. 이 정보를 사용하여 해당 ACL 권한을 적절한 버킷 정책으로 마이그레이션할 수 있습니다. 이러한 버킷 정책을 생성한 후에는 해당 버킷에 ACL을 비활성화할 수 있습니다. ACL에 대한 자세한 내용은 ACL 사용 중지를 위한 사전 조건 페이지를 참조하십시오.

SELECT eventTime, eventName, eventSource, sourceIpAddress, userAgent, userIdentity.arn as userArn, json_extract_scalar(requestParameters, '$.bucketName') as bucketName, json_extract_scalar(requestParameters, '$.key') as object, json_extract_scalar(additionalEventData, '$.aclRequired') as aclRequired FROM s3_cloudtrail_events_db.cloudtrail_table WHERE json_extract_scalar(additionalEventData, '$.aclRequired') = 'Yes' AND eventTime BETWEEN '2022-05-10T00:00:00Z' and '2022-08-10T00:00:00Z'
참고
  • 이 쿼리 예제는 보안 모니터링에도 유용할 수 있습니다. 예상치 못하거나 승인되지 않은 IP 주소 또는 요청자의 PutObject 또는 GetObject 호출 결과를 검토하고 버킷에 대한 익명 요청을 식별할 수 있습니다.

  • 이 쿼리는 로깅이 사용 설정된 시간부터의 정보만 검색합니다.

Amazon S3 서버 액세스 로그를 사용하는 경우 Amazon S3 액세스 로그를 사용하여 객체 액세스 요청 식별 단원을 참조하십시오.