RDS 퍼블릭 액세스 설정을 감지하고 이메일로 통지
안녕하세요 클래스메소드 김재욱(Kim Jaewook) 입니다. 이번에는 RDS 퍼블릭 액세스 설정을 감지하고 이메일로 통지하는 구성을 만들어 봤습니다.
IAM 정책 및 역할 생성
IAM에는 Lambda 함수의 로그를 기록하기 위한 CloudWatch 권한과 이메일 전송을 위한 SNS 권한 그리고 생성한 DB 인스턴스에 대한 정보를 받아오기 위한 DescribeDBInstances 권한을 할당합니다.
[arn:aws:sns:ap-northeast-2:xxxxxxxxxx]에는 SNS 토픽 Arn을 입력합니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"rds:DescribeDBInstances"
],
"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 함수 생성 및 코드 작성
EventBridge에서 이벤트가 발생하면, Lambda 함수가 트리거 됩니다. 해당 Lambda 함수에서는 DB 인스턴스 ID와 퍼블릭 액세스 여부, 이벤트 이름 등을 추출하여 이메일로 전송합니다.
[arn:aws:sns:ap-northeast-2:xxxxxxxxxx]에는 SNS 토픽 Arn을 입력합니다.
import json
import boto3
sns = boto3.client('sns')
rds = boto3.client('rds')
SNS_TOPIC_ARN = 'arn:aws:sns:ap-northeast-2:xxxxxxxxxx'
def lambda_handler(event, context):
print("Received event:", json.dumps(event))
detail = event.get('detail', {})
request_params = detail.get('requestParameters', {})
db_instance_id = request_params.get('dBInstanceIdentifier', 'unknown')
public_access = request_params.get('publiclyAccessible', False)
print(f"DBInstanceIdentifier: {db_instance_id}, PubliclyAccessible: {public_access}")
if public_access:
subject = "⚠️ RDS 퍼블릭 액세스 설정 감지"
message = f"""
🔒 보안 경고: RDS 인스턴스가 퍼블릭하게 설정되었습니다.
- DB 인스턴스 ID: {db_instance_id}
- 퍼블릭 액세스: {public_access}
- 이벤트 이름: {detail.get('eventName')}
- 호출자: {detail.get('userIdentity', {}).get('arn')}
- 리전: {event.get('region')}
- 시간: {event.get('time')}
보안을 위해 즉시 설정을 확인하세요.
"""
sns.publish(
TopicArn=SNS_TOPIC_ARN,
Subject=subject,
Message=message
)
return {
'statusCode': 200,
'body': f"Checked RDS instance {db_instance_id}, public access: {public_access}"
}
EventBridge 규칙 생성
EventBridge 규칙에서는 [CreateDBInstance]와 [ModifyDBInstance] 이벤트 발생 시 Lambda 함수가 실행되도록 설정합니다.
즉, RDS가 생성되거나 수정될 때 해당 이벤트가 감지되며, Lambda 함수가 이를 처리합니다.
이 Lambda 함수는 퍼블릭 액세스 설정(PubliclyAccessible)이 활성화되어 있는지 확인하고, 활성화된 경우 SNS를 통해 이메일 알림을 전송하는 구조입니다.
{
"source": ["aws.rds"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventName": ["CreateDBInstance", "ModifyDBInstance"]
}
}
결과 확인
먼저 테스트로 RDS를 생성할 때 퍼블릭 액세스를 활성화한 상태로 생성해 봅시다.
RDS 생성하자 이메일로 퍼블릭 액세스 설정 감지 통지가 날아온 것을 확인할 수 있습니다. RDS를 생성했을 때 발생하는 [CreateDBInstance]를 이메일에서 확인할 수 있습니다.
이번에는 퍼블릭 액세스 거부한 RDS를 수정하여 퍼블릭 액세스를 허용해 봅시다.
기존 RDS를 수정하자 [ModifyDBInstance] 이벤트가 발생하고, 퍼블릭 액세스가 허용되었다는 이메일이 날아옵니다.
마지막으로 CloudTrail을 통해 흐름을 확인해 보면, RDS가 생성되고서 로그 그룹과 로그가 생성된 것을 확인할 수 있습니다. 여기서 로그 그룹이 생성된 것은 Lambda 함수가 실행되었다는 것을 의미합니다. 이어서 RDS에 수정이 일어나자 또 로그가 생성된 것을 확인할 수 있습니다.
본 블로그 게시글을 읽고 궁금한 사항이 있으신 분들은 jaewookkim533@yahoo.com로 보내주시면 감사하겠습니다.
문의 사항은 클래스메소드 코리아로!
클래스메소드 코리아에서는 다양한 세미나 및 이벤트를 진행하고 있습니다.
진행중인 이벤트는 아래 페이지를 참고해주세요.
AWS에 대한 상담 및 클래스 메소드 멤버스에 관한 문의사항은 아래 메일로 연락주시면 감사드립니다!
Info@classmethod.kr