Cloudwatch Logs로 서버 로그 감시하기

Cloudwatch의 로그 필터링과 경보를 활용하여 로그의 특정 문자에 따라 경보(알람)이 발생하도록 설정하는 방법을 적은 글입니다
2021.06.30

클래스메소드의 수재 입니다.
이번에 작업을 하며 CloudWatch로 서버 로그를 감시할 일이 생겼습니다.
아직 한번도 해본적이 없었기에 개인 공부를 겸하여 블로그를 씁니다.

무엇을 하는가

이번 글에선 간단하게 ec2 인스턴스의 아파치 서버 액세스 로그를 Cloudwatch Logs에 보내고
이를 활용하여 특정한 IP가 필터링되면 경보 메일이 송신되도록 하는 설정을 해보겠습니다.
해당 글에선 간단히 누가 액세스를 하는가를 감시하지만 같은 방식으로 다양한 로그를 감시할 수 있습니다.
사용하는 서비스는 다음과 같습니다.

  • AWS Cloudwatch(로그 수집, 필터링, 경보 생성)
  • AWS Systems Manager(에이전트 설치 및 구성, Parameter store)
  • AWS SNS(구독 설정)

설정해보기

인스턴스는 미리 작성되어 있다는 가정하에 작업을 진행합니다.
시연 인스턴스의 AMI는 AmazonLinux2(ami-06631ebafb3ae5d34) 입니다

흐름

작업의 흐름은 다음과 같습니다.

  1. 사용할 IAM 역할 작성 및 지정하기
  2. Systems Manager로 Cloudwatch Agent 설치 및 구성하기
  3. 로그 필터 및 경보 만들기

이 중 IAM 역할 작성 및 지정은 내용이 너무 길어지므로 본 글에서 생략하도록 하겠습니다.
해당 과정을 대략적으로 설명하자면 다음과 같습니다.

  1. IAM 서비스 접속
  2. 역할 - 역할 만들기
  3. 정책에서 [CloudWatchAgentServerPolicy, AmazonSSMManagedInstanceCore]를 지정하여 역할 만들기
  4. EC2 인스턴스 목록에서 설정할 인스턴스를 클릭하고 작업 - 보안 - IAM 역할 수정 에서 생성한 역할 지정하기

간단하게 설명했지만 위의 설정이 IAM 역할 생성 및 연결하기의 전부이며 상세한 내용은 다음 링크를 참조해주세요.
Cloudwatch Agent용 IAM 설정하기

SSM으로 Cloudwatch Agent 설치 및 구성하기

Systems Manager(SSM)로 Cloudwatch Agent 설치

SSM으로 설치하기 전 인스턴스에 2.2.93.0 이상의 Systems Manager Agent가 설치되어 있어야 합니다.
아래의 AMI에는 기본적으로 설치가 되어 있으니 따로 설치하지 않아도 되지만 이외의 경우엔 이 페이지를 참고하여 인스턴스에 SSM Agent를 설치하고 진행해주세요.

  • SSM Agent가 사전에 설치되어 있는 AMI
    • Amazon Linux
    • Amazon Linux 2
    • Amazon Linux 2 ECS-Optimized Base AMIs
    • Ubuntu Server 16.04, 18.04, and 20.04

필요 버전 이상의 SSM Agent가 설치되었다면 Cloudwatch Agent를 다음 순서에 따라 설치합니다.

  1. AWS Systems Manager 서비스의 좌측에 있는 Run Command명령 실행 을 클릭합니다
  2. 명령 목록에서 AWS-ConfigureAWSPackage를 클릭하고 Name 파라미터에
    AmazonCloudWatchAgent를 입력합니다
  3. 아래의 대상 에서 수동으로 인스턴스 선택을 고른 후 설치할 인스턴스를 선택합니다
  4. 출력 옵션의 S3 버킷에 쓰기 활성화는 필요하다면 결과를 출력할 버킷을 선택합니다
  5. 실행한 뒤 성공하면 결과를 확인합니다

2~4의 순서의 이미지는 다음과 같습니다.

Cloudwatch Agent 구성 파일 설정

에이전트는 설치했지만 아직 정지 상태입니다.
이어서 수집할 지표와 로그를 지정하는 구성 파일을 작성하겠습니다.
구성 파일은 SSM의 Parameter Store에 저장되어 사용됩니다.
구성 파일을 작성하기 위해선 인스턴스에 접속 후, 구성 파일 작성 마법사를 이용하거나 직접 작성합니다.
마법사를 사용하여 작성하면 기본적인 내용으로 빠르게 작성할 수 있으며 직접 작성하면 필요한 지표나 로그마다 따로 지정하여 작성할 수 있습니다.
마법사를 이용하여 작성한다면 공식 페이지를 참고해주세요.
수동으로 작성다면 사용할 수 있는 파라미터는 공식 문서를 참고해주세요.

  • agent
    • agent의 설정입니다. 읽을 파일의 권한에 맞는 유저 선택이 필요합니다
  • logs의 collect_list
    • file_path의 로그 파일을 log_group_name / log_stream_name 이라는 이름으로 Cloudwatch Logs에 게시합니다
    • 감시가 필요한 로그의 패스를 지정하면 됩니다
  • metrics
    • Cloudwatch의 지표에 게시할 metrics입니다
{
        "agent": {
                "metrics_collection_interval": 60,
                "region": "ap-northeast-2",
                "run_as_user": "cwagent"
        },
        "logs": {
                "logs_collected": {
                        "files": {
                                "collect_list": [
                                        {
                                                "file_path": "/var/log/httpd/access_log",
                                                "log_group_name": "CWTEST",
                                                "log_stream_name": "accessLog"
                                        }
                                ]
                        }
                }
        },
        "metrics": {
                "metrics_collected": {
                        "disk": {
                                "measurement": [
                                        "used_percent"
                                ],
                                "metrics_collection_interval": 60,
                                "resources": [
                                        "*"
                                ]
                        },
                        "mem": {
                                "measurement": [
                                        "mem_used_percent"
                                ],
                                "metrics_collection_interval": 60
                        }
                }
        }
}

이렇게 작성한 json 확장자의 구성 파일을 인스턴스에 저장하여 참조하거나 위에서 언급한 Parameter Sotre에 저장하여 참조하여 사용할 수 있습니다.
공식 문서의 추천 방법은 Parameter Store에 저장하여 참조하는 방식입니다.

그럼 위의 내용으로 구성 파일을 설정하겠습니다.

  1. AWS Systems Manager 서비스의 좌측에 있는 Parameter Store파라미터 생성 을 클릭합니다
  2. 이름을 지정하고 에 구성 파일의 내용을 입력 후 파라미터를 생성합니다
  3. AWS Systems Manager 서비스의 좌측에 있는 Run Command명령 실행 을 클릭합니다
  4. 명령 목록에서 AmazonCloudWatch-ManageAgent를 클릭하고 Optional Configuration Location
    방금 Parameter Store에 저장한 파일의 이름을 입력합니다
  5. 아래의 대상 에서 수동으로 인스턴스 선택을 고른 후 설치할 인스턴스를 선택합니다
  6. 출력 옵션의 S3 버킷에 쓰기 활성화는 필요하다면 결과를 출력할 버킷을 선택합니다
  7. 실행한 뒤 성공하면 결과를 확인합니다

2번 작업의 이미지는 다음과 같습니다.

4~6번 작업의 이미지는 다음과 같습니다.

설정이 완료된 후 Cloudwatch의 로그 그룹을 보시면 로그가 추가되어 있는 것을 확인할 수 있습니다.

로그에서 특정 문자 감시하기

로그를 성공적으로 읽어왔으니 특정 문자를 감시하도록 하겠습니다.
로그 그룹의 지표 필터라는 기능을 이용하여 특정한 IP가 접근하면 경보가 발생하도록 설정하겠습니다.

설정하기

작업에 사용하는 CWTEST라는 로그 그룹명은 구성 파일에서 지정한 log_group_name 라는 옵션의 값입니다.
그리고 accessLog 라는 로그 이름은 log_stream_name의 값입니다.

  1. CloudWatch 서비스의 로그 그룹 탭에서 CWTEST(log_group_name)에 들어간 뒤 accessLog(log_stream_name)를 체크합니다
  2. 오른쪽 위의 작업 에서 지표 필터 생성을 클릭합니다
  3. 패턴 필터링에 대상 IP를 지정하고 테스트할 로그를 지정합니다
  4. 패턴 테스트를 하여 결과에 문제가 없으면 다음으로 넘어갑니다
  5. 이름 필터링, 지표 네임스페이스, 지표 이름, 지표 값을 지정하고 다음으로 넘어간 후 생성합니다 이름 필터링은 본 필터링의 이름이며 지표 네임스페이스는 지표의 그룹이름, 지표 이름은 해당 지표가 지표 목록에서의 이름, 지표 값은 지표의 단위입니다.

작성 후 로그 그룹을 보시면 감시하려는 로그 그룹에 지표 필터가 한 개 생긴 것을 확인 할 수 있습니다.

이어서 경보를 설정하겠습니다.
기존 AWS SNS를 활용해도 되고 경보를 생성하면서 같이 생성하여도 됩니다.

  1. 생성된 지표 필터를 클릭하여 목록을 확인한 후 대상 지표필터를 체크 후 경보 생성을 클릭합니다
  2. 액세스하면 바로 알리도록 보다 크거나 같음에 임계값으로 1을 지정합니다
  3. 기존 SNS가 설정되어 있다면 기존의 SNS를 사용하고 아니라면 새 주제 생성으로 새로운 구독을 생성한 후 다음으로 넘어갑니다
    새롭게 구독을 생성하면 인증 메일이 날아오니 확인합니다
  4. 경보 이름을 설정한 후 경보 생성을 완료합니다

이후 서버에 해당 IP가 접근하면 이미지와 같이 이메일이 날아온 것을 확인할 수 있습니다.

마치며

해당 글에선 단순하게 서버에 특정한 IP가 접근하면 경보가 발생하도록 설정하였습니다.
하지만 이를 응욯아면 어떠한 어플리케이션 등의 로그를 수집하여 필터링 문자를 알맞게 설정하면 특수한 문자가 발생하였을 때 경보를 발생시키는 것 또한 가능하므로 필요에 따라 응용해주세요.
긴 글 읽어주셔서 감사합니다.
오타 및 내용 피드백은 언제나 환영합니다. must01940 지메일 로 부탁드립니다!