AWS Lambda + Amazon EventBridge로 보안 그룹의 풀 오픈(0.0.0.0) 규칙을 탐지하고 이메일로 통지해 봤습니다.

AWS Lambda + Amazon EventBridge로 보안 그룹의 풀 오픈(0.0.0.0) 규칙을 탐지하고 이메일로 통지해 봤습니다.

AWS Lambda + Amazon EventBridge로 보안 그룹의 풀 오픈(0.0.0.0) 규칙을 탐지하고 이메일로 통지해 봤습니다.
Clock Icon2025.06.17

안녕하세요 클래스메소드 김재욱(Kim Jaewook) 입니다. 이번에는 AWS Lambda + Amazon EventBridge로 보안 그룹의 풀 오픈(0.0.0.0) 규칙을 탐지하고 이메일로 통지해 봤습니다.

IAM 정책 및 역할 생성

먼저 Lambda 함수에 사용할 IAM 정책과 역할을 생성합시다.

Lambda 함수에서 보안 그룹으로 접근할 필요가 있기 때문에 [ec2:DescribeSecurityGroups] 권한을 할당합니다. 나머지는 이메일 통지를 위한 권한과 CloudWatch에 로그를 남기기 위한 권한입니다.

[arn:aws:sns:ap-northeast-2:xxxxxxxxxx]에는 SNS 토픽 Arn을 입력합니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:DescribeSecurityGroups"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "sns:Publish"
      ],
      "Resource": "arn:aws:sns:ap-northeast-2:xxxxxxxxxx"
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    }
  ]
}

Lambda 함수 코드 작성

IAM 정책과 역할을 생성했다면 Lambda 함수 코드를 작성합시다.

Lambda 함수의 런타임은 [Python 3.13]을 지정합니다.
[arn:aws:sns:ap-northeast-2:xxxxxxxxxx]에는 SNS 토픽 Arn을 입력합니다.

이벤트가 발생하고 해당 Lambda 함수가 실행되면, 보안 그룹의 정보를 확인하고 인바운드 규칙이 [0.0.0.0]으로 설정되어 있다면 SNS를 통해 이메일을 전송합니다.

import json
import boto3

ec2 = boto3.client('ec2')
sns = boto3.client('sns')

SNS_TOPIC_ARN = 'arn:aws:sns:ap-northeast-2:xxxxxxxxxx'

def lambda_handler(event, context):
    print("Received event:", json.dumps(event))

    # 모든 보안 그룹 조회
    response = ec2.describe_security_groups()
    security_groups = response['SecurityGroups']

    for sg in security_groups:
        group_id = sg['GroupId']
        for perm in sg.get('IpPermissions', []):
            ip_ranges = perm.get('IpRanges', [])
            for ip_range in ip_ranges:
                cidr = ip_range.get('CidrIp')
                if cidr == '0.0.0.0/0':
                    from_port = perm.get('FromPort', 'All')
                    to_port = perm.get('ToPort', 'All')
                    protocol = perm.get('IpProtocol', 'All')

                    message = (f"⚠️ 보안 경고: Security Group {group_id}이(가) "
                               f"0.0.0.0/0로 포트 오픈됨\n"
                               f"Protocol: {protocol}, Ports: {from_port} - {to_port}")
                    print(message)

                    sns.publish(
                        TopicArn=SNS_TOPIC_ARN,
                        Subject="❗보안 그룹 포트 오픈 경고",
                        Message=message
                    )

    return {
        'statusCode': 200,
        'body': 'Security Group check completed'
    }

EventBridge 규칙 생성

EventBridge 규칙에서는 보안 그룹의 인바운드 규칙을 추가할 때 발생하는 [AuthorizeSecurityGroupIngress] 이벤트를 사용합니다.

https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_AuthorizeSecurityGroupIngress.html

{
  "source": ["aws.ec2"],
  "detail-type": ["AWS API Call via CloudTrail"],
  "detail": {
    "eventName": ["AuthorizeSecurityGroupIngress"]
  }
}

결과 확인

보안 그룹을 생성할 때 인바운드 규칙에 [0.0.0.0]을 지정하면 이메일이 전송됩니다.

먼저 보안 그룹의 인바운드 규칙을 [0.0.0.0]으로 설정합시다.

jw-blgsgtest-1

시간이 지나면 이메일로 [0.0.0.0]이 설정된 보안 그룹의 ID와 포트 번호가 전송되어 옵니다.

jw-blgsgtest-2

본 블로그 게시글을 읽고 궁금한 사항이 있으신 분들은 jaewookkim533@yahoo.com로 보내주시면 감사하겠습니다.

문의 사항은 클래스메소드 코리아로!

클래스메소드 코리아에서는 다양한 세미나 및 이벤트를 진행하고 있습니다.
진행중인 이벤트는 아래 페이지를 참고해주세요.

https://classmethod.kr/board/library

AWS에 대한 상담 및 클래스 메소드 멤버스에 관한 문의사항은 아래 메일로 연락주시면 감사드립니다!
Info@classmethod.kr

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.