전 세계에 콘텐츠를 배포하는 CDN 서비스인 CloudFront

이재홍 http://www.pyrasis.com 2014.03.24 ~ 2014.06.30

Canned Policy를 사용한 Signed URL 생성하기

이제 Signed URL을 직접 생성해보겠습니다. Signed URL은 보통 애플리케이션에서 자체적으로 생성하여 사용합니다. 따라서 Java, PHP, C# 등의 프로그래밍 언어로 생성하는 것이 편리합니다. 하지만 프로그래밍 언어로 하나하나 설명하기에는 내용이 너무 길어지므로 Linux에서 커맨드라인 명령으로 간단하게 생성하는 방법을 알아보겠습니다.

먼저 Canned Policy를 사용한 Signed URL 생성 방법을 알아보겠습니다. Canned Policy에서 Canned는 미리 준비 되어 있는 상태를 뜻합니다. 따라서 CloudFront 배포 서버에서 정책을 이미 알고 있기 때문에 URL에 정책 내용이 포함되지 않습니다.

EC2 인스턴스 혹은 Linux가 설치된 컴퓨터에 SSH로 접속합니다. 그리고 텍스트 편집기를 열고 아래와 같이 작성한 뒤 canned_policy.js로 저장합니다.

  • Resource: 제가 생성한 CloudFront 배포의 도메인은 d38443sd7c5866.cloudfront.net 입니다. 여기서 도메인은 여러분들이 생성한 CloudFront 배포의 도메인을 입력합니다. http://d38443sd7c5866.cloudfront.net/index.html과 같이 http://를 포함한 CloudFront 배포 도메인과 파일의 경로를 포함한 파일명을 입력합니다.
  • DateLessThan → AWS:EpochTime: Signed URL에서는 이 만료날짜 값이 필수입니다. 그리고 UTC 형식을 사용해야 합니다. 위의 정책 파일에서 1399206886 값은 이미 지나가버린 시간 값이므로 그대로 사용하면 Signed URL이 동작하지 않습니다. 꼭 미래의 시간 값을 사용하기 바랍니다.

canned_policy.json

{
  "Statement": [{
    "Resource": "http://d38443sd7c5866.cloudfront.net/index.html",
    "Condition": {
      "DateLessThan": {
        "AWS:EpochTime": 1399206886
      }
    }
  }]
}

웹에서 UTC 값 생성하기
UTC 시간 값을 사람이 직접 계산하는 것은 무리가 있습니다. 이 값은 프로그래밍 언어를 통하지 않고도 인터넷에서 쉽게 생성할 수 있습니다.

http://www.epochconverter.com에 접속합니다.


그림 12-52 웹에서 UTC 값 생성하기

원하는 날짜와 시간을 입력한 뒤 Human date to Timestamp 버튼을 클릭하면 Epoch timestamp에 UTC 형식의 값을 얻을 수 있습니다. 이 사이트 이외에도 구글에서 utc converter라고 검색하면 같은 기능을 가진 비슷한 사이트가 많이 있습니다.

정책 파일의 공백을 모두 제거하고 한 줄로 만듭니다. 공백과 개행문자(새 줄)이 있으면 Signed URL이 동작하지 않습니다. 특히 파일 맨 끝의 개행문자는 꼭 제거해야 합니다.

canned_policy.json

{"Statement":[{"Resource":"http://d38443sd7c5866.cloudfront.net/index.html","Condition":{"DateLessThan":{"AWS:EpochTime":1399206886}}}]}

Vim에서 공백 및 개행문자 제거하기
공백 삭제하기

:%s/ //g

개행문자 제거하기(Windows에서는 \r\n)

:%s/\n//g

파일 맨 끝의(EOL) 개행문자 제거하기

:set binary
:set noeol

공백과 개행문자를 제거했으면 :wq를 입력하여 파일을 저장하고 Vim을 종료합니다.

다음과 같이 명령을 입력하여 서명 값Signature을 생성합니다.

[ec2-user@ip-172-31-21-171 ~]$ cat canned_policy.json | openssl sha1 -sign pk-APKAJERVTR4A7EO47UYA.pem | openssl base64 | tr '+=/' '-_~'
j4BzzIDpjzzDswJKtKFfQLGAD3bHhmPLW-OKGXydlPOwzHYjad0yp9I1f7T58e~X
6juzu3EXbR-P~edx49nDtPusgY4v6IhP3IWYThR7BdIY7I6BScjjynSA~vUF~E5e
z7MqZDUE7ZhKHFtOI9-h3rz5PX4uL1vwWRMST8AKDuOq0Xix6arLGeRgvXWlulmh
ebGpO-hUZA3ya5zGA2YXuMttHQp9yoJ8FO3AXuHNDWeKtGOWOOan0TzAS3TpgAfu
fk0SHhJQHa3fp-zWdZXrNAEx6fSdIMqlKyc8zY~KXPhECtGfzLzibWRtlCKKbhTS
j-0aSbHrdm14AXB5IGTmBg__
  • cat canned_policy.json: 방금 작성한 canned_policy.json 파일 입니다.
  • openssl sha1 -sign pk-APKAJERVTR4A7EO47UYA.pem: pk-APKAJERVTR4A7EO47UYA.pem는 CloudFront 키(Key Pair)에서 개인 키 파일입니다. 여러분들이 생성한 개인 키 파일을 지정합니다.
  • openssl base64: 서명 값(Signature)를 BASE64로 인코딩합니다.
  • tr ‘+=/’ ‘-_~’: BASE64로 인코딩 된 값 중에서 URL로 인식될 수 있는 문자를 다른 것으로 바꿉니다.

명령을 입력하면 canned_policy.json의 내용을 서명한 데이터가 출력됩니다.

메모장이나 기타 텍스트 편집기에서 아래와 같이 Signed URL을 직접 생성합니다.

  • http://d38443sd7c5866.cloudfront.net/index.html: 접속할 CloudFront 도메인과 파일명입니다. 이 도메인은 여러분들이 생성한 CloudFront 배포 도메인을 입력합니다.
  • Expires: Signed URL이 만료되는 날짜와 시간 값 입니다. 여러분이 canned_policy.json에 지정한 DateLessThan → AWS:EpochTime 값과 동일해야 합니다.
  • Signature: 생성한 서명 값을 이곳에 붙입니다. 생성할 때는 여러 줄로 출력이 되지만 URL로 사용할 때는 한 줄로 만들어서 붙여야 합니다.
  • Key-Pair-Id: CloudFront 액세스 키 값 입니다. 여러분들이 생성한 액세스 키 값을 입력합니다.
http://d38443sd7c5866.cloudfront.net/index.html?Expires=1399206886&Signature=j4BzzIDpjzzDswJKtKFfQLGAD3bHhmPLW-OKGXydlPOwzHYjad0yp9I1f7T58e~X6juzu3EXbR-P~edx49nDtPusgY4v6IhP3IWYThR7BdIY7I6BScjjynSA~vUF~E5ez7MqZDUE7ZhKHFtOI9-h3rz5PX4uL1vwWRMST8AKDuOq0Xix6arLGeRgvXWlulmhebGpO-hUZA3ya5zGA2YXuMttHQp9yoJ8FO3AXuHNDWeKtGOWOOan0TzAS3TpgAfufk0SHhJQHa3fp-zWdZXrNAEx6fSdIMqlKyc8zY~KXPhECtGfzLzibWRtlCKKbhTSj-0aSbHrdm14AXB5IGTmBg__&Key-Pair-Id=APKAJERVTR4A7EO47UYA

이제 Canned Policy를 사용한 Signed URL이 완성되었습니다. 웹 브라우저에서 이 URL로 접속해봅니다.

index.html의 내용이 정상적으로 출력됩니다. Expires에 설정한 날짜와 시간이 지나면 index.html 파일의 내용을 볼 수 없습니다.


그림 12-53 Canned Policy를 사용한 Signed URL에 접속

설정을 다 했는데도 Signed URL이 동작하지 않는다면 Resource에서 도메인과 파일명이 정확하게 설정되었는지, Resources에서 설정한 도메인으로 접속했는지, Expires와 DateLessThan → AWS:EpochTime 값이 일치하는지, canned_policy.json에서 공백과 개행문자, 파일 끝의 개행문자를 제거했는지, 서명에 사용한 개인 키와 Key-Pair-Id에 설정한 액세스 키가 동일한 것인지 확인하기 바랍니다.

CloudFront Signed URL과 Restrict Bucket Access
CloudFront를 Signed URL로 제한한다 하더라도 S3의 접근 권한이 열려 있으면 아무런 소용이 없습니다. 이렇게 되면 Signed URL을 사용하지 않고, S3으로 바로 접근하여 파일을 가져갈 수 있습니다. 따라서 S3에는 CloudFront만 접근할 수 있도록 꼭 Restrict Bucket Access를 설정합니다.

S3가 아닌 EC2 인스턴스나 외부 웹 서버를 오리진으로 사용한다면 웹 서버 레벨에서 CloudFront 만 접근 가능하도록 설정해야 합니다. 접근해오는 서버가 CloudFront 인지 판별하는 방법은 HTTP 헤더의 User-Agent의 내용을 확인하면 됩니다. CloudFront에서 접속해왔다면 헤더에는 "Amazon CloudFront"라고 표시됩니다.


저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.