AWS 환경에서 서비스를 구성 후 사용하다보면 Security Group 에 특정 IP List 를 자동으로 업데이트해서 관리해야하는 경우가 종종 발생합니다. 예를 들면 CloudFront 를 이용해서 웹 서비스를 구성한 경우 Origin ALB 나 EC2 인스턴스에 적용된 Security Group 은 별도로 꼭 필요하지 않다면 CloudFront 에서 유입되는 웹 트래픽만을 허용하고 인터넷에서 유입되는 웹트래픽은 차단하는 것이 바람직합니다. 또한, Route53 에서 Health Check 기능을 사용하는 경우에도 Health Check 의 대상이 되는 ALB 혹은 EC2 인스턴스에서 모든 트래픽을 허용하는 것이 아니라 선택적으로 트래픽을 허용하고 그 중 Route53 의 Health Check 에 사용되는 IP 들은 반드시 추가해주는 등의 설정이 필요합니다.
이와 같은 설정 관리를 위해서는 CloudFront 나 Route53 Health Check 에 사용되는 Amazon IP List 를 발췌하여 Security Group 의 Inbound Rule 에 추가하고 만일 이 IP List 에 변경사항이 있다면 변경사항을 Security Group 에 반영해주는 작업이 필요한대요. 언제 얼마나 이 Amazon IP List 가 변경될지 알 수 없기 때문에 이 변경사항을 수작업으로 관리하는 것은 비현실적이고 관리적으로 어려움이 많습니다. 따라서, 자동화된 방법에 따라 IP 정보를 수집하고 수집된 IP 정보를 Security Group 에 반영하는 프로세스를 갖는 것이 중요할텐데요.
이와 같은 프로세스는 다음과 같은 절차에 따라 구성할 수 있을 것 같습니다.
- 관리 대상 IP 리스트 수집
: Amazon 에서 관리하는 AWS 서비스 별 공인 IP 목록은 아래의 링크를 통해 관리되고 공개되어 있습니다. 사용자는 아래에 공개된 IP 목록 중 필요한 AWS 서비스나와 리전을 선택하여 IP 리스트를 수집하면 됩니다.
https://ip-ranges.amazonaws.com/ip-ranges.json - 관리 대상 서비스 확인
: 예를 들어 CloudFront 의 IP 를 허용하고자하는 경우 위 IP 목록에서 “CLOUDFONT” 서비스에 해당하는 모든 IP 를 허용하면되고 Route53 Health Check 를 허용하고자 하는 경우라면 “ROUTE53_HEALTHCHECKS” 서비스 중 Health Check 를 사용하도록 설정한 Region 에 해당하는 모든 IP 를 허용하면 됩니다. - 주기적으로 수집된 IP 를 설정에 반영
: 자동으로 수집된 IP 리스트는 Security Group 에 반영되도록 구성하여야 합니다. 이 때 2가지 방법을 사용할 수 있는데 첫번째는 Security Group 의 Rule 을 직접 수정하여 IP 리스트를 반영하는 것이고 두번째는 최근 추가된 Managed Prefix List 를 이용하여 수집된 IP 리스트를 Managed Prefix List 에 반영하는 방법입니다.
그럼 위에 설명된 3가지 단계를 설정해보도록 하겠습니다.
아래 링크에 있는 AWS-Samples 에 CloudFront 의 IP 를 추출하는 Sample Code 가 있어 이 코드를 기반으로 하여 AWS Lambda 를 이용해 추출해보도록 하겠습니다.
사전 준비
조건 1. 이 코드는 Managed Prefix 를 사용하는 것이 아니라 Security Group 설정을 직접 변경하는 것으로 이 코드의 사용을 위해서는 각 Security Group 에 아래와 같은 3개의 Tag 가 설정되어야 합니다.
- Global Ingress 용 Security Group
- Name = cloudfront_g
- AutoUpdate = true
- Protocol = http
2. Regional Ingress 용 Security Group
- Name = cloudfront_r
- AutoUpdate = true
- Protocol = http
조건 2. 이 코드는 AmazonIpSpaceChanged 라는 SNS Topic 을 구독후에 사용하여야 합니다.
조건 3. Lambda Function 에서 사용할 적절한 권한이 부여되어야 합니다.
참고. 저는 서울 리전을 선택하도록 하겠습니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupIngress"
],
"Resource": "arn:aws:ec2:ap-northeast-2:0123456789012:security-group/*"
},
{
"Effect": "Allow",
"Action": "ec2:DescribeSecurityGroups",
"Resource": "*"
},
{
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Effect": "Allow",
"Resource": "arn:aws:logs:*:*:*"
}
]
}
Security Group 생성
Lambda Function 에 의해 자동으로 Inbound Rule 이 업데이트 되도록 구성하기 위해서는 먼저 적절한 Tag 값이 설정된 Security Group 이 생성되어야 합니다.
Tag 설정 규칙은 사전 준비 항목에 언급된 것처럼 설정해주도록 하고 CloudFront 의 경우 Global 과 Regional 서비스가 있으므로 각각 설정하도록 합니다.
Lambda Function 생성
CloudFront 서비스의 IP 를 추출한 후 자동으로 Security Group 에 설정으로 반영하는 Python Code 는 위쪽에 위치한 AWS-samples Github 에서 제공하는 코드를 그대로 사용하도록 하겠습니다.
Lambda Function 생성 시 위에 언급되어 있는 Security Group 설정을 위한 IAM Permission 도 Lambda Function 에 사용되는 Role 에 추가해 주었습니다.
SNS Topic 구독
Lambda Function 을 생성한 후에는 Amazon IP Range 에 변경이 있을 때마다 해당 Lambda Function 이 Triggering 될 수 있도록 SNS Topic 을 구독하여야 합니다. IP Range 변경과 관련한 SNS 를 구독하기 위해서는 아래의 절차를 따르면 됩니다.
- 리전을 N.Virginia ( us-east-1 ) 선택.
IP Range 업데이트 SNS 구독은 반드시 N.Virginia 에서만 가능합니다. - 아래와 같이 Subscription 생성
Topic ARN 에 아래 ARN 입력
arn:aws:sns:us-east-1:806199016981:AmazonIpSpaceChanged
Endpoint 에는 위에 생성한 Lambda Function 을 선택
동작확인
Lambda Function 의 테스트 항목에 아래의 테스트 이벤트를 입력한 후 저장합니다.
{
"Records": [
{
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:EXAMPLE",
"EventSource": "aws:sns",
"Sns": {
"SignatureVersion": "1",
"Timestamp": "1970-01-01T00:00:00.000Z",
"Signature": "EXAMPLE",
"SigningCertUrl": "EXAMPLE",
"MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
"Message": "{\"create-time\": \"yyyy-mm-ddThh:mm:ss+00:00\", \"synctoken\": \"0123456789\", \"md5\": \"7fd59f5c7f5cf643036cbd4443ad3e4b\", \"url\": \"https://ip-ranges.amazonaws.com/ip-ranges.json\"}",
"Type": "Notification",
"UnsubscribeUrl": "EXAMPLE",
"TopicArn": "arn:aws:sns:EXAMPLE",
"Subject": "TestInvoke"
}
}
]
}
테스트 이벤트가 저장된 후 실행하면 아래와 같은 MD5 관련 에러가 발생할 것입니다.
로그에 나타난 MD5 값을 복사한 후 테스트이벤트에 그 값을 붙여넣습니다.
MD5 값이 수정된 후 다시 테스트를 진행하면 Lambda Function 이 정상동작하는 것을 확인하실 수 있고 정상적으로 실행되었다면 아래와 같이 CF 관련 Security Group 에 CloudFront 의 IP List 가 Inbound Rule 에 추가되어 있는 것을 확인하실 수 있습니다.
Route53 HealthCheck 를 위한 IP List 자동 업데이트
Route53 HealthCheck 사용을 위해 허용되어야하는 IP List 를 추출하는 과정은 CloudFront 와 동일한 순서에 따라 진행하되 Lambda Function Code 만 아래 링크에 있는 Code 처럼 약간 수정하여 적용하였습니다.
코드만 변경하고 코드에 반영된 Tag 값만 아래와 같이 변경하여 Security Group 을 생성 동일한 과정을 진행하면 아래와 같이 전체 IP List 중 ROUTE53_HEALTHCHECKS 서비스에 해당하는 IP 가 자동으로 업데이트되는 것을 확인할 수 있습니다.
감사합니다.