Category: Amazon CloudFront


Lambda@Edge 정식 출시 – 엣지 기반 HTTP 호출에 대한 지능적 처리 기능

지난해 말 Lambda@Edge미리 보기를 발표하여, 고객에게 가까이 있는 (대기 시간 기반) 엣지 로케이션에서 HTTP 요청을 지능적으로 처리하는 방법에 대해 설명했습니다. 미리 보기를 사용해 본 개발자 고객들은 이를 잘 활용하면서 많은 도움이 되는 피드백을 제공했습니다. 미리보기 테스트 중에 HTTP 응답을 생성하고 CloudWatch 통계를 지원하는 기능을 추가했으며, 피드백을 기반으로 향후 로드맵을 수정했습니다.

오늘 부터 Lambda@Edge가 정식 출시 되어 누구나 사용 가능합니다. 아래는 주요 사용 사례 입니다.

  • A/B 테스트를 수행하여, 쿠키 검사 및 URL 리다이렉트
  • User-Agent 헤더를 기반으로 특정 객체를 사용자에게 전송
  • HTTP 요청을 원본으로 전달하기 전에 특정 헤더를 찾아 접근 제어
  • HTTP 헤더를 추가, 삭제 또는 수정하여 사용자에게 다른 캐시 정보 사용
  • 신규 HTTP 응답 생성
  • 레거시 URL 에 대한 지원
  • HTTP 헤더 또는 URL을 수정 또는 압축하여 캐시 활용도 향상

Lambda@Edge를 활용하면 풍부한 개인적 웹 기반 사용자 환경을 만들 수 있습니다.  서버리스 기반이 빠르게 표준화 되고 있으므로, 이제 가상 서버를 프로비저닝하거나 관리 할 필요가 없습니다. 프로그래밍 코드 (Node.js로 작성된 람다 함수)를 업로드하고, Amazon CloudFront 배포판과 연결하면 됩니다. 그런 다음 원하는 CloudFront 이벤트와 함께 배포용으로 만든 CloudFront 동작 중 하나를 선택합니다.

위의 경우, 람다 함수 (가상으로 이름 붙인 EdgeFunc1)는 지정 배포 지점에서 image/*에 대한 원래 요청에 응답하여 실행합니다. 보시다시피 네 가지 CloudFront 이벤트에 대한 응답으로 코드를 실행할 수 있습니다.

뷰어 요청 (Viewer Request) -이 이벤트는 뷰어 (HTTP 클라이언트, 일반적으로 웹 브라우저 또는 모바일 앱)에서 이벤트가 도착하고 들어오는 HTTP 요청에 접근할 때 동작합니다. 각 CloudFront Edge 로케이션은 반복되는 요청에 효율적으로 응답 할 수 있도록 객체 캐시를 유지합니다. 이 특정 이벤트는 요청 된 개체가 이미 캐시되어 있는지 여부에 관계없이 동작합니다.

오리진 요청(Origin Request) -이 이벤트는 요청된 객체가 엣지 로케이션에 캐시되지 않기 때문에 오리진으로 다시 요청하려고 할 때 동작합니다. 오리진 요청 (종종 S3 버킷 또는 EC2 인스턴스에서 실행되는 코드)에 접근할 수 있습니다.

오리진 응답 (Origin Response) -이 이벤트는 오리진이 요청에 대한 응답을 반환 한 후에 동작합니다. 오리진의 응답에 접근할 수 있습니다.

뷰어 응답 (Viewer Response) – 엣지 로케이션 뷰어에 응답을 반환하기 전에 이벤트가 동작합니다. 응답에 대한 액세스 권한이 있습니다.

람다 함수는 중국을 제외한 모든 AWS 엣지 로케이션과 공개 리전에 자동 복제됩니다. HTTP 요청은 자동 실행을 위해 최적의 위치로 라우팅됩니다. 프로그램 코드를 한번에 배포하여, 전 세계 사용자가 낮은 지연 시간으로 실행할 수 있습니다.

소스 코드에는 HTTP 헤더, 쿠키, 메소드 (GET, HEAD 등) 및 URI를 비롯한 요청 및 응답에 대한 모든 접근 권한이 있습니다. 몇 가지 제한 사항에 따라 기존 헤더를 수정하고 새 헤더를 삽입 할 수 있습니다.

Lambda@Edge 직접 사용해 보기
뷰어 요청 이벤트에 응답하여 실행되는 간단한 함수를 작성해 보겠습니다. 람다 콘솔을 열고 새로운 함수를 만듭니다. Node.js 6.10 런타임을 선택하고 cloudfront 예제를 검색합니다.

cloudfront-response-generation을 선택하고 함수를 호출하는 트리거를 구성합니다.

람다 콘솔은 본 함수를 위한 운영 환경에 대한 몇 가지 정보를 제공합니다:

평소대로 함수에 대한 이름과 설명을 입력합니다.

예제에는 완전한 기능이 작동되도록 되어 있습니다. “200” HTTP 응답에 대한 간단한 동작을 생성합니다.

소스 코드를 내 자신 코드의 시작점으로 사용하여 HTTP 요청에서 흥미로운 값을 가져 와서 테이블에 표시합니다.

'use strict';
exports.handler = (event, context, callback) => {

    /* Set table row style */
    const rs = '"border-bottom:1px solid black;vertical-align:top;"';
    /* Get request */
    const request = event.Records[0].cf.request;
   
    /* Get values from request */ 
    const httpVersion = request.httpVersion;
    const clientIp    = request.clientIp;
    const method      = request.method;
    const uri         = request.uri;
    const headers     = request.headers;
    const host        = headers['host'][0].value;
    const agent       = headers['user-agent'][0].value;
    
    var sreq = JSON.stringify(event.Records[0].cf.request, null, ' ');
    sreq = sreq.replace(/\n/g, '<br/>');

    /* Generate body for response */
    const body = 
     '<html>\n'
     + '<head><title>Hello From Lambda@Edge</title></head>\n'
     + '<body>\n'
     + '<table style="border:1px solid black;background-color:#e0e0e0;border-collapse:collapse;" cellpadding=4 cellspacing=4>\n'
     + '<tr style=' + rs + '><td>Host</td><td>'        + host     + '</td></tr>\n'
     + '<tr style=' + rs + '><td>Agent</td><td>'       + agent    + '</td></tr>\n'
     + '<tr style=' + rs + '><td>Client IP</td><td>'   + clientIp + '</td></tr>\n'
     + '<tr style=' + rs + '><td>Method</td><td>'      + method   + '</td></tr>\n'
     + '<tr style=' + rs + '><td>URI</td><td>'         + uri      + '</td></tr>\n'
     + '<tr style=' + rs + '><td>Raw Request</td><td>' + sreq     + '</td></tr>\n'
     + '</table>\n'
     + '</body>\n'
     + '</html>'

    /* Generate HTTP response */
    const response = {
        status: '200',
        statusDescription: 'HTTP OK',
        httpVersion: httpVersion,
        body: body,
        headers: {
            'vary':          [{key: 'Vary',          value: '*'}],
            'last-modified': [{key: 'Last-Modified', value:'2017-01-13'}]
        },
    };

    callback(null, response);
};

핸들러를 구성하고 Basic Edge Lambda 권한을 사용하여 새 IAM 역할을 만들도록 요청합니다.

다음 페이지에서 (일반적인 람다 함수처럼) 설정을 확인하고 Create function을 클릭한다.

이렇게 하면 람다 함수가 만들어지고, 코드 배포 기능이 실행되어 각 CloudFront에 함수 복제가 시작됩니다. 내 배포 상태가 복사 기간 동안 In Progress으로 변경됩니다 (일반적으로 5-8 분).

복제가 완료되면 즉시 상태가 Deployed로 변경됩니다.

그런 다음 배포본 (https://dogy9dy9kvj6w.cloudfront.net/) 루트에 접근하면 함수가 실행되는 것을 볼 수 있습니다.

코드를 실행하려면 이미지를 클릭하십시오 (내 배포판의 루트에 링크되어 있음)!

늘 그렇듯이 간단한 예이며, 이 후 여러분이 훨씬 더 잘할 수 있다고 확신합니다. 다음은 시작하기 위한 몇 가지 아이디어입니다.

  • 복구 사이트 관리 – 전체 동적 웹 사이트를 오프라인으로 전환하고, 유지 관리 또는 재해 복구 작업 중 중요한 페이지를 Lambda@Edge 기능으로 대체 할 수 있습니다.
  • 대용량 정적 콘텐츠 – 스코어 보드, 일기 예보 또는 공공 안전 페이지를 작성하여, 엣지에서 빠르고 비용 효율적으로 사용할 수 있습니다.

멋진 것을 만들고 의견이나 블로그 게시물에서 공유하십시오. 그러면 살펴 보겠습니다.

알아 두어야 할 점들
Lambda@Edge를 응용 프로그램에서 사용하는 방법을 생각할 때 염두에 두어야 할 몇 가지 사항이 있습니다.

  • Timeouts – Origin Request 및 Origin Response 이벤트를 처리하는 함수는 3 초 이내에 완료되어야 합니다. 뷰어 요청 및 뷰어 응답 이벤트를 처리하는 기능은 1 초 이내에 완료되어야합니다.
  • 버전 관리 – 람다 콘솔에서 코드를 업데이트 한 후에는 새 버전을 게시하고 이에 대한 새로운 트리거 세트를 설정 한 다음 복제가 완료 될 때까지 기다려야합니다. 버전 번호를 사용하여 항상 코드를 참조해야합니다. $LATEST 및 별칭은 적용되지 않습니다.
  • 헤더 – 내 코드에서 볼 수 있듯이 HTTP 요청 헤더는 배열로 액세스 할 수 있습니다. 헤더는 네 가지 범주로 나뉩니다.
    • 액세스 가능 – 읽기, 쓰기, 삭제 또는 수정할 수 있음
    • 제한됨 – 원본으로 전달 필요
    • 읽기 전용 – 읽을 수는 있지만 어떤 방식 으로든 수정할 수는 없음
  • 블랙 리스트 – 코드에서 볼 수 없으며 추가 할 수 없음
  • 런타임 환경 – 런타임 환경은 각 기능에 128MB의 메모리를 제공하지만 내장 라이브러리 나 / tmp에 대한 액세스는 제공하지 않습니다.
  • 웹 서비스 접근 – Origin Request 및 Origin Response 이벤트를 처리하는 기능이 3 초 이내에 완료되어야 AWS API에 액세스하고 HTTP를 통해 컨텐츠를 가져올 수 있습니다. 이러한 요청은 항상 원본 요청 또는 응답에 대한 요청과 동 기적으로 이루어집니다.
  • 함수 복제 – 앞에서 언급했듯이 함수는 중국의 AWS 영역을 제외한 모든 공용 AWS 영역에 복제됩니다. 복제본은 람다 콘솔의 “기타”영역에서 볼 수 있습니다.

CloudFront 동작에 대해 이미 알고 있는 모든 것이 Lambda@Edge와 관련이 있습니다. 각 동작에서 여러 동작 (최대 4 개의 Lambda@Edge 함수 포함)을 사용하고, HTTP 헤더 및 쿠키 전달을 사용자 정의 할 수 있습니다. 동작을 편집하는 동안 이벤트 버전과 함수 (함수 버전을 포함하는 ARN을 통해)를 연결할 수도 있습니다.

정식 출시
Lambda@Edge는 현재 이용 가능하며, 지금 바로 사용하실 수 있습니다. 가격은 기능 호출 횟수 및 실행 시간을 기준으로 합니다 (자세한 정보는 Lambda@Edge 가격 책정 페이지 참조).

Jeff;

이 글은 Lambda@Edge – Intelligent Processing of HTTP Requests at the Edge의 한국어 번역입니다.

AWS Web Application Firewall을 통한 Application Load Balancer 보호하기

오늘은 작년에 출시한 주요 서비스 중 AWS Web Application Firewall(WAF) 및 AWS Application Load Balancer라는 두 가지 서비스에 대한 업데이트입니다.

AWS Web Application Firewall – 애플리케이션 가용성에 영향을 미치거나 과도한 자원을 소비 할 수 있는 외부 공격을 보호하는 서비스로서, 이전 출시 소식 에서 볼 수 있듯이 HTTP  요청 허용 여부 및 IP 주소를 정의하는 접근 제어 목록 (ACL), 규칙 및 조건을 사용할 수 있습니다. 선택적으로 웹 응용 프로그램의 특정 경로에 대한 접근를 허용하거나 거부 할 수 있으며, 다양한 SQL 주입 공격을 차단할 수 있습니다. 본 서비스는 Amazon CloudFront를 지원합니다.

AWS Application Load Balancer – Elastic Load Balancing에서 상위 애플리케이션 계층을 지원하는 신규 서비스로서 콘테이너 또는 EC2 인스턴스 웹 서비스 경로를 기반으로 하는 라우팅 규칙을 정의 할 수 있습니다. Application Load Balancer는 HTTP/2 및 WebSocket을 지원하며 대상 콘테이너 및 인스턴스 상태를 자세히 볼 수 있습니다. 자세한 내용은 이전 출시 소식를 참조하십시오.

WAF 및 ALB 상호 연동 하기
작년 연말 AWS WAF를 통해 Application Load Balancer 기반 응용 프로그램 보호 기능을 제공할 것이라고 발표하였으며, 오늘부터 이를 매우 빠르게 설정할 수 있으며 내부 및 외부 응용 프로그램과 웹 서비스를 모두 보호 할 수 있습니다.

예를 들어, 아래 ALB 뒤에 세 개의 EC2 인스턴스가 있습니다.

같은 리전에 접근 목록(ACL)을 간단하게 만들고 ALB와 연결합니다. 먼저 ACL의 이름을 지정하고, WAF에 지정된 CloudWatch 측정 항목에 제공하도록 설정합니다.

그런 다음 ACL에 원하는 조건을 추가합니다.

예를 들어, 질의 문자열에 대해 몇 가지 SQL 주입 필터(Injection Match)를 쉽게 설정할 수 있습니다.

필터를 만든 후에 이를 규칙 만드는 데 사용합니다.

그런 다음 규칙을 사용하여, 조건과 일치하는 요청을 차단합니다.

이를 모두 함께 사용하려면, 아래처럼 설정을 검토한 다음 ACL을 만드십시오.

Confirm and create을 클릭하면 새 규칙이 활성화되고, WAF가 내 ALB 뒤에 있는 응용 프로그램을 보호합니다.

이렇게 하면 WAF를 통해 Application Load Balancer 뒤의 EC2 인스턴스와 콘테이너를 보호할 수 있습니다.

자세히 알아보기
WAF 및 ALB를 함께 사용하는 데 대한 부분을 더 자세히 알고 싶으시면, re:Invent 중 Secure Your Web Application With AWS WAF and Amazon CloudFront 세션을 참고하시기 바랍니다.

Jeff;

이 글은 AWS Web Application Firewall (WAF) for Application Load Balancers의 한국어 번역입니다.

AWS Lambda@Edge – 미리 보기 출시

지난 주에 한 AWS 고객으로 부터 Hacker News에 올린 댓글을 통해 한 통의 메일을 받았습니다.

그는 싱글 페이지 애플리케이션(SPA)을 빠른 속도의 웹 페이지 배포가 가능한 Amazon CloudFront를 통해 Amazon S3에 정적 웹 호스팅으로 서비스를 하고 있는데, 그 페이지에서 AWS Elastic Beanstalk에서 운용중인 자체 API를 통해 개별 사용자를 위한 동적인 작업을 진행하고 있다고 합니다. 그 분이 설명한 문제는 다음과 같습니다.

최근의 웹 환경에서는 검색 엔진을 위해 별도 색인을 생성하고 Facebook 및 Twitter 내에서 콘텐츠 미리보기가 올바르게 표시 되려면 각 페이지의 미리 렌더링 된 버전을 제공해야 합니다. 이를 위해서는 사용자가 Google 사이트를 방문 할 때마다 Cloudfront의 프론트엔드에 서비스를 제공해야 합니다. 그러나 사용자 에이전트가 Google/Facebook/Twitter 인 경우 미리 렌더링된 사이트 버전으로 리디렉션을 해야합니다.

한 명의 고객이 보내준 사용 사례를 넘기지 않고, 우리가 앞으로 이러한 문제를 개선하겠다는 사실을 알려주었습니다. 여러 고객들이 이미 엣지에서 신속하게 의사 결정을 내림으로써 맞춤형 최종 사용자 경험을 제공하고자 하는 의견을 주었습니다.

(레이턴시 기준) 고객에게 가까이 있는 위치에서 HTTP 요청을 “지능적으로” 처리하는 데는 많은 주목할만한 사용 사례가 있습니다. 예를 들어, HTTP 헤더 검사, 접근 제어 (특정 쿠키가 필요함), 모바일 디바이스 탐지, A/B 테스트, 크롤러 또는 봇에 대한 신속한 처리 또는 특수한 별도 처리, 레거시 시스템을 수용 할 수 있는 사용자 친화적인 URL 리다이렉트 등입니다. 이런 요구 사항 대부분은 단순한 패턴 일치 및 규칙으로 표현할 수 있는 것보다 좀 더 복잡한 처리 및 의사 결정을 필요로합니다.

AWS Lambda@Edge 서비스 소개
이러한 요구 사항을 지원하기 위해 AWS Lambda@Edge 미리 보기를 시작합니다. 이 새로운 람다 기반 처리 모델을 사용하면, 전 세계에 산재하는 AWS 엣지 로케이션에서 JavaScript 코드를 작성하여 실행할 수 있습니다.

이제는 가벼운 요청 처리 로직을 작성하고 CloudFront 배포판을 통과하는 요청(request) 및 응답(response)을 처리 할 수 있습니다. 아래와 같이 네 가지 별개의 이벤트에 대한 응답으로 코드를 실행할 수 있습니다.

Viewer Request – 콘텐츠 캐시 여부에 관계없이 모든 요청에 대해 코드가 실행됩니다. 다음은 간단한 헤더 처리 코드입니다.

JavaScript
exports.viewer_request_handler = function(event, context) {
  var headers = event.Records[0].cf.request.headers;
  for (var header in headers) {
    headers["X-".concat(header)] = headers[header];
  }
  context.succeed(event.Records[0].cf.request);
}

Origin Request – Your code will run when the requested content is not cached at the edge, before the request is passed along to the origin. You can add more headers, modify existing ones, or modify the URL.

Viewer Response – 캐시 여부와 관계없이 모든 응답에서 실행됩니다. 이것을 사용하여 브라우저로 다시 전달할 필요가 없는 일부 헤더를 정리할 수 있습니다.

Origin Response – 캐시 실패로 인해 원본(Origin)에서 다시 가져와서 엣지(Edge)에 반응한 후 코드를 실행합니다.

개별 코드는 URL, 메소드, HTTP 버전, 클라이언트 IP 주소 및 헤더 등 HTTP 요청 및 응답에서 나오는 여러 데이터를 접근할 수 있습니다. 간단하게 헤더를 추가, 수정 및 삭제할 수도 있고, HTTP 바디(Body)를 포함한 모든 값을 변경할 수 있습니다. 처음에는 헤더를 추가, 삭제 및 수정할 수 있습니다. 곧 바디를 포함한 모든 값에 대한 읽기 / 쓰기 접근 권한을 갖게됩니다.

자바 스크립트 코드는 HTTP 호출/응답의 한 부분이 되기 때문에 재빠르고 의미 있는 스스로 완결적인 코드여야 합니다. 다른 웹 서비스를 호출 할 수 없으며, 다른 AWS 리소스에 접근할 수 없습니다. 128MB의 메모리 내에서 실행되어야 하며 50ms 이내에 실행이 끝나야 합니다.

처음 시작을 해보려면, 새로운 람다 함수를 생성하고, CloudFront 배포를 트리거로 설정한 후 새 Edge 런타임을 선택하면됩니다.

CynNG_pVQAADVbR

그런 다음, 코드를 만들면 됩니다. Lambda 함수는 엣지 로케이션의 여러 가지 측면을 개선하는데 도움을 줄 것입니다.

미리 보기 신청하기
이 기능이 새로운 애플리케이션 및 개발 도구로서 창의적인 적용을 해 볼 수 있을 것으로 생각하고, 여러분이 직접 해 보시기를 권해 드립니다.

오늘 AWS Lambda@Edge 미리 보기를 시작하였고, 직접 해보시려면 미리 보기 신청 페이지에서 등록해 주시기 바랍니다.

Jeff;

이 글은 AWS re:Invent 2016 신규 출시 소식으로 AWS Lambda@Edge – Preview의 한국어 번역입니다. re:Invent 출시 소식에 대한 자세한 정보는 12월 온라인 세미나를 참고하시기 바랍니다.

IPv6 지원 업데이트 – CloudFront, WAF 및 S3 Transfer Acceleration

최근 Amazon S3 IPv6 지원 발표 이후, 이번에는 Amazon CloudFront, Amazon S3 Transfer AccelerationAWS WAF와 60개가 넘는 모든 CloudFront 엣지 로케이션에서도 IPv6 지원이 이용 가능합니다. AWS는 모든 자율 시스템 네트워크(ASN)에서 IPv6를 활성화하기 위한 단계적 마이그레이션 프로세스를 오늘부터 시작하고, 앞으로 몇 주에 걸쳐 모든 네트워크에서 확장 할 예정입니다.

CloudFront IPv6 지원
이제 각 Amazon CloudFront 배포 버전마다 IPv6 지원을 활성화 할 수 있습니다. IPv6을 사용하여, CloudFront 엣지 로케이션에 연결하는 방문자와 네트워크는 자동으로 IPv6 콘텐츠를 가져옵니다. IPv4를 사용하여 연결하는 경우, 예전처럼 작동합니다. 오리진(Origin) 서버 연결은 IPv4를 사용합니다.

새로 만든 배포 게시 지점은 자동으로 IPv6을 사용합니다. 기존 게시 지점을 변경하려면, Enable IPv6를 선택합니다. 이것은 콘솔 또는 CloudFront API에서 설정할 수 있습니다.

새로운 기능의 중요 사항은 아래를 참조하십시오.

  • 별칭 레코드(Alias Records) – 게시 지점에서 IPv6 지원을 활성화하면, DNS 항목은 AAAA 레코드를 포함해서 업데이트 합니다. Amazon Route 53과 별칭 레코드를 사용하여, 배포 도메인 전체 또는 일부를 가르키고 있는 경우, 그 도메인에 AAAA 별칭을 추가 해야합니다.
  • 로그 파일(Log Files) – CloudFront 접속 로그를 사용하는 경우, IPv6 주소가 c-ip 필드에 표시되므로, 로그 처리 시스템이 이를 처리할 수 있도록 해야 합니다.
  • 신뢰할 수 있는 서명(Trusted Signers) – 신뢰할 수 있는 서명 및 IP 주소 화이트 리스트를 함께 사용하는 경우, IP 허용 목록과 실제 내용 IPv4/IPv6 배포를 갖추는 신뢰된 서명과 각 URL의 IPv4 제한 배포 지점을 사용할 것을 적극 권장합니다. 이 모델에서는 IPv4 주소를 사용하여 전송 한 서명 요청에 서명한 것으로, 콘텐츠 요청이 화이트리스트에 실려 있지 않은 다른 IPv6 주소에서 주어진 같은 문제를 해결 할 수 있습니다.
  • CloudFormation – CloudFormation 지원을 준비 중 이번 출시에서는 CloudFormation 템플릿에서 만든 배포판에서 IPv6를 사용할 수 없습니다. 기존 스택을 업데이트 할 때, 스택에서 참조 배포판 설정 변경은 없습니다.
  • AWS WAF – AWS WAF와 CloudFront를 함께 사용하는 경우 IPv6 주소의 화이트리스트 또는 블랙리스트에 연결 되도록, WebACL과 IP 규칙 세트를 업데이트 해야합니다.
  • Forwarded 헤더 (Forwarded Headers) – 배포 지점에서 IPv6를 사용하는 경우, X-Forwarded-For 헤더에 IPv6 주소가 포함합니다. 오리진(Origin)이 형식 헤더를 처리 할 수 ​​있는지 확인하십시오.

자세한 내용은 IPv6 Support for Amazon CloudFront를 참고하십시오.

AWS WAF IPv6 지원
AWS WAF는 애플리케이션 레이어에서 발생하는 공격으로부터 응용 프로그램을 보호합니다. (자세한 사항은 AWS WAF 신규 서비스를 참고하십시오.)

AWS WAF가 IPv4 또는 IPv6 주소를 통해 요청을 검사 할 수 있습니다. IPv6와 일치하는 웹 접근 목록(ACL)을 만들 수 있습니다. 자세한 내용은 Working with IP Match Conditions를 참조하십시오.

기존 WAF 기능은 모든 IPv6 지원 성능에 보이는 변화는 없습니다. IPv6는 WAF가 수집 되어 표시한 샘플 요청으로 표시됩니다.

S3 Transfer Acceleration IPv6 지원
Amazon S3 전송 가속 기능이 IPv6를 지원하게 되었습니다. (자세한 내용은 AWS 스토리지 업데이트 – Amazon S3 Transfer Acceleration 참조). 업로드에 사용할 수 있는 이중 스택 엔드 포인트에 쉽게 전환 할 수 있습니다. 다음과 같이 변경 하면됩니다.

https://BUCKET.s3-accelerate.amazonaws.com

에서

https://BUCKET.s3-accelerate.dualstack.amazonaws.com

클라이언트 객체 생성 및 듀얼 스택 전송의 활성화를 가능하게 하는 AWS SDK for Java 사용 코드는 다음과 같습니다.

Java
AmazonS3Client s3 = new AmazonS3Client();
s3.setS3ClientOptions(S3ClientOptions.builder().enableDualstack().setAccelerateModeEnabled(true).build());

대부분 응용 프로그램과 네트워크 스택은 자동으로 IPv6 사용을 선호하는 경향이 있기 때문에 더 이상의 설정은 필요하지 않습니다. IPv6 주소와 함께 사용하기에 기능 동작에 문제가 없는지 확인하기 위해 패킷 IAM 정책을 검토하는 것이 좋습니다. 자세한 내용은 IPv6를 사용하여 Amazon S3에 요청 전송을 참조하십시오.

테스트를 잊지 마세요!
AWS 리전에 IPv6 연결에 제한이 있거나 존재하지 않는 경우, 대신 IPv4를 사용합니다. 이전에 블로그에서도 언급했지만, IPv6를 지원하도록 클라이언트 시스템을 구성 할 수 있습니다. 그러나, 이 경우 IPv6 패킷을 인터넷에 라우팅 설정하지 않은 네트워크에 연결해야 합니다. 이러한 이유에서 IPv6로 전환하기 전에 응용 프로그램 수준에서 네트워크 수행 지점 간 연결 테스트를 수행하는 것이 좋습니다.

Jeff;

이 글은 IPv6 Support Update – CloudFront, WAF, and S3 Transfer Acceleration의 한국어 버전입니다.

Amazon CloudFront를 활용한 동적 콘텐츠 전송 성능 개선하기

게임 서비스에 있어서 데이터 전송 성능은 매우 중요한 요소입니다. 성능 향상을 통해 더 많은 페이지 뷰, 풍부한 사용자 경험, 높은 전환율을 얻을 수 있으며, 이는 비지니스 성공과도 직결된 중요한 요소들이라고 볼 수 있습니다. 한 통계 자료에 따르면 페이지 로딩시의 1초 지연은 7%의 전환율 하락을 가져올 수 있다고 합니다.  뿐만 아니라, 글로벌 서비스에서 최종 사용자 경험을 향상 시키는데 있어서 콘텐츠 전송 성능은 매우 중요한 요소 입니다.

CDN을 통한 동적 콘텐츠 전송에 대한 이해
Amazon CloudFront는 AWS의 콘텐츠 전송 서비스(CDN) 로서, 다른 서비스들과 통합되어 최종 사용자에게 효과적으로 콘텐츠를 쉽고 빠르게 전송할 수 있습니다. CDN은 최종 사용자와 원본 저장소(Origin) 사이에서 프록시(Proxy) 역할을 하며,  전 세계 56개(2016년 6월 20일 기준) 엣지 로케이션(Edge Location)에 미리 캐시 함으로써 빠르게 사용자에게 콘텐츠 전송을 할 수 있습니다.

일반적으로 이미지나 동영상 파일 같은 정적 콘텐츠 전송을 위해서 Amazon CloudFront를 많이 활용하고 있지만, 동적 콘텐츠 전송을 위해 사용하는 것에 대해서는 몇 가지 이유로 고민을 합니다. 동적 콘텐츠는 대게 자주 변경되는 정보를 가지고 있거나, 사용자가 보낸 요청에 포함된 요인에 따라 그 내용이 변경되는 특성을 가지고 있습니다.

그래서 항상 최신의 콘텐츠를 가져오기 위해 TTL 을 0 으로 설정하여 원본 저장소에 매번 접속 하여야 하기 때문에, 엣지에 캐시를 함으로써 향상되는 콘텐츠 전송 가속의 효과가 미비하다고 생각되는 이유 때문입니다. 하지만, TTL 을 0으로 설정하여 매번 원본 저장소에 접속하여 동적 콘텐츠를 제공하더라도, CloudFront를 프록시로 사용함으로써 전송 성능을 향상 시킬 수 있습니다.

먼저 콘텐츠 전송 성능에 대해서 얘기하기 앞서, 요청에 대한 응답 시간을 어떤 요인들로 구분하여 생각할 수 있는지 알아보는게 도움이 될 것입니다.

데이터 전송 관점에서 성능 향상 방법
아래 그림에서 보시다시피 응답 시간은 간단히 DNS Lookup 시간과, 연결 수립 시간, 최초 바이트를 받기까지의 시간, 콘텐츠 다운로드 시간의 합으로 생각해 볼 수 있습니다.

최종 사용자가 요청을 보내면, 먼저 DNS Lookup 을 하게 됩니다. 이 후 대상 서버와 TCP handshakes/retries 등의 과정으로 연결을 수립하게 됩니다. 그리고 TTFB 로 알려져 있는 최초의 응답을 기다리게 되고, 그 이후 콘텐츠를 다운로드 합니다.

이 과정이 완료되면 요청에 대한 응답이 완료되었고, 콘텐츠가 전송 되었다고 볼 수 있습니다. 앞서 나열한 요인들을 포함한 응답 시간을 CloudFront는 어떻게 처리하여 콘텐츠 전송 성능을 향상 시킬까요?

  1. 최적화된 네트워크: Amazon CloudFront 엣지와 AWS 리전 사이의 네트워크는 지속적으로 모니터링되고 성능 및 가용성면에서 최적화 됩니다. 게다가 네트워크상에 문제가 발생할 경우 신속하게 감지 및 수정되고, 최종 사용자를 다른 네트워크 경로로 자동 라우팅하여 최종 사용자에 미치는 영향을 최소화 합니다. 이를 통해 더 적은 패킷 감소와 더 나은 성능을 기대할 수 있습니다.
  2. 원본과의 지속적인 연결 유지: IP 기반의 네트워크를 통해 TCP/IP 연결을 맺기 위해서는 TCP 3-way handshake 라는 과정을 거치게 됩니다. 이 과정에 필요한 패킷 사이즈는 그렇게 크지 않기 때문에 큰 오버헤드가 아닐 수 있습니다. 하지만 글로벌 서비스와 같은 경우 지리적으로 떨어져 있는 곳에서 최종 사용자가 요청을 하게 되고, 지리적인 요건으로 인한 높은 RTT(Round-Trip Time)로 인해 매우 큰 오버헤드가 될 수 있습니다. CloudFront는 엣지에서 오리진으로의 지속적인 연결을 유지 및 재사용 하여 대게 수백 밀리세컨드가 소요되는 연결 설정 시간을 줄여 줍니다. 글로벌 서비스에서는 물론, 초당 요청 건수가 많아지면 많아질수록 지속적인 연결 유지로 얻을 수 있는 콘텐츠 전송 속도 향상의 효과는 커집니다.
  3. TCP/IP 최적화: 네트워크의 대역폭은 다양한 이유로 시시때때로 바뀌게 됩니다. CloudFront의 모든 호스트에는 엣지와 최종 사용자 간의 시시때때로 변하는 네트워크 대역폭 사용을 최대화 하기 위해 TCP initcwnd(initial congestion window) 값이 최적화 되어 있습니다.
  4. Gzip 압축 사용: Amazon CloudFront가 제공하는 GZIP 압축을 사용한다면 전송되는 데이터의 크기를 줄여, 트래픽을 줄일 수 있습니다. 이를 통해, 데이터 전송은 더 짧은 시간 안에 완료할 수 있을 뿐만 아니라, 데이터 전송 비용도 절감할 수 있습니다. 특히나 동적 콘텐츠는 대부분 매우 높은 압축률을 보여주는 텍스트 형태이기에 압축을 통한 효율이 더 높습니다. 또, CloudFront 엣지에서 압축 작업을 수행함으로써 오리진에서 압축을 위해 자원을 사용할 필요가 없어지는 장점도 있습니다.

앞서 설명한 대부분의 기능과 방법들은 CloudFront 엣지와 오리진 사이의 최적화에 관련된 내용 입니다. 최종 사용자와 엣지 사이의 최적화는 어떨까요? CloudFront는 지속적으로 지연 시간을 측정하여 최종 사용자가 항상 더 나은 경험을 할 수 있는 엣지로 연결을 하도록 합니다. 그리고, 여러 리전에 오리진을 배치하여 실제 물리적 거리를 줄일 수 있을 경우 Amazon Route 53의 LBR(Latency Based Routing)을 사용하여 최종 사용자로부터 최적의 리전에 있는 오리진에서 콘텐츠가 전송될 수 있도록 합니다.

지금까지 설명한 내용으로 앞서 언급한 응답 시간 관여 요인들을 최적화 하여 응답 시간을 줄일 수 있습니다.

  • DNS Lookup 시간: CloudFront의 라우팅 기술, Route 53과의 통합
  • 연결 수립 시간: CloudFront의 지속적인 연결 유지
  • 최초의 응답 시간(TTFB): CloudFront의 지속적인 연결 유지, Gzip 압축
  • 콘텐츠 다운로드 시간: CloudFront의 TCP/IP 최적화, Gzip 압축

CloudFront를 활용한 동적 콘텐츠 전송 테스트
Amazon CloudFront가 제공하는 응답 시간을 줄이기 위한 다양한 방법들을 살펴보았습니다. 이를 통해 어느 정도 응답 시간을 줄일 수 있는지는 간단한 테스트로 확인할 수 있습니다.

아래는 Amazon CloudFront를 활용한 동적 콘텐츠 전송 테스트 시나리오입니다.

  • 미국 동부(버지니아)에 있는 사용자가 한국에 있는 개인 서버로 접속하여, 1.7KB 정도의 동적 콘텐츠를 요청
  • CloudFront 엣지와 오리진과의 네트워크 성능에 집중하기 위해, 모든 캐시는 비활성
  • 마찬가지로 네트워크 성능에 집중하기 위해, 요청을 보낸 후 응답을 받은 뒤, 곧바로 다시 요청을 보내는 방법으로 진행 (Python 스크립트 사용)
  • 1일 03:09:00 초 ~ 5일 19:29:30 초 까지 5일 가까운 기간 동안 테스트 진행
  • 테스트1(빨간색 라인): 버지니아 EC2 -> CloudFront (No-cache, TTL 0) -> 오리진 (서울, 개인 서버, Node.js)
  • 테스트 2(파란색 라인): 버지니아 EC2 -> 오리진 (서울, 개인 서버, Node.js)

아래는 저의 인터넷 환경에서 얻은 결과입니다. (여러분의 환경과 설정 값들로 인해, 결과는 다를 수 있음을 유의해 주시기 바랍니다.)

횟수 평균 최소 최대 90백분위 10백분위 > 1초
CloudFront 1,902,091번 0.212초 0.187초 9.605초 0.209초 0.197초 40번
직접 연결 1,027,763번 0.393초 0.365초 7.415초 0.403초 0.384초 118번

동일한 기간 동안 테스트를 진행하였고, 그 결과를 확인해보면, CloudFront를 사용하였을 때 87만번 이상의 요청을 더 처리하였으며, 응답 시간은 직접 연결했을 때 보다 평균 181ms로 이는 약 1.8배 정도 더 빠른 결과 입니다. 또한, CloudFront를 사용하였을 때 1초 이상의 응답 지연은 직접 연결한 것에 비해 34% 정도 밖에 되지 않았습니다. 이를 통해, 직접 연결 보다 CloudFront를 활용하였을 때 더욱 빠르고 안정적인 서비스가 가능할 수 있음을 알 수 있습니다.

추가로 미국 서부(오레곤) 리전의 EC2에서 요청을 보냈을 때, 지리적인 이점으로 인해 더 낮은 평균 응답 시간을 얻을 수 있었습니다.

  • 테스트1: 오레곤 EC2 -> CloudFront (No-cache, TTL 0) -> 오리진 (서울, 개인서버, Node.js)
  • 테스트2: 오레곤 EC2 -> 오리진 (서울, 개인서버, Node.js)

아래는 저의 인터넷 환경에서 얻은 결과입니다. (여러분의 환경과 설정 값들로 인해, 결과는 다를 수 있음을 유의해 주시기 바랍니다.)

횟수 평균 최소 최대 90백분위 10백분위 > 1초
CloudFront 2,689,804번 0.150초 0.129초 5.223초 0.191초 0.134초 52번
직접 연결 1,642,063번 0.249초 0.236초 3.700초 0.248초 0.241초 90번

간단한 테스트를 통하여 Amazon CloudFront를 사용하면 동적 콘텐츠 전송을 가속할 수 있음을 알 수 있었습니다. 이러한 동적 콘텐츠를 위해서 캐시 기능을 사용할 수 있다면 어떨까요? 분명 더 나은 콘텐츠 전송 속도는 물론 원본 저장소 자원 사용도 줄일 수 있을 것 입니다.

동적 콘텐츠에 대한 캐싱을 통한 성능 향상하기
웹 애플리케이션 및 게임 서비스 등에서 제공하는 다양한 기능들에서 동적 콘텐츠 임에도 불구하고 일정 기간 동안은 갱신되지 않아도 크게 영향이 없는 것들을 찾을 수 있습니다. 이런 동적 콘텐츠들은 짧게는 수십초부터 길게는 수일까지 내용을 갱신할 필요가 없으며, 캐싱을 통하여 더 빠르게 전송될 수 있습니다.

아래는 동적 콘텐츠를 캐싱할 수 있을만한 애플리케이션 및 게임 서비스 내의 기능들의 예 입니다.

  1. 리더보드: http://www.example.com/leaderboards/?page=50&lowest=true – 리더 보드는 소셜 기능을 포함하는 많은 서비스들, 특히 게임에서 많이 요구되는 기능입니다. 게임을 예를 들면, 게임 플레이어들이 전투와 같은 게임 내 활동을 통해 점수가 업데이트 되고, 백그라운드에서 순위가 집계 및 계산이 된 후, 그 결과가 갱신되어, 리더보드에서 순위 정보가 표시됩니다. 게임과 같이 경쟁을 요하는 서비스에서 최종 사용자로부터 자주 요청되는 콘텐츠 입니다. 만약 이 순위 정보를 즉각 계산하고 갱신하고자 한다면 많은 자원을 필요로 할 것입니다. 하지만, 순위 정보는 항상 최신일 필요성이 적다는 점을 감안하면, CloudFront에 캐싱 하여 더 빠르게 응답을 처리하는 동시에 오리진의 자원을 효율적으로 사용할 수 있을 것입니다.

    <게임Castle Clash의 리더보드. 매일 자정 리더보드 갱신>
  2. 통계 정보: http://www.example.com/stats/player1/ – 최종 사용자는 추가적인 정보를 얻기 위해서 통계 정보를 요청합니다. 이 통계 정보는 특정한 활동에 대한 집계 일 수도 있으며, 최종 사용자의 활동으로부터 예측한 정보일 수도 있습니다. 이러한 정보는 최종 사용자의 지난 정보들을 수집한 뒤 생성되는 것으로서 자주 요청될 필요성이 적습니다. CloudFront 의 캐시 기능과 보다 긴 TTL 설정을 통하여 더 빠르게 정보를 제공할 수 있습니다.

    <World of Warships 포럼의 게임 플레이어 통계 정보>
  3. 각종 리플레이 기반의 기능: http://www.example.com/replay/player1/20/ – 게임 내에서 전투와 같은 활동은 추후 다시 재현하기 위해 리플레이로 저장할 수 있습니다. 리플레이는 일반적으로 게임 플레이어와 상대방(AI 혹은 다른 게임 플레이어)이 언제 어떤 활동 및 명령을 수행 했는지에 대한 순차적인 데이터들의 모음입니다. 이런 데이터를 기반으로 멀티플레이어 게임과 같은 기능을 구현할 수 있습니다. 리플레이 데이터는 한번 생성된 후 수정이 필요하지 않은 정적 콘텐츠의 특징을 가지고 있으며 CloudFront 의 캐시 기능을 백분 활용할 수 있습니다.

    <게임 Drag Racing Classic의 멀티플레이어 화면>

뿐만 아니라 VarnishSquid 등의 Caching Proxy를 CloudFront와 함께 사용한다면 더 세밀하고, 더 효율적으로 동적 콘텐츠를 캐싱할 수 있습니다.

지금까지 Amazon CloudFront를 활용하여 동적 콘텐츠의 전송을 가속 할 수 있는 방법을 알아 보았습니다. Amazon CloudFront가 제공하는 비용 효율성과 동적 콘텐츠 가속을 위한 기능들을 사용하여 보다 쉽고 빠르게 콘텐츠를 전송하여 최종 사용자 경험 향상은 물론 인프라의 부하도 줄일 수 있습니다. 이외에도 Amazon Route 53, Amazon S3 등의 AWS 서비스와 파트너 솔루션과의 통합으로도 성능 및 가용성을 향상 시킬 수 있습니다.

더 자세한 정보는 Amazon CloudFront – 동적 콘텐츠 전송 페이지와 Amazon CloudFront 개발자 안내서를 참고하시기 바랍니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 김필중 솔루션즈 아키텍트께서 작성해주셨습니다.

Amazon CloudFront, 한국에 세번째 엣지 로케이션 공개

아마존웹서비스는 한국에 Amazon CloudFront의 세번째 엣지 로케이션(Edge Location)을 공개합니다. 2013년 5월 한국에 처음으로 국내 고객을 위한 콘텐츠 배포 지점인 엣지 로케이션을 설치한 이후, 2015년 1월 두번째 엣지를 설치 하였습니다.

늘어나는 한국 고객의 트래픽 처리와 많은 피드백을 통해 세번째 엣지 로케이션을 설치하게 되었고, 이로서 전 세계적으로 55개의 콘텐츠 배포망을 갖추게 되었습니다. (자세한 것은 AWS 글로벌 인프라 구조를 살펴 보세요.)

새로운 엣지 로케이션을 통해 AWS 고객들의 애플리케이션을 일반 사용자에게 빠르게 배포하고, 가용성을 더욱 높일 수 있게 되었습니다. 특히 Amazon CloudFront는 통해 웹 페이지 캐싱, 실시간 스트리밍, S3 전송 가속화 기능, 웹 애플리케이션 방화벽, 무료 SSL 보안 서버 및 인증서 제공 서비스, API 게이트웨이 배포 지점 등 다양한 AWS 서비스와의 연동 분야를 가지고 있습니다.

이제 한국 고객들은 지난 1월 설립한 Asia Pacific (Seoul) 리전과 더불어 3개의 엣지 로케이션을 통해 더 높은 품질의 클라우드 서비스를 제공할 수 있게 되었습니다.

Amazon CloudFront의 더 자세한 사항은 서비스 상세 페이지를 참고하시기 바랍니다.

이 글은 Announcing Third Edge Location in Seoul, Korea for Amazon CloudFront의 한국어 편집입니다.

CloudFront 업데이트 – 소스와 HTTPS & TLS v1.1/v1.2 통신 지원, 헤더 추가 및 변경

Amazon CloudFront는 글로벌 콘텐츠 배포망의 에지 위치를 이용하여 정적 및 동적 콘텐츠를 제공 할 수 있습니다. 몇 분 안에 설치를 진행하고, 여러분의 고객에게 빠르고 낮은 레이턴시의 웹 사이트, 영상, 음악 스트리밍 서비스를 제공할 수 있습니다.

개별 CloudFront 배포 지점은 하나 혹은 여러 개의 원래 소스 위치 (웹 서버나 S3 Bucket)를 참조할 수 있습니다. CloudFront의 에지 위치에 콘텐츠의 캐시가 존재하지 않는 경우, 배포지점에서 설정된 매핑(behaviors)을 따라 올바른 소스 위치(Origin)에 요청합니다.

오늘 부터 CloudFront와 소스 위치의 연결을 위한 3 가지 제어 기능을 새롭게 제공합니다.

  • TLS v1.1 및 v1.2 지원
  • HTTPS-only 연결 지원
  • edge-to-origin 요청 헤더 지원

TLS v1.1 및 v1.2 지원

에지 로케이션과 사용자 오리진 간의 프로토콜 설정으로 TLS v1.1 과 TLS v1.2 을 새롭게 추가했습니다. 이를 통해 CloudFront는 CloudFront 배포 지점에서 설정 중인 각 오리진 대해 SSLv3, TLS v1.1TLS v1.2를 지정할 수 있게 되었습니다.

HTTPS-only 연결 지원

CloudFront에서 엣지 로케이션에서 소스 위치와의 통신에서 사용하는 프로토콜 (HTTP 또는 HTTPS)은 항상 HTTPS를 사용하도록 지정할 수 있게 되었습니다. 이전에는 CloudFront에서 엣지와 통신에 이용되는 프로토콜(HTTP 또는 HTTPS)과 같은 프로토콜로 소스 위치와 통신하고 있었습니다. 이 설정을 사용하여 Viewer에서 HTTP 및 HTTPS 요청은 모든 HTTPS를 이용하여 소스 위치에 전송됩니다.

다음은 사용할 프로토콜 지정 및 HTTP-Only로 설정하는 방법입니다 :

Edge-to-origin 요청 헤더 지원

CloudFront에서 소스 위치에 요청을 포워드 할 때, 사용자 정의 헤더를 추가하거나 요청 헤더 값을 재정의 할 수있게 되었습니다. 이 헤더를 이용하여 소스 측의 임의 요청 헤더가 포함되어있는 것 만을 허용하도록 설정함으로써, 소스 에 대한 요청이 CloudFront에서 이루어지고있음(Shared Secret)을 평가할 수 있습니다.

Cross-Origin Request Sharing (CORS)의 경우 Viewer 측이 자동으로 적절한 헤더를 부여하여 요청 전송을 실행해도, CloudFront에서 소스에 대해 항상 적절한 헤더를 부여 할 수 있습니다. 또한 캐시 비율을 향상시키기 위해 값이 변화하는 소스에 헤더를 비활성화 할 수 있습니다.

아래가 X-CloudFront-Distribution-IdX-Shared-Secret이라는 새로운 헤더를 설정하는 방법입니다.

이들 기능은 추가 비용없이 오늘부터 사용할 수 있습니다. 더 자세한 사항은 CloudFront Developer Guide를 참고하세요.

Jeff;
이 글은 CloudFront Update – HTTPS & TLS v1.1/v1.2 to the Origin, Add/Modify Headers의 한국어 번역입니다.

Amazon CloudFront- 신규 Gzip 압축 기능 제공!

전 세계 사용자에게 Amazon CloudFront를 이용하여 낮은 지연 속도로 빠르게 콘텐츠를 제공 할 수 있습니다.

오늘 부터 CloudFront에 Gzip 압축 기능을 추가 지원합니다. 특정 CloudFront 배포 지점에 본 기능을 사용하면, (일반적으로 브라우저가 자동 수행하는) 콘텐츠 압축 요청에 텍스트와 바이너리 콘텐츠를 특정 엣지(Edge)에서 전달하게 됩니다.

이를 통해 사용자의 웹 페이지 로딩 속도가 더 빨라지며, 콘텐츠 다운로드 시간도 짧아지고, CloudFront 데이터 전송 비용 역시 절감 할 수 있습니다. 텍스트 스크립트나 이미지가 혼합된 일반 웹 페이지의 경우, 최대 80% 정도의 속도나 비용 감소가 생길 수 있습니다.

현재 AWS 블로그에서 이러한 기능을 한번 테스트 해보도록 하겠습니다. 아래는 압축 없을 때 데이터입니다.

압축 기능을 사용했을 때 데이터입니다.

웹 브라우저 상태 표시 줄에서도 보시다시피, Gzip 압축을 통해 총 다운로드 용량을 792KB에서 1​​77KB(77% 감소)까지 낮출 수 있었습니다. 다운로드 시간은 846ms에서 446ms(약 50%)까지 단축되었습니다.

Gzip 압축 사용 방법
본 기능은 몇 분안에 바로 사용할 수 있습니다. CloudFront 관리 콘솔을 열고 대상 배포 지점을 선택하고 Behavior 옵션에서 Compress Objects AutomaticallyYes로 하면 됩니다.

더 자세한 사항은 파일 압축 제공 방법 문서를 참고하시기 바랍니다.

정식 출시
압축 기능은 오늘부터 바로 사용할 수 있습니다. 압축 기능에 사용함으로서 바로 CloudFront 데이터 전송 비용을 절감 할 수 있습니다. (다만, 서비스 특성에 따라 압축하지 않은 것이 효율적인 경우도 있으므로 판단하셔서 사용하시면 됩니다.)

Jeff;

이 글은 New – Gzip Compression Support for Amazon CloudFront의 한국어 번역입니다.

AWS WAF 서비스 공개

여러분 웹 서버의 access log 및 error log를 한번 살펴 보신 적이 있으신가요? 사용자 뿐만 아니라 크롤러 등의 정상적인 요청이 대부분이지만, 종종 이상하고 위험하게 보이는 로그도 볼 수 있습니다. 예를 들어, 제 서버를 한번 확인해 봤는데, 잘 알려진 패키지나 소프트웨어의 취약점을 이용하기 위해 자주 설치하는 주소로 요청을 보내는 경우가 매우 흔합니다. (소스 서버 IP 주소는 이미지 생성을 위해 바꾸었습니다~)

이 중에 하나라도 성공한다면, 공격자들이 취약점을 틈타서 서버 권한을 얻을 수 있습니다. 흔히 사용하거나 기본 아이디와 암호로 접근을 하거나 시스템 취약점, 언어 및 애플리케이션 취약점을 노리고 SQL Injection이나 크로스 사이트 사기 요청 등의 단계로 공격이 진행될 수 있습니다.

우리가 원하던 원치 않던 이러한 비정상적인 호출은 매일 항상(24×7) 일어나고 있습니다. 우리가 서버 업데이트를 잘하고, 소프트웨어 패치를 열심히 해서 공격 가능성을 줄이더라도 보호를 위한 추가적인 레이어를 두는 것이 좋습니다.

신규 AWS WAF 서비스
이를 위해 오늘 AWS WAF (Web Application Firewall)서비스를 공개합니다. 이 글을 읽어 보시면 아시겠지만, AWS WAF를 통해 AWS 기반의 웹 서비스를 애플리케이션 단계의 공격으로부터 보호하는 역할을 할 수 있습니다.

몇 분 안에 웹 애플리케이션 보호를 위한 설정을 할 수 있습니다. 한 개 이상의 웹 접근 제어 목록(Web Access Control Lists, Web ACL)을 만들고, 내장된 규칙(IP 주소 및 허용/거부 URL에 대한 조건 모음)을 통해 이에 대한 요청을 제어합니다. 이 ACL 목록은 Amazon CloudFront 배포 시 적용할 수 있습니다.

이러한 규칙 및 조건은 여러 가지 방법으로도 사용 가능합니다. 예를 들어 위에 로그에서 봤던 IP 주소를 모두 차단할 수 있습니다. 만약 비슷한 요청이 다른 IP로부터 오고 있다면, “/typo3”, “/xampp”와 같은 URL 기반으로도 차단이 가능합니다. 여러분 애플리케이션 내부에 있는 URL에 대해 접근을 허용하거나 차단할 수도 있고, SQL injection공격에 사용하는 다양한 패턴도 규칙을 만들어 둘 수 있습니다.

AWS WAF 개념
이제 실행 조건(condition), 규칙(rule), Web ACL 및 동작(action) 등에 대해 설명해 드리겠습니다. AWS WAF 관리 콘솔의 스크린샷으로 이해하시기 편합니다.

Conditions 들어오는 요청을 검사합니다. 요청 URL, 쿼리 스트링(query string), 특정 HTTP header 또는 HTTP 메소드 등 (GET, PUT 등):

공격자들이 자신들의 시도를 여러가지 방법으로 위장하는 경우가 종종 있기 때문에 조건을 만들기 앞서 여러 가지 변형 옵션을 찾아서 살펴 보는 것이 좋습니다.

각 조건은 IP 주소를 조사할 수도 있는데, /8, /16, /24 등의 범위 또는 싱글 IP인 경우 /32로 찾을 수 있습니다.

Rules 하나 이상의 조건에 대한 참조를 말하는 것으로 모든 조건이 만족 되어야 실행이 됩니다. 예를 들어 특정 콘텐츠를 차단하기 위해 IP 기반 규칙과 호출 기반 규칙을 함께 사용할 수 있습니다. 각 규칙은 Amazon CloudWatch 측정치로 만듭니다.

Actions 규칙의 일부분으로서 규칙에 부합하는 모든 조건에 대해 우리가 취할 행동을 말합니다. 그냥 두거나 혹은 차단하거나 부합하는 양을 측정할 수도 있습니다. (결정적인 동작을 취하기 전에 새로운 규칙을 실험해서 확인하는 것도 필요합니다.)

Web ACLs 각 규칙의 동작에 따른 여러 규칙을 참조합니다. 규칙 내 모든 조건에 맞기 전에는 각 (CloudFront) 배포에서 들어오는 호출을 정상적이지 않은 것으로 판단합니다. 이 때 규칙에 맞는 동작이 실행됩니다. 규칙이 맞지 않으면 기본 동작(차단 또는 허용)만 수행합니다.

WAF 지금 해보기
이제 조건, 규칙, Web ACL 등을 한번 같이 만들어 보겠습니다. 관리 콘솔 뿐만 아니라 AWS Command Line Interface (CLI), AWS Tools for Windows PowerShell, Web Application Firewall API를 활용하실 수 있습니다.

관리 콘솔에서 WebACL을 만드는 방법을 알려주는데 ProtectSite라는 이름을 사용해 보겠습니다.

허용 혹은 차단한 조건을 만듭니다.

서버 로그에서 가짜 IP를 차단하기 위해 BadIP라는 조건을 만들어 보겠습니다.

BadCompany라는 규칙도 만듭니다.

규칙을 선택하고 동작을 골랐습니다.(하나의 Web ACL에서는 여러 규칙을 사용할 수 있지만, 저는 하나만 골랐습니다.)

위에서 보다시피 기본 동작은 요청을 허용하는 것입니다. 실제로는 (조건 + 규칙 + Web ACL) 조합으로 10.11.12.217에서 오는 트래픽을 차단하고 다른 곳에서의 호출은 허용합니다.

다음 단계는 우리가 만든 Web ACL을 CloudFront 배포본에 적용하는 것입니다. (앞으로 더 많은 서비스에도 적용 예정입니다.)

단일 Web ACL을 여러 개 CloudFront 배포에 사용할 수 있습니다만 각 배포는 하나의 Web ACL만 적용 됩니다. 설정을 하면 몇 분 안에 적용이 됩니다. Web ACL이 동작해서 얼마나 규칙이 적용되는 지 CloudWatch 통계치를 통해 확인할 수 있습니다.

API 기능 소개
지금까지 설명한 모든 기능은 API로도 수행이 가능합니다.

  • CreateIPSet, CreateByteMatchSet, 및 CreateSqlInjectionMatchSet – 조건 생성
  • CreateRule – 조건에서 규칙 생성
  • CreateWebACL-규칙에서 Web ACL 생성
  • UpdateWebACL– CloudFront 배포에 Web ACL 적용

그 외에도 목록 보기, 정보 업데이트 및 삭제를 할 수 있는 API들이 있습니다.

GetSampledRequests 함수를 실행하면 5,000개의 호출을 해서 특정 패턴의 규칙이 적용되는지 확인해 볼 수 있습니다. 호출 결과 실행한 동작(ALLOW, BLOCK, COUNT)에 대한 상세한 정보를 얻을 수 있습니다.

지금 사용하기
AWS WAF은 오늘 부터 바로 CloudFront에서 사용할 수 있습니다. 가격은 $5/web ACL, $1/rule이며, 1백만 HTTP 호출당 $0.60 입니다.

— Jeff;

이 글은 New – AWS WAF의 한국어 한국어 번역이며, re:Invent 2015의 신규 서비스 소식입니다.

Route53 지연 속도 기반 라우팅 활용하기

AWS는 전 세계에 11개의 리전(Region)과 30개의 가용 영역(Availability Zone)으로 글로벌 서비스를 제공함으로써, 각 국가 또는 지역 사용자에게 가장 빠른 서비스를 제공합니다. 뿐만 아니라 Amazon CloudFront라는 전용 콘텐츠 전송 네트워크를 통해 네트워크 속도 측면에서 가장 가까운 53개의 에지(Edge)에서 더 빠르게 정적 콘텐츠 및 동적 캐싱을 통해 더 빠른 서비스 전달이 가능합니다.

이를 위해 원래 콘텐츠 위치(Origin)인 S3 버킷에서 가장 빠른 클라우드프론트 에지를 찾아야 할 필요가 있습니다. 그래야 더 빠르게 콘텐츠를 배포할 수 있을 테니까요. 많은 고객들이 이러한 질문을 해주셨습니다.

이 글에서는 도메인 네임 서비스로 알려진 Amazon Route53의 여러 가지 기능 중 지연 속도 기반 라우팅(Latency based routing)을 통해 위와 같은 질문에 대한 해결 방법을 찾아 보도록 하겠습니다.

지연 속도 기반 라우팅(Latency based routing) 설정하기
만약 AWS 위에서 운영 중인 서비스가 동경 리전(Tokyo region)과 버지니아 리전(Virginia region)을 통해 서비스 되고 있을 경우, 이 서비스 도메인 이름을 Route53을 통해 등록하고 지연 속도 기반 라우팅을 설정 할 수 있습니다. 이러한 경우 Route53은 해당 서비스의 DNS 질의를 했을 때, Tokyo와 Virginia region 중 고객 입장에서 보다 낮은 지연 속도(Latency)를 가질 수 있는지 판단하여 지연이 낮은 리전의 주소를 반환합니다.

대부분의 경우, 아시아쪽 고객은 동경 리전으로 미국쪽 고객은 버지니아 리전으로 DNS 주소를 반환하고, 사용자의 접속 속도는 훨씬 빨라지게 되므로 사용자의 경험은 증가할 것입니다.

우리는 이러한 라우팅이 잘 동작하는지 검증하기 위한 도구를 만들기 위해 버지니아, 아일랜드 및 동경 리전에 각각 S3 버킷을 만들고 정적 웹 호스팅을 구현한 후 location.txt라는 파일을 만들어 각각 자신의 리전이름(예: I’m in Virginia)을 표시하도록 하였습니다.

  • 버지니아: Virginia.cloudinternal.com
  • 아일랜드: Ireland.cloudinternal.com
  • 동경: Tokyo.cloudinternal.com

버킷 생성과 Index 문서 설정이 끝났다면, Route53으로 이동하여 해당 버킷이 도메인명을 통해 인터넷에서 접근할 수 있도록 Route53 Alias 기능을 이용해 ireland.cloudinternal.com, tokyo.cloudinternal.com, virginia.cloudinternal.com을 등록합니다.

사실 lbr.cloudinternal.com이 실제 지연 속도 기반 라우팅으로 설정할 도메인 이름입니다. 레코드에 등록할 때 Routing PolicyLatency로 설정하고, Region은 타겟 S3 버킷 위치에 해당하는 리전을 설정합니다. 예를 들어, ireland.cloudinternal.com을 Target으로 등록할 때는 리전을 eu-west-1으로 선택하게 됩니다.

즉, eu-west-1(아일랜드 리전)에 가까우면 ireland.cloudinternal.com로, ap-northeast-1(동경 리전)에 가까우면 tokyo.cloudinternal.com로, us-east-1(버지니아 리전)에 가까우면 virginia.cloudinternal.com으로 DNS 응답을 받을 수 있도록 설정합니다.

라우팅 결과 살펴보기
각 지역의 가까운 곳에서 DNS Lookup을 하여 실제로 가까운 S3 버킷으로 연결되는지 시험합니다. 아일랜드와 오레곤 리전에 각각 t2.micro로 인스턴스를 실행하고, dig 명령을 실행합니다. 동경은 한국에서 연결될 가능성이 높으니 직접 자신의 랩탑에서 시험해도 좋습니다.

Oregon Instance에서 DNS lookup실행

$ ssh -i [your_key_file1]  ec2-user@52.27.81.xxx 'dig +short lbr.cloudinternal.com'
virginia.cloudinternal.com.s3-website-us-east-1.amazonaws.com.
s3-website-us-east-1.amazonaws.com.
54.231.16.60

Ireland Instance에서 DNS Lookup 실행

$ ssh -i [your_key_file2] ec2-user@54.171.115.xxx 'dig +short lbr.cloudinternal.com'
ireland.cloudinternal.com.s3-website-eu-west-1.amazonaws.com.
s3-website-eu-west-1.amazonaws.com.
54.231.129.36

한국 내에서 DNS Lookup 실행

$ dig +short lbr.cloudinternal.com
tokyo.cloudinternal.com.s3-website.ap-northeast-1.amazonaws.com.
s3-website.ap-northeast-1.amazonaws.com.
54.231.230.12

가까운 AWS 리전의 S3 주소가 반환되는 것을 확인 할 수 있습니다.

빠른 CloudFront S3 Origin 설정하기

이제 lbr.cloudinternal.com으로 CloudFront Origin을 설정하면 자동으로 가까운 S3 버킷을 Origin으로 객체(Object)를 가져오겠지만, S3는 HTTP Request header 의 Host 정보를 참조하여 Bucket 이름과 다르면 404 Not Found 페이지를 반환합니다. 따라서 추가적인 설정이 필요합니다. 지연 속도 기반 라우팅이 잘 동작하니, CDN 서비스를 요청하는 클라이언트는 Route53을 통해 내가 어느 쪽 리전으로 접근해야 하는지 확인한 후, URL에 해당 리전 정보를 포함하여 요청하면 지연 속도가 낮은 쪽의 S3 버킷을 원래 소스 저장소(Origin)로 선택할 수 있습니다.

WHERE = `dig +short lbr.domainname.com`
CF_URL = dfoijefo2eoifjeaf.cloudfront.net/$WHERE/target_file.jpg

위와 같은 로직을 수행하기 위해서 CloudFront에서 Origin과 Behavior를 아래와 같이 설정합니다.

Origin 설정

Behavior 설정

간단히 아래와 같이 가까운 Region위치를 알 수 있습니다.
한국에서 수행

$ dig lbr.cloudinternal.com +short | awk -F "." '{ print $1 }' | head -1
tokyo

Oregon region 인스턴스에서 수행

$ ssh -i [your_key_file] ec2-user@52.27.81.xxx  'dig +short lbr.cloudinternal.com' | awk -F "." '{ print $1 }' | head -1
virginia

Ireland region 인스턴드에서 수행

$ ssh -i [your_key_file2] ec2-user@54.171.115.xxx 'dig +short lbr.cloudinternal.com' | awk -F "." '{ print $1 }' | head -1
ireland

최종적으로 알게된 리전을 URL Prefix에 포함하여 요청하여 원하는 결과를 얻을 수 있습니다.

$ curl http://d2r05xiwqufy6.cloudfront.net/ireland/location.txt
I'm in Ireland.
$ curl http://d2r05xiwqufy6.cloudfront.net/tokyo/location.txt
I'm in Tokyo
$ curl http://d2r05xiwqufy6.cloudfront.net/virginia/location.txt
I'm in Virginia

지금까지 우리는 Route 53의 지연 속도 라우팅 방식을 기반으로 CloudFront의 소스 파일이 위치한 가장 가까운 S3 버킷의 위치를 찾는 문제를 해결해 보았습니다. 이를 위해 S3 정적 웹 호스팅 및 CloudFront의 몇 가지 기능을 활용하기 위한 설정이 필요했지만, 단순히 리전간에 구성된 웹 서비스의 Elastic Load Balancing 주소를 지연 속도 기반 라우팅으로 Route 53에 구성하면 복잡한 설정 없이 CloudFront을 통해 동적 콘텐츠도 활용할 수 있는 구성을 할 수 있습니다.

본 글은 아마존웹서비스 코리아의 솔루션즈 아키텍트가 국내 고객을 위해 전해 드리는 AWS 활용 기술 팁을 보내드리는 코너로서, 이번 글은 김일호 솔루션즈 아키텍트께서 작성해주셨습니다.