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에서 기록한 이벤트는 S3 버킷에 GZip으로 압축된 JSON 객체로 저장됩니다. 요청을 효율적으로 찾으려면 Amazon Athena와 같은 서비스를 사용하여 CloudTrail 로그를 인덱싱하고 쿼리해야 합니다. CloudTrail 및 Athena에 대한 자세한 내용은 Amazon Athena 사용 설명서에서 AWS CloudTrail 로그 쿼리를 참조하세요.

CloudTrail 로그에 Athena 사용

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

s3://<myawsexamplebucket1>/AWSLogs/<111122223333>/CloudTrail/<Region>/<yyyy>/<mm>/<dd>

예 - Athena를 사용하여 특정 요청에 대한 CloudTrail 이벤트 로그 쿼리

CloudTrail 이벤트 로그를 찾습니다.

s3://myawsexamplebucket1/AWSLogs/111122223333/CloudTrail/us-east-2/2019/04/14

CloudTrail 이벤트 로그를 사용하면 다음과 같이 Athena 데이터베이스와 테이블을 생성하여 쿼리할 수 있습니다.

  1. https://console.aws.amazon.com/athena/에서 Athena 콘솔을 엽니다.

  2. AWS 리전을 CloudTrail 대상 S3 버킷과 동일하게 변경하세요.

  3. 쿼리 창에서 CloudTrail 이벤트에 대한 Athena 데이터베이스를 생성합니다.

    CREATE DATABASE s3_cloudtrail_events_db
  4. 다음 쿼리를 사용하여 버킷의 모든 CloudTrail 이벤트에 대한 테이블을 생성합니다. 버킷 이름을 <CloudTrail_myawsexamplebucket1>에서 본인의 버킷 이름으로 변경하세요. 또한 버킷에 사용되는 AWS_account_ID CloudTrail을 입력하세요.

    CREATE EXTERNAL TABLE s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket1_table( 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 ) ROW FORMAT SERDE 'com.amazon.emr.hive.serde.CloudTrailSerde' STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' LOCATION 's3://<myawsexamplebucket1>/AWSLogs/<111122223333>/';
  5. 쿼리가 작동하는지 확인하기 위해 Athena를 테스트하세요.

    SELECT * FROM s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket1_table WHERE eventsource='s3.amazonaws.com' LIMIT 2;

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

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

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

자세한 내용은 AWS 토론 포럼의 공지: Amazon S3용 AWS CloudTrail, 향상된 보안 감사를 위해 새로운 필드 추가를 참조하세요.

참고

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

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

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

예 - 모든 서명 버전 2 이벤트를 선택하고 EventTime, S3 작업, Request_Parameters, Region, SourceIP 및 UserAgent만 인쇄

다음 Athena 쿼리에서 <s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket1_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_myawsexamplebucket1_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_myawsexamplebucket1_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_myawsexamplebucket1_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 'com.amazon.emr.hive.serde.CloudTrailSerde' STORED AS INPUTFORMAT 'com.amazon.emr.cloudtrail.CloudTrailInputFormat' OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' LOCATION 's3://myawsexamplebucket1/AWSLogs/111122223333/';

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

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

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

SELECT useridentity.arn, Count(requestid) AS RequestCount FROM s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket1_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_myawsexamplebucket1_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_myawsexamplebucket_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_myawsexamplebucket_table WHERE eventName = 'GetObject' AND eventTime BETWEEN '2019-07-05T00:00:00Z' and '2019-07-06T00:00:00Z'

예 - 특정 기간에 버킷에 대한 모든 익명 요청자 이벤트를 선택하고, EventTime, EventSource, SourceIP, UserAgent, BucketName, UserIdentity, UserARN만 인쇄

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

  • 이 쿼리는 로깅이 활성화된 시간부터의 정보만 검색합니다.

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