

# CloudTrail을 사용하여 Amazon S3 요청 식별
<a name="cloudtrail-request-identification"></a>

Amazon S3에서는 AWS CloudTrail 이벤트 로그를 사용하여 요청을 식별할 수 있습니다. AWS CloudTrail은 Amazon S3 요청을 식별하는 기본 방법이지만, Amazon S3 서버 액세스 로그를 사용하는 경우 [Amazon S3 서버 액세스 로그를 사용하여 요청 식별](using-s3-access-logs-to-identify-requests.md) 섹션을 참조하십시오.

**Topics**
+ [CloudTrail 로그에서 Amazon S3에 대한 요청 식별](#identify-S3-requests-using-in-CTlog)
+ [CloudTrail을 사용하여 Amazon S3 서명 버전 2 요청 식별](#cloudtrail-identification-sigv2-requests)
+ [CloudTrail을 사용하여 S3 객체에 대한 액세스 식별](#cloudtrail-identification-object-access)

## CloudTrail 로그에서 Amazon S3에 대한 요청 식별
<a name="identify-S3-requests-using-in-CTlog"></a>

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

`s3://amzn-s3-demo-bucket1/AWSLogs/111122223333/CloudTrail/Region/yyyy/mm/dd` 

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

CloudTrail 및 Athena에 대한 자세한 내용은 *Amazon Athena 사용 설명서*의 [파티션 프로젝션을 사용하여 Athena에서 AWS CloudTrail 로그에 대한 테이블 생성](https://docs.aws.amazon.com/athena/latest/ug/cloudtrail-logs.html#create-cloudtrail-table-partition-projection)을 참조하십시오.

## CloudTrail을 사용하여 Amazon S3 서명 버전 2 요청 식별
<a name="cloudtrail-identification-sigv2-requests"></a>

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](https://forums.aws.amazon.com/ann.jspa?annID=6551)(공지: Amazon S3용 CloudTrail, 향상된 보안 감사를 위해 새로운 필드 추가)를 참조하십시오.

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

AWS CloudTrail서명 버전 2 요청을 식별하는 데 사용되는 기본 방법은 입니다. Amazon S3 서버 액세스 로그를 사용하는 경우 [Amazon S3 액세스 로그를 사용하여 Signature Version 2 요청 식별](using-s3-access-logs-to-identify-requests.md#using-s3-access-logs-to-identify-sigv2-requests) 섹션을 참조하십시오.

**Topics**
+ [Amazon S3 서명 버전 2 요청을 식별하기 위한 Athena 쿼리 예제](#ct-examples-identify-sigv2-requests)
+ [서명 버전 2 데이터 분할](#partitioning-sigv2-data)

### Amazon S3 서명 버전 2 요청을 식별하기 위한 Athena 쿼리 예제
<a name="ct-examples-identify-sigv2-requests"></a>

**Example - 모든 서명 버전 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;
```

**Example - 서명 버전 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 데이터 분할
<a name="partitioning-sigv2-data"></a>

쿼리할 데이터가 많은 경우 분할된 표를 생성하면 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://amzn-s3-demo-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://amzn-s3-demo-bucket1/AWSLogs/111122223333/CloudTrail/us-east-1/2019/02/19/'
    PARTITION (region= 'us-west-1', year= '2019', month= '02', day= '19') LOCATION 's3://amzn-s3-demo-bucket1/AWSLogs/111122223333/CloudTrail/us-west-1/2019/02/19/'
    PARTITION (region= 'us-west-2', year= '2019', month= '02', day= '19') LOCATION 's3://amzn-s3-demo-bucket1/AWSLogs/111122223333/CloudTrail/us-west-2/2019/02/19/'
    PARTITION (region= 'ap-southeast-1', year= '2019', month= '02', day= '19') LOCATION 's3://amzn-s3-demo-bucket1/AWSLogs/111122223333/CloudTrail/ap-southeast-1/2019/02/19/'
    PARTITION (region= 'ap-southeast-2', year= '2019', month= '02', day= '19') LOCATION 's3://amzn-s3-demo-bucket1/AWSLogs/111122223333/CloudTrail/ap-southeast-2/2019/02/19/'
    PARTITION (region= 'ap-northeast-1', year= '2019', month= '02', day= '19') LOCATION 's3://amzn-s3-demo-bucket1/AWSLogs/111122223333/CloudTrail/ap-northeast-1/2019/02/19/'
    PARTITION (region= 'eu-west-1', year= '2019', month= '02', day= '19') LOCATION 's3://amzn-s3-demo-bucket1/AWSLogs/111122223333/CloudTrail/eu-west-1/2019/02/19/'
    PARTITION (region= 'sa-east-1', year= '2019', month= '02', day= '19') LOCATION 's3://amzn-s3-demo-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 객체에 대한 액세스 식별
<a name="cloudtrail-identification-object-access"></a>

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

**참고**  
AWS CloudTrail을 사용하여 데이터 활동을 로깅하는 경우 Amazon S3 `DeleteObjects` 데이터 이벤트에 대한 이벤트 레코드에는 `DeleteObjects` 이벤트 및 해당 작업의 일부로 삭제된 각 객체에 대한 `DeleteObject` 이벤트가 모두 포함됩니다. 이벤트 레코드에서 삭제된 객체에 대한 추가 가시성을 제외할 수 있습니다. 자세한 내용은 *AWS CloudTrail 사용 설명서*의 [AWS CLI examples for filtering data events](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/filtering-data-events.html#filtering-data-events-deleteobjects)를 참조하세요.

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

**Topics**
+ [Amazon S3 객체 액세스 요청을 식별하기 위한 Athena 쿼리 예제](#ct-examples-identify-object-access-requests)

### Amazon S3 객체 액세스 요청을 식별하기 위한 Athena 쿼리 예제
<a name="ct-examples-identify-object-access-requests"></a>

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

**Example - `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'
```

**Example - `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'
```

**Example - 특정 기간 내 버킷으로의 모든 익명 요청자 이벤트 선택, `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'
```

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

```
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 액세스 로그를 사용하여 객체 액세스 요청 식별](using-s3-access-logs-to-identify-requests.md#using-s3-access-logs-to-identify-objects-access) 섹션을 참조하세요.