AWS 기술 블로그

Amazon CloudFront의 원본 액세스 제어를 활용하여 Lambda 함수 URL을 안전하게 관리하기

이 글은 AWS Networking & Content Delivery Blog에 게시된 Secure your Lambda function URLs using Amazon CloudFront origin access control by Karan Desai and Tanya Pahuja을 한국어 번역 및 편집하였습니다.

2022년 AWS는 별도의 서비스를 학습하고 구성, 운영할 필요 없이 AWS Lambda 함수에 대해 HTTPS 엔드포인트를 간단히 구성할 수 있는 Lambda 함수 URL을 출시했습니다. Lambda 함수 URL을 사용하는 애플리케이션의 성능과 보안을 향상시키고자 하는 고객은 Lambda 함수 URL 앞에 Amazon CloudFront를 배포하여 전 세계에 분포된 수백 개의 엣지 로케이션(Points of Presence, PoPs)을 통해 데이터를 전달할 수 있습니다. 그러나 이를 위해서는 Lambda 함수 URL을 CloudFront가 접근할 수 있도록 공개적으로 접근 가능하게 유지해야 했습니다. 또한, 함수 코드에서 정상적인 요청에 대한 접근을 허용하기 위해서 CloudFront가 사용자 지정 헤더의 값으로 보내는 시크릿 값을 검증하는 등의 추가적인 애플리케이션 로직을 구현해야 했습니다.

Amazon CloudFront와 AWS Lambda 간의 보안을 강화하고 기능을 보다 긴밀하게 통합하기 위한 Lambda 함수 URL에 대한 원본 액세스 제어(OAC)를 소개합니다. AWS 서명 버전 4 (SigV4)를 사용하여 지정된 CloudFront 배포에서만 Lambda 함수에 접근할 수 있도록 함으로써 Lambda 함수를 보호합니다. OAC는 이미 Amazon S3 원본과 함께 사용할 수 있으며, 이는 특정 S3 버킷에 지정된 CloudFront 배포만 접근할 수 있도록 합니다. 이제 이 OAC 기능을 Lambda 함수 URL 원본에서도 사용할 수 있습니다.

CloudFront와 Lambda 함수 URL의 결합

함수 URL은 요청 검증, 요청 조절, 사용자 지정 권한 부여자와 같은 고급 기능이 필요하지 않은 퍼블릭 엔드포인트를 가진 단일 함수 마이크로 서비스를 구현해야 하는 사용 사례에 적합합니다. 예를 들어, Webhook 핸들러, 사용자가 입력한 데이터의 유효성을 검사하는 폼 유효성 검증, 모바일 결제 처리, 광고를 적절한 위치에 노출시키는 광고 배치, 머신 러닝(ML) 추론 등에 적합합니다. Lambda 함수와 CloudFront를 결합하면 Lambda 함수 URL을 공개적으로 노출하지 않아도 될 뿐만 아니라, 전 세계적으로 분산된 콘텐츠 전송 네트워크 서비스인 CloudFront로 사용자 요청을 라우팅하여 지연 시간을 개선하고, 더 빠른 응답 시간과 더 나은 사용자 경험을 제공할 수 있습니다. 또한, CloudFront를 통해 사용자 정의 도메인 이름을 정의하고, TLS를 통한 HTTPS 전송을 활성화할 수 있습니다. AWS WAF를 활성화하여 악의적인 봇과 일반적인 애플리케이션 취약점으로부터 애플리케이션을 보호하며, 추가 비용 없이 AWS Shield Standard를 통해 DDoS로부터 보호 받을 수 있습니다. OAC를 사용하면 의도하지 않은 사용자가 함수 URL에 직접 접근하는 것을 차단할 수 있습니다. OAC를 활성화하면 공격받을 수 있는 영역을 최소화하여 보안 태세가 향상됩니다. 더 나아가 모든 요청이 이러한 보안 서비스가 적용되는 CloudFront를 거쳐야 하므로 AWS Shield와 AWS WAF 보호를 받을 수 있습니다.

그림 1: CloudFront OAC를 활용한 Lambda 함수 URL에 대한 접근 제한

Lambda 함수 URL에 OAC 구성

Lambda 함수 URL과 CloudFront에서 OAC를 사용하는 방법을 알아보겠습니다. 이미 Lambda 함수에서 실행 중인 서버리스 애플리케이션을 사용하거나 새 Lambda 함수를 만들어서 시작할 수 있습니다. 이 게시글에서는 AWS 관리 콘솔을 사용하지만, AWS Command Line Interface(AWS CLI), AWS CloudFormation 또는 AWS SDK를 선호에 따라 사용할 수 있습니다. AWS CLI를 사용하는 경우 Lambda 함수를 생성하는 AWS 리전을 확인해야 합니다. AWS CLI 프로파일에 구성된 리전이 Lambda 함수를 생성하는 리전과 동일해야 명령어를 실행할 수 있기 때문입니다.

기존 Lambda 함수 URL에 OAC를 활성화하려면 1단계를 건너뛰고, 기존 함수 URL을 확인한 후 2단계부터 진행하시기 바랍니다.

1단계: 함수 URL이 활성화된 Lambda 함수 생성하기

  1. Lambda 콘솔의 함수 페이지로 이동합니다.
  2. 함수 생성을 선택합니다.
  3. 새로 작성을 선택합니다.
  4. 기본 정보 영역에서 함수 이름으로 myLambdaFunction을 입력합니다.
  5. 런타임에서 Node.js 20.x 또는 Python 3.12를 선택합니다.
  6. 고급 설정 부분을 열어 함수 URL 활성화를 체크합니다. 인증 유형AWS_IAM으로 유지합니다.
  7. 다른 설정은 기본값으로 두고 함수 생성을 선택합니다.

그림 2: Lambda 함수에 대한 함수 URL 생성

  1. 다음 화면에서 구성 탭으로 이동한 다음, 함수 URL을 선택합니다. 함수 URL을 복사하여 저장합니다. 나중 단계에서 이 URL이 사용됩니다.

그림 3: Lambda 함수 URL 가져오기

2단계: CloudFront OAC 생성하기

  1. AWS 관리 콘솔에 로그인하고 CloudFront로 이동합니다.
  2. 화면 왼쪽 메뉴에서 원본 액세스를 선택합니다.
  3. 제어 설정 생성을 선택합니다.
  4. OAC 생성 시에는 다음과 같이 진행합니다.
    1. OAC의 이름설명(선택 사항)을 입력합니다.
    2. 서명 동작에서, 서명 요청(권장)의 옵션을 그대로 유지하는 것이 좋습니다. 자세한 내용은 오리진 액세스 제어를 위한 고급 설정을 참조하시기 바랍니다.
  5. 원본 유형에서 Lambda를 선택합니다.
  6. 생성을 선택합니다.

그림 4: Lambda 함수를 원본으로 OAC 구성

3단계: CloudFront 배포 생성하기

  1. CloudFront 콘솔 왼쪽 메뉴에서 배포를 선택하고, 배포 생성을 선택합니다.
  2. 오리진 도메인 드롭다운 목록을 무시하고, https://와 마지막 슬래시를 제외한 Lambda 함수 URL을 입력합니다. 예: xyzabcdefghijk.lambda-url.region-name.on.aws
  3. 원본의 프로토콜로 HTTPS만 해당을 선택합니다.
  4. 원본 액세스 제어 드롭다운에서 이전 단계에서 생성한 OAC 를 선택합니다.
  5. 캐싱 정책이 자동으로 CachingDisabled로 설정된 것을 확인할 수 있습니다. 이는 Lambda 함수 URL에 권장되는 설정입니다. Lambda 함수의 응답을 캐싱해야 하는 특정 요구 사항이 있는 경우, 사용자가 변경할 수 있습니다.
  6. 다른 설정은 기본값을 그대로 유지합니다. 웹 애플리케이션 방화벽(WAF) 설정을 보안 보호 활성화(선택 사항이지만 권장)로 선택하여 AWS에서 모든 애플리케이션에 권장하는 기본 보호 기능을 포함한 AWS WAF 웹 ACL을 CloudFront에서 생성 및 구성하도록 합니다.
  7. 배포 생성을 선택합니다.

그림 5: CloudFront 배포 구성

  1. CloudFront에서 Lambda 함수에 접근할 수 있도록 하기 위해서, 함수 정책을 업데이트해야 합니다. 현재 Lambda 콘솔에서 AWS Identity and Access Management(IAM) 정책 문을 직접 편집할 수 없기 때문에 CLI 명령을 실행합니다. 배포 생성을 클릭한 후 나오는 다음 화면 상단에 표시된 CLI 명령을 복사합니다. <YOUR_FUNCTION_NAME>을 Lambda 함수 이름으로 대체하시기 바랍니다. 복사한 명령은 다음과 비슷합니다.

    aws lambda add-permission \
    --statement-id "AllowCloudFrontServicePrincipal" \
    --action "lambda:InvokeFunctionUrl" \
    --principal "cloudfront.amazonaws.com" \
    --source-arn "arn:aws:cloudfront::1234567890:distribution/ABCDEFGHIJ" \
    --function-name my_example_function

  2. 복사한 명령을 터미널 창에서 실행합니다. AWS CLI가 구성된 로컬 장비에서 실행하거나 AWS CloudShell을 사용할 수 있습니다. AWS CloudShell은 브라우저 기반의 사전 인증된 Shell로 AWS 콘솔에서 직접 실행할 수 있습니다. 복사한 명령은 OAC가 Lambda 함수와 작동할 수 있는 필수 권한을 생성하고, 생성된 정책 문을 보여주는 응답을 합니다.

그림 6: Lambda 정책 문을 생성하기 위한 CLI 명령문

4단계: Lambda 함수 검토하기

  1. Lambda 콘솔로 이동하여 CloudFront 배포의 원본으로 사용한 Lambda 함수를 선택합니다.
  2. 구성 탭으로 이동하여 권한을 선택합니다. 리소스 기반 정책 설명으로 스크롤 하면 새로 추가된 권한을 확인할 수 있습니다. 문 ID를 선택하고 정책 보기를 선택하면 다음 예시와 유사한 정책문을 볼 수 있습니다.
    {
      "Version": "2012-10-17",
      "Id": "default",
      "Statement": [
        {
          "Sid": "AllowCloudFrontServicePrincipal",
          "Effect": "Allow",
          "Principal": {
            "Service": "cloudfront.amazonaws.com"
          },
          "Action": "lambda:InvokeFunctionUrl",
          "Resource": "arn:aws:lambda:us-east-1:<ACCOUNT_ID>:function:<FUNCTION_NAME>",
          "Condition": {
            "ArnLike": {
              "AWS:SourceArn": "arn:aws:cloudfront::<ACCOUNT_ID>:distribution/ABCDEFGHIJ"
            }
          }
        }
      ]
    }

Lambda 함수 URL에 OAC 적용 여부 테스트

CloudFront를 통해 Lambda 함수 URL에 접근할 수 있는지 테스트하기 위해 명령 프롬프트에서 curl 요청을 수행합니다. 로컬 장비의 터미널을 사용하거나 AWS 콘솔 하단에서 CloudShell을 사용합니다. 다음 curl 명령을 실행하되, CLOUDFRONT_DOMAIN_NAME을 CloudFront 배포의 도메인 이름으로 변경합니다. 도메인 이름을 찾아야 하는 경우, 콘솔에서 CloudFront로 이동하여 배포를 선택합니다. 일반 탭에서 배포 도메인 이름을 복사합니다.

curl <CLOUDFRONT_DOMAIN_NAME> -kvv

이 요청에 대해서 아래와 같이 200 OK 응답을 받아야 합니다.

$ curl https://d1234abcd.cloudfront.net/ -kvv
<<response truncated>>
< HTTP/2 200
< content-type: application/json
< content-length: 20

이는 Lambda 함수 URL에 CloudFront를 통해 접근할 수 있음을 보여줍니다.

이제 Lambda 함수 URL로 직접 요청하는 curl 명령을 실행합니다.

curl <LAMBDA_FUNCTION_URL> -kvv

OAC가 올바르게 구성되어 있다면 이 요청에 대해 403 응답을 받아야 합니다. CloudFront를 통하지 않고 Lambda 함수 URL에 직접 접근하려고 하면 OAC가 차단하기 때문입니다. 반환받은 403 응답은 다음과 비슷합니다.

$ curl https://abcd1234.lambda-url.region-name.on.aws/ -kvv
<<response truncated>>
< HTTP/1.1 403 Forbidden
< Content-Type: application/json
< Content-Length: 23
{"Message":"Forbidden"}

이는 Lambda 함수 URL에 직접 접근할 수 없고, Lambda에서 실행 중인 서버리스 애플리케이션에 대한 접근을 제한하기 위한 CloudFront 배포의 원본 액세스 제어가 성공적으로 구성된 것을 보여줍니다.

결론

이번 게시글을 통해 원본 액세스 제어를 사용하여 Lambda 함수에 추가적인 보안을 적용하고 인가되지 않은 접근을 차단하는 방법에 대해 알아보았습니다. 이러한 원본 접근 제한은 서버리스 애플리케이션의 전반적인 보안을 강화하고, CloudFront의 기능과 Lambda 함수를 연계하여 사용자 요청에 대한 세부 제어를 가능하게 합니다.

AWS Lambda 함수 URL 오리진에 대한 CloudFront OAC 지원은 이제 CloudFront 중국 지역을 제외한 전 세계에서 사용할 수 있습니다. CloudFront 콘솔, SDK, CLI 또는 AWS CloudFormation을 사용하여 OAC를 활성화할 수 있습니다. 이 기능을 사용하는 데 따른 추가 요금은 없습니다. 자세한 내용은 Amazon CloudFront 개발자 안내서를 참조하시기 바랍니다. CloudFront에 대해 더 알아보려면 Amazon CloudFront 시작하기로 이동하시기 바랍니다.

Yujin Jeong

Yujin Jeong

Yujin Jeong is a Solutions Architect at AWS based in Korea. She has a passion for helping enterprise customers navigate their cloud journey and finding the right solutions to meet their unique business needs. With her technical expertise and experience, she has helped customers achieve their cloud goals and drive business outcomes through innovative and scalable cloud solutions.