AWS

Part 16. AWS 서비스를 운영하면서 필요한 것들 (로깅)

cwchoiit 2024. 1. 26. 23:07
728x90
반응형
SMALL
728x90
SMALL

 

AWS 서비스를 운영하면서 필요한 작업들에 대한 기록을 할 예정이다. 로깅, 백업 등 다양한 AWS 서비스를 활용해보자.

 

 

로깅

서비스를 운영할 때 무조건적으로 필요한 로그 남기기. AWS에서는 여러 로그를 남기는 서비스가 있지만 여기서는 세가지를 알아보겠다.

  • CloudTrail의 Audit Log
  • Amazon VPC의 Flow Log
  • Elastic Load Balancing의 Access Log

그리고 이 로그들을 S3에 저장하고 저장된 로그들을 쿼리문으로 조회할 수 있게 도와주는 Athena 서비스를 이용해보겠다.

 

CloudTrail

우선 AWS Console에 ColudTrail을 입력하고 서비스를 선택한다.

 

왼쪽 사이드바에서 "Trails"를 선택하고 'Create trail' 클릭

 

General details는 다음과 같이 설정한다.

- Trail name: cwchoiit-cloudtrail

- Storage location: Create new S3 bucket

- Trail log bucket and folder: cwchoiit-cloudtrail

- Log file SSE-KMS encryption: Enabled 체크 해제

 

그 외 값은 기본값으로 생성한다. 그러면 리스트에 다음과 같이 생성된 Cloudtrail이 보이고 그 Trail이 가지는 S3 bucket도 보여진다.

 

S3 버킷으로 들어가보면 다음과 같은 화면이 보인다.

본인의 계정 번호 아래 두개의 Objects가 생성되는데 그 중 CloudTrail이라는 폴더가 있다. 이 폴더에 로그들이 쌓이게 된다. 

아래 화면을 보면 해당 폴더 아래 지역이 나오고 그 안에 날짜별로 폴더가 생성된 후 로그 파일이 저장된 것이 보인다.

 

 

쌓인 로그들을 Athena에서 테이블을 생성하고 쿼리로 조회할 수 있다. 그러기 위해 CloudTrail의 Event history로 들어가보자.

 

들어가보면 이벤트 히스토리가 쭉 쌓여있는 것도 확인할 수 있고 우측 상단 'Create Athena table' 이라는 버튼이 있다. 클릭.

 

다음과 같은 화면이 보인다. 여기서 방금 생성된 로그들을 저장하는 S3를 선택하면 알아서 테이블 만드는 쿼리를 짜준다. 테이블을 생성해보자.

 

테이블이 생성됐으면 AWS Console에서 "Athena"를 검색하고 서비스를 선택한다.

 

들어가서 좌측 사이드바에 "Query editor"를 클릭하면 쿼리를 날릴 수 있는 화면이 나온다.

 

에디터에서는 좌측 하단 방금 만든 테이블이 보인다. 이 테이블에 대한 쿼리를 날려보자.

 

쿼리 예시는 다음 링크를 참조하자.

 

AWS CloudTrail 로그 쿼리 - Amazon Athena

여러 계정, 리전 및 날짜에 걸쳐 CloudTrail 이벤트 정보에 대한 SQL 쿼리를 수행하려면 CloudTrail Lake 사용을 고려해 보세요. CloudTrail Lake는 기업의 정보를 검색 가능한 단일 이벤트 데이터 스토어로

docs.aws.amazon.com

 

예시 중 다음 쿼리를 날려보자. 참고로 FROM절은 내 테이블명을 입력해야한다.

SELECT
 useridentity.arn,
 eventname,
 sourceipaddress,
 eventtime
FROM cloudtrail_logs_cwchoiit_cloudtrail 
LIMIT 100;

 

그 전에 쿼리 에디터로 가보면 이러한 문구가 있다.

쿼리 날리기 전에 결과에 대한 위치를 설정해야 한다는데 우측에 'Edit settings'를 클릭해서 설정하자.

 

들어가면 저렇게 'Browse S3'가 있다. 클릭.

 

클릭하면 다음과 같은 화면이 나오는데 우리가 Athena 테이블 만들면서 자동으로 만들어진 S3 버킷이 하나있다.

"aws-athena-xxxx" 이것을 클릭한다. 

 

선택하고 다음 화면에서는 다른것 필요없이 바로 'Save'를 클릭하면 된다. 이제 진짜로 쿼리를 날려보자. 쿼리를 넣고 아래 'Run' 버튼을 클릭하면 하단에 결과가 도출된다.

 

CloudTrail 정리

내가 원하는 데이터에 대한 Athena 쿼리를 어떻게 날려야 하는지 알면 정말 유용하게 사용할 수 있을 것 같다. Audit Log는 정말 중요한 부분이기 때문에 CloudTrail로 로그를 잘 남겨서 관리 운영하면 좋을듯하다.

 

 

ELB Access Log

이번에는 ELB 액세스 로그를 활성화해서 로그를 저장하고 로그를 확인해보자.

우선 AWS Console에 EC2를 입력해서 서비스 화면으로 들어간다.

 

좌측 Load Balancers를 클릭한다.

 

액세스 로그를 활성화 시킬 ALB를 선택한 다음 하단 'Attributes' 탭에서 'Edit' 버튼을 클릭한다.

 

수정 화면에 들어오면 하단에 Access logs를 활성화 시킨다.

 

활성화를 시키면 S3 URI를 입력해야 한다. 그러려면 S3 버킷이 있어야 하니까 버킷을 하나 만들고 만든 버킷의 정책을 수정해야 한다. 왜냐하면 ELB Access log가 접근 가능하도록. 다음과 같은 정책을 사용한다. 여기서 변경 적용할 부분은 다음과 같다.

- ALBAccountId: ap-northeast-2로 만들어진 ALB의 경우 "600734575887"를 입력

- YourBucketName: 버킷 이름

- YourAWSAcountID: AWS Account ID

{
    "Version": "2012-10-17",
    "Id": "AWSConsole-AccessLogs-Policy",
    "Statement": [
        {
            "Sid": "AWSConsoleStmt",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::ALBAccountId:root"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::YourBucketName/AWSLogs/YourAWSAccountID/*"
        },
        {
            "Sid": "AWSLogDeliveryWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::YourBucketName/AWSLogs/YourAWSAccountID/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        },
        {
            "Sid": "AWSLogDeliveryAclCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::YourBucketName"
        }
    ]
}

 

버킷 정책을 수정했으면 버킷 이름을 입력해서 넣고 만들어보자.

 

생성이 완료되면 해당 버킷으로 가보자. 이러한 폴더(AWSLogs)가 자동으로 만들어져있다.

 

그 내부로 들어가보면 이러한 경로에 다음과 같은 액세스 로그 파일이 만들어져 있음을 확인할 수 있다.

 

액세스 로그를 활성화 시켰으니까 트래픽을 발생시켜서 액세스 로그가 잘 남는지도 확인해보자. 액세스 로그를 활성화시킨 ELB에 접근하자. 나의 경우는 "ecs.cwchoiit.net"으로 브라우저에 접속하면 된다. 그렇게 접속한 후 내 접근이 잘 기록됐는지 확인해보자.

 

그런데 그 로그를 찾기 위해 좀 더 효율적으로 쿼리문으로 뽑아내보자. 위에서 했던것처럼 Athena를 이용한다.

Athena를 이용하려면 먼저 ELB의 테이블을 만들어야 한다. 만드는 방법은 다음 링크를 참조.

 

Application Load Balancer 로그 쿼리 - Amazon Athena

다음 CREATE TABLE 문에는 최근에 추가된 classification 및 classification_reason 열이 포함됩니다. 이러한 항목을 포함하지 않은 Application Load Balancer 액세스 로그에 대한 테이블을 생성하려면 CREATE TABLE 문에

docs.aws.amazon.com

 

해당 링크에서 ALB 로그의 테이블 생성 관련 쿼리 예제가 있다. 그것을 복사해서 테이블을 만들어보자. 복사해서 변경할 부분은 다음과 같다.

CREATE EXTERNAL TABLE IF NOT EXISTS alb_logs (
            type string,
            time string,
            elb string,
            client_ip string,
            client_port int,
            target_ip string,
            target_port int,
            request_processing_time double,
            target_processing_time double,
            response_processing_time double,
            elb_status_code int,
            target_status_code string,
            received_bytes bigint,
            sent_bytes bigint,
            request_verb string,
            request_url string,
            request_proto string,
            user_agent string,
            ssl_cipher string,
            ssl_protocol string,
            target_group_arn string,
            trace_id string,
            domain_name string,
            chosen_cert_arn string,
            matched_rule_priority string,
            request_creation_time string,
            actions_executed string,
            redirect_url string,
            lambda_error_reason string,
            target_port_list string,
            target_status_code_list string,
            classification string,
            classification_reason string
            )
            ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
            WITH SERDEPROPERTIES (
            'serialization.format' = '1',
            'input.regex' = 
        '([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*):([0-9]*) ([^ ]*)[:-]([0-9]*) ([-.0-9]*) ([-.0-9]*) ([-.0-9]*) (|[-0-9]*) (-|[-0-9]*) ([-0-9]*) ([-0-9]*) \"([^ ]*) (.*) (- |[^ ]*)\" \"([^\"]*)\" ([A-Z0-9-_]+) ([A-Za-z0-9.-]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" ([-.0-9]*) ([^ ]*) \"([^\"]*)\" \"([^\"]*)\" \"([^ ]*)\" \"([^\s]+?)\" \"([^\s]+)\" \"([^ ]*)\" \"([^ ]*)\"')
            LOCATION 's3://DOC-EXAMPLE-BUCKET/AWSLogs/<ACCOUNT-ID>/elasticloadbalancing/<REGION>/'

 

이 LOCATION 부분에서 다음을 수정한다.

- DOC-EXAMPLE-BUCKET: 버킷 이름

- ACCOUNT-ID: AWS Accound ID

- REGION: ap-northeast-2

LOCATION 's3://DOC-EXAMPLE-BUCKET/AWSLogs/<ACCOUNT-ID>/elasticloadbalancing/<REGION>/'

 

테이블을 만들면 버킷에서 로그가 잘 쌓여있는지 확인해보자. 아까 트래픽을 발생시켰으니까 시간이 좀 지나면서 로그가 쌓일것이다.

아래 사진과 같이 오늘 날짜로 된 폴더 내 로그가 보인다.

 

이제 해당 로그 파일에서 원하는 쿼리를 날려보자. 다음은 위 링크에서 가져올 수 있는 예시 쿼리이다.

이 쿼리는 클라이언트 IP 주소별로 그룹화된 로드 밸런서가 수신한 HTTP GET 요청의 개수를 계산한다. 날려보자.

SELECT COUNT(request_verb) AS
 count,
 request_verb,
 client_ip
FROM alb_logs
GROUP BY request_verb, client_ip
LIMIT 100;

 

쿼리 결과는 다음처럼 나온다. 내 IP는 11회 조회를 했고 그 외 나머지는 아마도 AWS의 서울 각 가용영역에서 접근한 것으로 보여진다.

 

 

ELB Access Log 중간정리

ELB의 Access Log를 Athena를 통해 쿼리문을 날려 원하는 데이터만 뽑아봤다. 이렇게 접근 관련 로그도 잘 남길 수 있게 됐다.

 

 

 

Amazon VPC Flow Log

이번에는 VPC Flow Log를 활성화해서 Athena에서 확인해보자.

AWS Console에서 VPC를 검색해서 서비스에 들어가고 화면 좌측 VPC를 클릭한다.

Flow log를 활성화 시킬 VPC를 선택한 다음에 하단 Flow logs 탭을 클릭해서 Create flow log 버튼을 누른다.

 

진입 화면에서 다음 사진에서 빨간 박스 부분을 수정해야 한다.

- Name: cwchoiit-vpc-flow-logs

- Destination: S3 bucket

- S3 bucket ARN: S3 버킷의 ARN을 입력 (S3 Bucket은 직접 만들어서 ARN 입력란에 입력해야 한다)

 

입력해서 만들면 Flow logs 탭에 만든 플로우 로그가 보인다. (나는 Maximum aggregation interval을 1분으로 수정했다)

 

이렇게 생성한 후 S3 버킷으로 가보면 폴더가 자동으로 아래처럼 만들어진다. (AWSLogs/AWSAccountID 경로)

 

아직 로그가 생성되지 않았고 이 로그를 생성하기 위해 트래픽을 발생시켜보자. 이 VPC 플로우 로그는 EC2에 붙어있는 네트워크 인터페이스에서 발생하는 모든 트래픽을 트래킹한다. 아래 사진이 EC2의 네트워크 인터페이스에 들어가면 보여지는 모든 네트워크 인터페이스이다. 모두 동일한 VPC(위에서 설정한 VPC)에 붙어있는 네트워크 인터페이스이고 이 네트워크를 통한 트래픽에 대한 로그를 남긴다.

 

트래픽을 발생시켜서 S3 버킷에 로그가 쌓이는지 확인해보자. 다음과 같이 오늘 날짜 경로에 로그가 저장된다.

 

이 로그를 Athena를 통해 쿼리로 데이터를 추출해보자. Athena를 통해 쿼리를 날리려면 VPC 플로우 로그에 대한 테이블이 만들어져야 한다. 테이블 만드는 쿼리는 아래 링크를 참조.

 

Amazon VPC 흐름 로그 쿼리 - Amazon Athena

Amazon VPC 흐름 로그 쿼리 Amazon Virtual Private Cloud 흐름 로그는 VPC의 네트워크 인터페이스에서 송수신되는 IP 트래픽에 대한 정보를 수집합니다. 로그를 사용하여 네트워크 트래픽 패턴을 조사하고 V

docs.aws.amazon.com

해당 링크에서 테이블 만드는 쿼리를 가져왔으면 Athena 서비스로 들어가서 테이블을 만든다. 다음이 테이블 만드는 쿼리인데 여기서 변경할 부분은 그 바로 아래와 같다.

CREATE EXTERNAL TABLE IF NOT EXISTS `vpc_flow_logs` (
  version int,
  account_id string,
  interface_id string,
  srcaddr string,
  dstaddr string,
  srcport int,
  dstport int,
  protocol bigint,
  packets bigint,
  bytes bigint,
  start bigint,
  `end` bigint,
  action string,
  log_status string,
  vpc_id string,
  subnet_id string,
  instance_id string,
  tcp_flags int,
  type string,
  pkt_srcaddr string,
  pkt_dstaddr string,
  region string,
  az_id string,
  sublocation_type string,
  sublocation_id string,
  pkt_src_aws_service string,
  pkt_dst_aws_service string,
  flow_direction string,
  traffic_path int
)
PARTITIONED BY (`date` date)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ' '
LOCATION 's3://DOC-EXAMPLE-BUCKET/prefix/AWSLogs/{account_id}/vpcflowlogs/{region_code}/'
TBLPROPERTIES ("skip.header.line.count"="1");

 

- DOC-EXAMPLE-BUCKET: S3 버킷 이름

- {account_id}: AWS Account ID

- {region_code}: ap-northeast-2

LOCATION 's3://DOC-EXAMPLE-BUCKET/prefix/AWSLogs/{account_id}/vpcflowlogs/{region_code}/'

 

이렇게 해서 테이블을 생성한 다음 한 가지 더 해줄게 있다. 테이블을 수정해야 하는데 데이터를 읽을 수 있도록 파티션을 생성해야 한다. 왜냐하면 테이블 만들 때 쿼리를 잘 보면 PARTITIONED BY ('date' date)라고 입력한 부분이 있다. 날짜로 파티션을 나눴기 때문에 하단 쿼리처럼 원하는 날짜에 대한 파티션을 추가해야 그 날짜에 대한 쿼리에 대한 결과를 출력할 수 있다.

ALTER TABLE vpc_flow_logs
ADD PARTITION (`date`='YYYY-MM-dd')
LOCATION 's3://DOC-EXAMPLE-BUCKET/prefix/AWSLogs/{account_id}/vpcflowlogs/{region_code}/YYYY/MM/dd';

그래서 위 코드에서 파티션을 생성할 날짜를 입력해야 한다. 날짜는 당연히 원하는 쿼리에 해당하는 날짜를 입력해야 한다. 아래는 그 예시다.

ALTER TABLE vpc_flow_logs
ADD PARTITION (`date`='2023-01-28')
LOCATION 's3://cwchoiit-vpc-flow-logs/AWSLogs/135149110460/vpcflowlogs/ap-northeast-2/2023/01/28';

 

이렇게 파티션을 만들었으면 이제 예시 쿼리를 날려보면 된다. 아래는 예시 쿼리이고 지정한 날짜에 최대 100개의 흐름을 출력한다.

SELECT * 
FROM vpc_flow_logs 
WHERE date = DATE('2020-05-04') 
LIMIT 100;

 

그럼 다음과 같이 결과가 쭉 나온다.

 

또 다른 예시는 해당 날짜에 거절된 트래픽이다. 결과가 잘 출력되는 모습이다.

 

VPC Flow Log 정리

VPC Flow log와 Athena를 통해 원하는 쿼리문을 작성해서 로그를 출력할 수 있었다.

 

728x90
반응형
LIST