

# Amazon S3 서버 액세스 로그를 사용하여 요청 식별
<a name="using-s3-access-logs-to-identify-requests"></a>

Amazon S3 서버 액세스 로그를 사용하여 Amazon S3 요청을 식별할 수 있습니다.

**참고**  
Amazon S3 요청을 식별하려면 Amazon S3 서버 액세스 로그 대신 AWS CloudTrail 데이터 이벤트를 사용하는 것이 좋습니다. CloudTrail 데이터 이벤트는 더 쉽게 설정할 수 있으며 더 많은 정보를 포함합니다. 자세한 내용은 [CloudTrail을 사용하여 Amazon S3 요청 식별](cloudtrail-request-identification.md) 섹션을 참조하세요.
받는 액세스 요청의 수에 따라 CloudTrail 데이터 이벤트를 사용하는 것보다 로그를 분석하는 데 더 많은 리소스 또는 시간이 필요할 수 있습니다.

**Topics**
+ [Amazon Athena를 사용하여 요청에 대한 액세스 로그 쿼리](#querying-s3-access-logs-for-requests)
+ [Amazon S3 액세스 로그를 사용하여 Signature Version 2 요청 식별](#using-s3-access-logs-to-identify-sigv2-requests)
+ [Amazon S3 액세스 로그를 사용하여 객체 액세스 요청 식별](#using-s3-access-logs-to-identify-objects-access)

## Amazon Athena를 사용하여 요청에 대한 액세스 로그 쿼리
<a name="querying-s3-access-logs-for-requests"></a>

Amazon Athena를 사용하여 Amazon S3 액세스 로그로 Amazon S3 요청을 식별할 수 있습니다.

Amazon S3에서는 서버 액세스 로그를 S3 버킷에 객체로 저장합니다. Amazon S3의 로그를 분석할 수 있는 도구를 사용하는 것이 보통 더 쉽습니다. Athena는 S3 객체 분석을 지원하며 Amazon S3 액세스 로그를 쿼리하는 데 사용할 수 있습니다.

**Example**  
다음 예에서는 Amazon Athena에서 Amazon S3 서버 액세스 로그를 쿼리하는 방법을 보여 줍니다. 다음 예시에 사용된 `user input placeholders`를 실제 정보로 바꾸세요.  
Athena 쿼리에서 Amazon S3 위치를 지정하려면 로그가 전송되는 버킷 이름에 대한 S3 URI를 제공해야 합니다. 이 URI에는 버킷 이름과 접두사가 `s3://amzn-s3-demo-bucket1-logs/prefix/` 형식으로 포함되어야 합니다.

1. [https://console.aws.amazon.com/athena/](https://console.aws.amazon.com/athena/home)에서 Athena 콘솔을 엽니다.

1. 쿼리 편집기에서 다음과 유사한 명령을 실행합니다. `s3_access_logs_db`를 데이터베이스에 부여하려는 이름으로 바꿉니다.

   ```
   CREATE DATABASE s3_access_logs_db
   ```
**참고**  
S3 버킷과 동일한 AWS 리전에 데이터베이스를 생성하는 것이 가장 좋습니다.

1. 쿼리 편집기에서 다음과 비슷한 명령을 실행하여 2단계에서 만든 데이터베이스에 테이블 스키마를 생성합니다. `s3_access_logs_db.mybucket_logs`를 테이블에 부여하려는 이름으로 바꿉니다. `STRING` 및 `BIGINT` 데이터 형식 값이 액세스 로그 속성입니다. Athena에서 이 속성을 쿼리할 수 있습니다. `LOCATION`의 경우 앞서 설명한 대로 S3 버킷 및 접두사 경로를 입력하세요.

------
#### [ Date-based partitioning ]

   ```
   CREATE EXTERNAL TABLE s3_access_logs_db.mybucket_logs( 
    `bucketowner` STRING, 
    `bucket_name` STRING, 
    `requestdatetime` STRING, 
    `remoteip` STRING, 
    `requester` STRING, 
    `requestid` STRING, 
    `operation` STRING, 
    `key` STRING, 
    `request_uri` STRING, 
    `httpstatus` STRING, 
    `errorcode` STRING, 
    `bytessent` BIGINT, 
    `objectsize` BIGINT, 
    `totaltime` STRING, 
    `turnaroundtime` STRING, 
    `referrer` STRING, 
    `useragent` STRING, 
    `versionid` STRING, 
    `hostid` STRING, 
    `sigv` STRING, 
    `ciphersuite` STRING, 
    `authtype` STRING, 
    `endpoint` STRING, 
    `tlsversion` STRING,
    `accesspointarn` STRING,
    `aclrequired` STRING,
    `sourceregion` STRING)
    PARTITIONED BY (
      `timestamp` string)
   ROW FORMAT SERDE 
    'org.apache.hadoop.hive.serde2.RegexSerDe' 
   WITH SERDEPROPERTIES ( 
    'input.regex'='([^ ]*) ([^ ]*) \\[(.*?)\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) (-|[0-9]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) ([^ ]*)(?: ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*))?.*$') 
   STORED AS INPUTFORMAT 
    'org.apache.hadoop.mapred.TextInputFormat' 
   OUTPUTFORMAT 
    'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
   LOCATION
    's3://bucket-name/prefix-name/account-id/region/source-bucket-name/'
    TBLPROPERTIES (
     'projection.enabled'='true', 
     'projection.timestamp.format'='yyyy/MM/dd', 
     'projection.timestamp.interval'='1', 
     'projection.timestamp.interval.unit'='DAYS', 
     'projection.timestamp.range'='2024/01/01,NOW', 
     'projection.timestamp.type'='date', 
     'storage.location.template'='s3://bucket-name/prefix-name/account-id/region/source-bucket-name/${timestamp}')
   ```

------
#### [ Non-date-based partitioning ]

   ```
   CREATE EXTERNAL TABLE `s3_access_logs_db.mybucket_logs`(
     `bucketowner` STRING, 
     `bucket_name` STRING, 
     `requestdatetime` STRING, 
     `remoteip` STRING, 
     `requester` STRING, 
     `requestid` STRING, 
     `operation` STRING, 
     `key` STRING, 
     `request_uri` STRING, 
     `httpstatus` STRING, 
     `errorcode` STRING, 
     `bytessent` BIGINT, 
     `objectsize` BIGINT, 
     `totaltime` STRING, 
     `turnaroundtime` STRING, 
     `referrer` STRING, 
     `useragent` STRING, 
     `versionid` STRING, 
     `hostid` STRING, 
     `sigv` STRING, 
     `ciphersuite` STRING, 
     `authtype` STRING, 
     `endpoint` STRING, 
     `tlsversion` STRING,
     `accesspointarn` STRING,
     `aclrequired` STRING,
     `sourceregion` STRING)
   ROW FORMAT SERDE 
     'org.apache.hadoop.hive.serde2.RegexSerDe' 
   WITH SERDEPROPERTIES ( 
     'input.regex'='([^ ]*) ([^ ]*) \\[(.*?)\\] ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) (-|[0-9]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) (\"[^\"]*\"|-) ([^ ]*)(?: ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*))?.*$') 
   STORED AS INPUTFORMAT 
     'org.apache.hadoop.mapred.TextInputFormat' 
   OUTPUTFORMAT 
     'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
   LOCATION
     's3://amzn-s3-demo-bucket1-logs/prefix/'
   ```

------

1. 탐색 창의 **데이터베이스** 아래에서 데이터베이스를 선택하세요.

1. **테이블**에서 테이블 이름 옆의 **Preview table(테이블 미리보기)**을 선택하세요.

   **결과** 창에 `bucketowner`, `bucket`, `requestdatetime` 등 서버 액세스 로그의 데이터가 표시됩니다. 즉, Athena 테이블이 만들어졌다는 뜻입니다. 이제 Amazon S3 서버 액세스 로그를 쿼리할 수 있습니다.

**Example - 객체를 삭제한 사람과 시기 표시(타임스탬프, IP 주소 및 IAM 사용자)**  

```
SELECT requestdatetime, remoteip, requester, key 
FROM s3_access_logs_db.mybucket_logs 
WHERE key = 'images/picture.jpg' AND operation like '%DELETE%';
```

**Example - IAM 사용자가 수행한 모든 작업 표시**  

```
SELECT * 
FROM s3_access_logs_db.mybucket_logs 
WHERE requester='arn:aws:iam::123456789123:user/user_name';
```

**Example - 특정 기간에 객체에 수행한 모든 작업 표시**  

```
SELECT *
FROM s3_access_logs_db.mybucket_logs
WHERE Key='prefix/images/picture.jpg' 
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2017-02-18:07:00:00','yyyy-MM-dd:HH:mm:ss')
AND parse_datetime('2017-02-18:08:00:00','yyyy-MM-dd:HH:mm:ss');
```

**Example - 특정 기간에 특정 IP 주소로 전송한 데이터의 양 표시**  

```
SELECT coalesce(SUM(bytessent), 0) AS bytessenttotal
FROM s3_access_logs_db.mybucket_logs
WHERE remoteip='192.0.2.1'
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2022-06-01','yyyy-MM-dd')
AND parse_datetime('2022-07-01','yyyy-MM-dd');
```

**Example - 특정 기간의 HTTP 5xx 오류에 대한 요청 ID 찾기**  

```
SELECT requestdatetime, key, httpstatus, errorcode, requestid, hostid 
FROM s3_access_logs_db.mybucket_logs
WHERE httpstatus like '5%' AND timestamp
BETWEEN '2024/01/29'
AND '2024/01/30'
```

**참고**  
로그를 보존하는 시간을 줄이려면 서버 액세스 로그 버킷에 대해 S3 수명 주기 구성을 생성할 수 있습니다. 주기적으로 로그 파일을 제거하는 수명 주기 구성 규칙을 생성합니다. 그러면 Athena에서 쿼리마다 분석하는 데이터의 양이 줄어듭니다. 자세한 내용은 [버킷에서 S3 수명 주기 구성 설정](how-to-set-lifecycle-configuration-intro.md) 섹션을 참조하세요.

## Amazon S3 액세스 로그를 사용하여 Signature Version 2 요청 식별
<a name="using-s3-access-logs-to-identify-sigv2-requests"></a>

서명 버전 2에 대한 Amazon S3 지원이 비활성화됩니다(사용되지 않음). 그 이후 Amazon S3는 더 이상 서명 버전 2를 사용하는 요청을 수락하지 않으며 모든 요청은 서명 버전 4 서명을 사용해야 합니다. Amazon S3 액세스 로그를 사용하여 Signature Version 2 액세스 요청을 식별할 수 있습니다.

**참고**  
Signature Version 2 요청을 식별하려면 Amazon S3 서버 액세스 로그 대신 AWS CloudTrail 데이터 이벤트를 사용하는 것이 좋습니다. CloudTrail 데이터 이벤트는 서버 액세스 로그보다 더 쉽게 설정할 수 있으며 더 많은 정보를 포함합니다. 자세한 내용은 [CloudTrail을 사용하여 Amazon S3 서명 버전 2 요청 식별](cloudtrail-request-identification.md#cloudtrail-identification-sigv2-requests) 섹션을 참조하세요.

**Example - 서명 버전 2 트래픽을 보내는 모든 요청자 표시**  

```
SELECT requester, sigv, Count(sigv) as sigcount 
FROM s3_access_logs_db.mybucket_logs
GROUP BY requester, sigv;
```

## Amazon S3 액세스 로그를 사용하여 객체 액세스 요청 식별
<a name="using-s3-access-logs-to-identify-objects-access"></a>

Amazon S3 서버 액세스 로그에 대한 쿼리를 사용하여 `GET`, `PUT`, `DELETE` 등의 작업에 대해 Amazon S3 객체 액세스 요청을 식별하고 그러한 요청에 대한 추가 정보를 검색할 수 있습니다.

다음 Amazon Athena 쿼리 예시에서는 서버 액세스 로그에서 Amazon S3에 대한 모든 `PUT` 객체 요청을 가져오는 방법을 보여줍니다.

**Example - 특정 기간에 `PUT` 객체 요청을 보내는 모든 요청자 표시**  

```
SELECT bucket_name, requester, remoteip, key, httpstatus, errorcode, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE operation='REST.PUT.OBJECT' 
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z') 
BETWEEN parse_datetime('2019-07-01:00:42:42',yyyy-MM-dd:HH:mm:ss')
AND parse_datetime('2019-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')
```

다음 Amazon Athena 쿼리 예제에서는 서버 액세스 로그에서 Amazon S3에 대한 모든 `GET` 객체 요청을 가져오는 방법을 보여 줍니다.

**Example - 특정 기간에 `GET` 객체 요청을 보내는 모든 요청자 표시**  

```
SELECT bucket_name, requester, remoteip, key, httpstatus, errorcode, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE operation='REST.GET.OBJECT' 
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z') 
BETWEEN parse_datetime('2019-07-01:00:42:42','yyyy-MM-dd:HH:mm:ss')
AND parse_datetime('2019-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')
```

다음 Amazon Athena 쿼리 예제에서는 서버 액세스 로그에서 S3 버킷에 대한 모든 익명 요청을 가져오는 방법을 보여 줍니다.

**Example - 특정 기간에 버킷에 요청하는 모든 익명 요청자 표시**  

```
SELECT bucket_name, requester, remoteip, key, httpstatus, errorcode, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE requester IS NULL 
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z') 
BETWEEN parse_datetime('2019-07-01:00:42:42','yyyy-MM-dd:HH:mm:ss')
AND parse_datetime('2019-07-02:00:42:42','yyyy-MM-dd:HH:mm:ss')
```

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

**Example - 인증을 위해 ACL이 필요한 모든 요청 식별**  

```
SELECT bucket_name, requester, key, operation, aclrequired, requestdatetime
FROM s3_access_logs_db.mybucket_logs
WHERE aclrequired = 'Yes' 
AND parse_datetime(requestdatetime,'dd/MMM/yyyy:HH:mm:ss Z')
BETWEEN parse_datetime('2022-05-10:00:00:00','yyyy-MM-dd:HH:mm:ss')
AND parse_datetime('2022-08-10:00:00:00','yyyy-MM-dd:HH:mm:ss')
```

**참고**  
필요에 따라 요구에 맞게 날짜 범위를 수정할 수 있습니다.
이 쿼리 예제는 보안 모니터링에도 유용할 수 있습니다. 예상치 못하거나 승인되지 않은 IP 주소 또는 요청자의 `PutObject` 또는 `GetObject` 호출 결과를 검토하고 버킷에 대한 익명 요청을 식별할 수 있습니다.
이 쿼리는 로깅이 사용 설정된 시간부터의 정보만 검색합니다.
AWS CloudTrail 로그를 사용하는 경우, [CloudTrail을 사용하여 S3 객체에 대한 액세스 식별](cloudtrail-request-identification.md#cloudtrail-identification-object-access) 섹션을 참조하세요.