AWS/Monitoring

AWS Monitoring[CloudTrail] - AWS Console Login 시 Slack 알람

TTwY 2021. 9. 16. 16:36
728x90
반응형

AWS Console Login 발생 시 Slack을 통해 Message를 받는 방법에 대해서 알아보겠습니다.

AWS에서는 Root Account로 Console에 접속하는 방법 대신 IAM을 통한 Console 접속을 통한 작업을 권장합니다.

 

현업에서 Root Account로 작업하는 경우는 없습니다. IAM에 권한을 부여하여 자기의 권한에 맞는 작업을 진행하고 있습니다.

 

아래와 같은 구성을 통하여 Slack Message를 받아 보도록 하겠습니다.

 

 검정선의 행동이 이루어 질 때 파란색 선의 절차에 따라 Slack으로 Message를 받게 됩니다.

 

구성진행 순서

1. CloudTrail 생성 및 설정

2. Lambda Function 만들기

3. CloudWatch > Events > Rules 만들기

4. Lambda Code 수정하기

5. 테스트

6. (번외)Rules를 수정하여 세밀하게 컨트롤 하기

 

1. CloudTrail 생성 및 설정

CloudTrail을 생성해야 여기서 발생하는 CloudTrail 정보를 가지고 Slack으로 Message를 받을 수 있습니다.

CloudTrail > Trail > Create Trail 순서로 클릭합니다.

Trail name 작성 및 이미 Trail 용 S3 버킷을 생성하였다면 Use exsiting S3 bucket을 선택, 위와 같이 신규로 생성한다면 Create new S3 bucket를 선택 후 Trail log bucket and folder를 유일한 값으로 작성해주면 됩니다.

디폴트로 Log file SSE-KMS encryption 이 선택되어있지만 저는 따로 암호화를 하지는 않을 것이기 때문에 체크를 해제 했지만 암호화가 필요하신 분들은 info를 눌러 본인에 맞게 설정을 하시기를 바랍니다.

 

특별히 추가 해야 할 부분은 없기 때문에 Next 하였습니다.

위와 같은 내용이 생긴다면 CloudTrail 생성은 모두 완료되었습니다.

 

2. Lambda Function 만들기

Slack Message를 받기 위한 Lambda Function 생성 및 Slack 기본 설정은 아래의 글에 자세하게 설명되어 있으니 상세 설정 부분에 대해서 아래 글을 보고 초반부 세팅을 하고 다시 본글로 오시면 됩니다.

https://longtermsad.tistory.com/49

 

AWS Monitering[CloudWatch] - 1. CloudWatch Alarm을 Slack 연동하기

AWS에서는 Amazon CloudWatch Alarm(경보)를 사용하여 모니터링 할 수 있으며 Alarm(경보)를 설정하고 해당 내용에 대해서 알람을 받을 수 있습니다. https://docs.aws.amazon.com/ko_kr/AmazonC..

longtermsad.tistory.com

 

Lambda Function을 만들어 보도록 하겠습니다. 여기서 가장 중요한 설정 사항이 있습니다.

리전을 반드시 N.Virginia(us-east-1)로 변경하여 작업을 수행하여야 합니다. CloudTrail이나 글로벌 서비스에 대한 CloudWatch 서비스는 N.Virginia(us-east-1)에 대부분 기록되게 됩니다.(예외가 있는경우가 있으나 거의 대부분 N.Virginia에 기록된다고 보시면 됩니다.)

 

[22년부터 IAM쪽의 Console login의 리다이렉션이 https://us-west-2.signin.aws.amazon.com/ << us-west-2(Oregon)로 되는 것이 확인됩니다. 그렇기 때문에 N.Virginia에 적용 후 us-west-2(Oregon)에도 같은 작업을 진행해주셔야 누락이 발생하지 않습니다.]

위와 같이 람다 함수를 생성합니다.

 

위와 같은 Lambda 기본 설정은 위쪽에 링크해둔 글에서 더욱 자세히 설명하였으니, 참조 부탁드립니다.

 

3. CloudWatch > Events > Rules 만들기

AWS Console을 이용해서 접속 했을 때 그 이벤트가 발생했을 때 람다 펑션에 트리거가 발생 할 수 있도록 설정을 하는 부분입니다.

Create Rule 클릭하여 Rule을 생성하도록 하겠습니다.

 

Service Name을 AWS Console Sign-in으로 그러면 Event Type 선택 항목이 여러개 나옵니다. 그 중에 Sign-in Event를 선택하여 진행합니다.

Targets 부분에서는 Lambda function 선택 CloudWatch Event 만들기 전에 미리 만들어둔 Function을 선택합니다.

필수 값인 Name을 작성 후 Create rule을 클릭합니다.

위와 같이 초록색 표시로 리스트로 나오게 되면 설정 완료입니다.

 

4. Lambda Code 수정하기

 

Rules을 설정하여 Lambda에 Trigger를 걸었습니다. 이전에 만들어둔 Lambda Function을 새로고침 하면 Trigger 부분에 Event Bridge(CloudWatch event)가 자동으로 설정되어 있는 것을 확인할 수 있습니다.

Trigger 설정도 자동으로 설정 됨으로, Code를 수정하여 Slack으로 message를 날릴 수 있도록 해보겠습니다.

import boto3
import json
import logging
import os
import time

from datetime import datetime
from datetime import timedelta
from base64 import b64decode
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError

HOOK_URL = os.environ['HOOK_URL']
SLACK_CHANNEL = os.environ['slackChannel']


logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    
    logger.info("Event: " + str(event))
    data = event['detail']
    
    accountType = data['userIdentity']['type']
    
    # Root 인지 IAMUser 인지 구분
    if accountType == "Root":
        accountUserName = "Root"
    elif accountType == "IAMUser":
        accountUserName = data['userIdentity']['userName']
    else:
        accountUserName = " "
        
    # KST 시간 변환
    state_login_time = data['eventTime'][:19]
    kst_login_time = datetime.strptime(state_login_time, '%Y-%m-%dT%H:%M:%S') - timedelta(hours=-9) #KST 시간 변환
    
    # Slack Message Title
    title = "[%s]%s AWS Console Login" %(accountType, accountUserName)
    
    # sourceIPAddress
    sourceIPAddress = data['sourceIPAddress']
    
    # MFA 사용 유무
    usedMFA = data['additionalEventData']['MFAUsed']
    
    # 접속 성공 유무
    loginStatusCheck = data['responseElements']['ConsoleLogin']
    
    slack_message = {
        'channel': SLACK_CHANNEL,
        'text': "*%s*\n>>>*접속시간*\n%s\n*접속 IPAddress*\n%s\n*Console Login 결과*\n%s\n*MFA 사용유무*\n%s" % (title, kst_login_time, sourceIPAddress, loginStatusCheck, usedMFA)
    }

    req = Request(HOOK_URL, json.dumps(slack_message).encode('utf-8'))
    try:
        response = urlopen(req)
        response.read()
        logger.info("Message posted")
    except HTTPError as e:
        logger.error("Request failed: %d %s", e.code, e.reason)
    except URLError as e:
        logger.error("Server connection failed: %s", e.reason)

이전 Slack 연동하기에서는 slackChannel을 Environment variables에 선언만 하고 사용하지 않았지만, 이번글에서는 사용을 한번 하기 위해 slack_message의 'channel' 부분을 추가하였습니다. 위와 같이 슬렉 채널로 구분할 필요가 있다면 위와 같은 방식으로 작성하시면 됩니다.

코드에 대한 설명은 주석으로 표시하였습니다.

 

5. 테스트

 

Lambda Code 까지 완료 하였으면 Console 접속 시 Slack을 통한 Message가 오는지 확인을 해보겠습니다. 테스트 계정 AWS Console sign out 후 재접속을 합니다.

재접속 시 Slack 에서 아래와 같은 Message가 옵니다.

Slack으로 보낼 수 있는 인자값은 더 많으므로 CloudWatch > Logs > Log groups에서 해당 Lambda Function Log를 확인하면 더 많은 인자값을 확일 할 수 있습니다. 그 값에서 본인이 필요한 값을 추출해서 Lambda Code를 수정하면 됩니다. (CloudWatch Logs를 확인했는대, 내용이 안보인다 하면 본인의 계정이 설정된 리전을 확인하시길 추천드립니다. 저는 Seoul로 되어 있어서 설정을 잘못했나 설정했던 부분을 다시 살펴보는 그런 행동을.... 했습니다 ^^)

 

6. (번외)Rules를 수정하여 세밀하게 컨트롤 하기

 

위와 같이 설정을 하면 root 및 콘솔로 접속할 수 있는 모든 IAM User들의 접속 Slack Message가 발생합니다. 보통은 어떤 특정 IAM User 나 root 콘솔 접속 등을 알기 위해서 위와 같은 설정을 많이 합니다. 일반적으로 root 계정은 사용하지 않기 때문에 root 계정으로 접속이 되었다는 것은 해킹이 되었을 가능성이 있거나 일반적이지 않은 접속이기 때문에 Console에 접속하는 특정 IAM이나 root만 콘솔 접속에 대해서 체크를 해야 할일이 더 많을 것이기 때문에 추가적으로 Rules 수정을 통하여 원하는 IAM 혹은 root만 접근하는 것에 대해서 알아보겠습니다.

위와 같이 접근해서 Edit을 클릭합니다.

Any user 에서 Specific user(s) by ARN을 선택 후 아래 칸에 ARN을 입력하면 Event Pattern Preview에 자동적으로 반영이 됩니다. 위에서는 root만 추가하였지만 필요한 IAM의 ARN을 추가로 입력하면 입력된 대상의 AWS Console 로그인에 대해서만 Slack Message를 받을 수 있습니다.

 

질문 사항이나 제가 전달한 내용이 잘못되었거나, 다른 부분이 있으면 댓글로 남겨 주시면 답변 드리도록 하겠습니다.

 

감사합니다.

 

*참고 페이지

- AWS 멀티 계정 환경에서 취약한 Security Group 설정 모니터링(https://techblog.woowahan.com/2665/)

728x90
반응형