Amazon Simple Storage Service
개발자 안내서 (API 버전 2006-03-01)

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

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

CloudTrail가 Amazon S3에 대한 요청을 캡처하는 방식

기본적으로 CloudTrail는 최근 90일 동안의 S3 버킷 수준 API 호출을 기록하지만 객체에 대한 로그 요청은 기록하지 않습니다. 버킷 수준 호출에는 CreateBucket, DeleteBucket, PutBucketLifeCycle, PutBucketPolicy 등의 이벤트가 포함됩니다. CloudTrail 콘솔에서 버킷 수준 이벤트를 볼 수 있습니다. 그러나 거기에서 데이터 이벤트(Amazon S3 객체 수준 호출)를 볼 수 없으므로 데이터 이벤트에 대한 CloudTrail 로그를 구분 분석하거나 쿼리해야 합니다.

CloudTrail에서 캡처한 Amazon S3 API 호출에 대한 정보는 CloudTrail의 Amazon S3 정보 단원을 참조하십시오.

S3 버킷 및 객체에 대한 CloudTrail 이벤트 로깅 활성화

CloudTrail 데이터 이벤트를 통해 버킷 및 객체 수준 요청에 대한 정보를 가져올 수 있습니다. 특정 버킷에 대해 CloudTrail 데이터 이벤트를 활성화하려면 Amazon Simple Storage Service 콘솔 사용 설명서에서 AWS CloudTrail 데이터 이벤트가 있는 S3 버킷에 대한 객체 수준 로깅을 사용하는 방법을 참조하십시오.

모든 버킷 또는 특정 버킷 목록에 대해 CloudTrail 데이터 이벤트를 사용하려면 CloudTrail에서 수동으로 추적을 생성해야 합니다.

참고

  • CloudTrail의 기본 설정은 관리 이벤트만 찾는 것입니다. 계정에 데이터 이벤트가 활성화되어 있는지 확인하십시오.

  • 많은 워크로드를 생성하는 S3 버킷의 경우, 단시간 내에 수천 개의 로그를 신속하게 생성할 수 있습니다. 사용량이 많은 버킷에 대해 얼마나 길게 CloudTrail 데이터 이벤트를 활성화할 것인지, 주의해서 선택해야 합니다.

CloudTrail는 선택한 S3 버킷에 Amazon S3 데이터 이벤트 로그를 저장합니다. 별도의 AWS 계정에서 버킷을 사용하면 소유할 수 있는 여러 버킷의 이벤트를 중앙 위치에서 더 잘 정리할 수 있으므로 쿼리 및 분석이 더 쉽습니다. 별도의 AWS 계정에서 버킷을 사용 AWS Organizations를 사용하면 모니터링하는 버킷을 소유한 계정과 연결된 AWS 계정을 쉽게 만들 수 있습니다. 자세한 내용은 AWS Organizations 사용 설명서AWS Organizations란 무엇입니까?를 참조하십시오.

CloudTrail에서 추적을 생성할 때 데이터 이벤트 섹션에서 Select all S3 buckets in your account(계정의 모든 S3 버킷 선택) 확인란을 선택하여 모든 객체 수준 이벤트를 기록할 수 있습니다.

참고

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

CloudTrail에서 기록한 이벤트는 S3 버킷에 GZip으로 압축된 JSON 객체로 저장됩니다. 요청을 효율적으로 찾으려면 Amazon Athena 같은 서비스를 사용하여 CloudTrail 로그를 인덱싱하고 쿼리해야 합니다. CloudTrail 및 Athena에 대한 자세한 정보는 AWS CloudTrail 로그 쿼리를 참조하십시오.

CloudTrail 로그에 Athena 사용

버킷으로 이벤트를 전달하도록 CloudTrail를 설정한 후 Amazon S3 콘솔에서 객체가 대상 버킷으로 이동하는지 확인해야 합니다. 이들은 다음과 같은 서식이 지정됩니다. s3://<myawsexamplebucket>/AWSLogs/<111122223333>/CloudTrail/<Region>/<yyyy>/<mm>/<dd>

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

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

s3://myawsexamplebucket/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_myawsexamplebucket>에서 본인의 버킷 이름으로 변경하십시오. 또한 버킷에 사용되는 AWS_account_ID CloudTrail를 입력하십시오.

    CREATE EXTERNAL TABLE s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket_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://<myawsexamplebucket>/AWSLogs/<111122223333>/';
  5. 쿼리가 작동하는지 확인하려면 Athena를 테스트하십시오.

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

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

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

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

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

참고

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

AWS CloudTrail은 서명 버전 2 요청을 식별하는 기본 방법이며, Amazon S3 서버 액세스 로그를 사용하는 경우 Amazon S3 액세스 로그를 사용하여 서명 버전 2 요청 식별 단원을 참조하십시오.

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

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

다음 Athena 쿼리에서 <s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket_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_myawsexamplebucket_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_myawsexamplebucket_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_myawsexamplebucket_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://myawsexamplebucket/AWSLogs/111122223333/';

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

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

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

SELECT useridentity.arn, Count(requestid) AS RequestCount FROM s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket_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

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

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

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

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

다음 Athena 쿼리 예제에서 <s3_cloudtrail_events_db.cloudtrail_myawsexamplebucket_table>을 Athena 세부 정보로 대체하고 필요에 따라 날짜 범위를 수정하십시오.

예 — PUT 객체 액세스 요청이 있는 모든 이벤트를 선택하고, EventTime, EventSource, SourceIP, UserAgent, BucketName, Object, UserARN만 인쇄

SELECT eventTime, eventName, eventSource, sourceIpAddress, userAgent, requestParameters.bucketName as bucketName, 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, requestParameters.bucketName as bucketName, 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, 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 액세스 로그를 사용하여 객체 액세스 요청 식별 단원을 참조하십시오.