AWS에서 Static한 Data를 Service 할 때 S3를 가장 많이 이용한다.

그리고 S3에 업로드된 파일을 Globally distribute 할 때는 CloudFront를 사용하여, Latency를 낮추고, Data transfer 속도는 높인다.

여기에 하나의 요구사항이 더 추가될 수 있다. Access Control!!

즉, 저장된 데이터에 허가받지 않은 사용자가 접근할 때, 이를 제어할 수 있어야 한다.

CloudFront는 Origin Access Identity를 통해 이를 제공한다.

* S3 Bucket을 생성한 뒤, 생성한 Bucket에 CloudFront를 연결하고, Origin Access Identity를 설정하여 Access Control을 해보자.

 

1. Bucket 생성 및 파일 업로드.

S3 Console이 워낙 잘 만들어져 있어서, S3 Bucket 생성과 파일 업로드는 누구나 쉽게 할 수 있다. 업로드한 파일의 경로는 아래와 같다.

https://[S3 region].amazonaws.com./[bucket-name]/[filename]

e.g) https://s3-ap-northeast-1.amazonaws.com/bucket-name/filename

* Bucket 생성 후 특별한 설정을 하지 않았다면, Owner 계정만 Open/Download/View/Edit 할 수 있도록 Permissions이 설정되어 있다. 현재 상태에서 추가한 파일을 요청해보면 403 Forbidden과 함께, AccessDenied라는 메시지를 확인할 수 있다.

 

2. Bucket에 CloudFront를 설정해보자.

CloudFront Console에서 CloudFront를 생성하는 과정 역시 매우 쉽다.

Console -> Create Distribution -> Origin Domain Name -> Dropdown의 S3 Bucket 리스트중에서 원하는 Bucket 선택 -> 생성.

* 생성한 CloudFront가 Enable되는데는 15분 정도가 소요된다.

CloudFront가 Enable된 이후에 CloudFront로 Bucket에 업로드된 파일에 접속해보자. 위에서와 동일하게 403 Forbidden과 함께, AccessDenied라는 메시지를 반환한다. (기본적으로 Bucket의 Permission 설정을 따라간다.)

S3 URL) https://s3-ap-northeast-1.amazonaws.com/bucket-name/filename

CloudFront URL) http://[cloudfront-domain-name]/filename

 

3. CloudFront distribution에 Origin Access Identity 추가.

Distribution 설정의 Origins Tab에 추가되어있는 Origin을 아래와 같이 수정하자.

* Restrict Bucket Access : Yes

* Origin Access Identity : Create a New Identity (기존에 사용하던게 있으면 Use a Existing Identity)

* Grant Read Permissions on Bucket : Yes, Update Bucket Policy

위와 같이 Origin 설정을 수정하면 CloudFront와 연결된 Bucket의 Policy에 Origin Access Identity 조건이 추가된다.

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html

 

4. S3 Console에서 Bucket Policy 확인.

S3 Console -> Choose Bucket -> Permissions -> Edit bucket policy (확인)

(* 지금까지 제대로 됐다면 위와 같이 Origin Access Identity Policy가 Bucket에 제대로 설정되어 있다.)

 

1~4번까지 설정이 완료됐다면, AWS의 구성은 완료됐다.  Client에서 Signed URL을 생성한 뒤 접근하는 과정만 남았다. 

 

5. CloudFront Key Pair 생성 (이미 발급 받았으면 Skip)

Security Credential 페이지에 접속하면 CloudFront key fair를 발급 받을 수 있다. .pem으로 발급되는 Key를 Client Platform에 맞게 변경하여 사용해야 한다.

e.g) Java : DER Format, .Net : XML Format

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-trusted-signers.html#private-content-reformatting-private-key

(* Private Key의 경우 재발급이 되지 않으니, 직사광선을 피해 잘 보관해야 한다.)

 

6. Signed URL 생성.

Signed URL을 생성하기 위해서는 Private KeyCloudFront Key Pair ID가 필요하다.

5번까지 정상적으로 진행했으면 2가지가 뭘 의미하는지 알아야한다.

Signed URL은 Base URL + 만료기간 + 허용 IP + Signature로 구성된 URL을 의미한다.

Signature 생성에 Private Key가 필요하고, CloudFront Key Pair ID를 동봉하여, 서버에서 Signed URL이 Valid한지 확인 할 수 있도록 한다.

e.g) http://d92s70lgx4e93.cloudfront.net/drmt.jpg?

Expires=1398919860&

Key-Pair-Id=APKAJRMC2OMX2MG46AEA&

Signature=gF9U0TBb7Hosg3rMbBdULbxTM9QZ-oHk8-gq1gaVkQABojKb5ynCeuJ8vJ5eWOTu4PlQvEnrsFLmr1mfvqNveQY8PLW3T-deUTU1FnJ9f-AzNihcuxLSILH0BX9~-Zz2wVArzB-zil15klQRxFf2PNhgKEgorO1ANqIpI7JYKhMl26O8nzah5xWfxa-Phni29Yl1RNS3MPyxO8UgoYk376jfFYFx8lq1r8r1aaQ1lZWNfKx1X0uS~oIuObMwCe~7yXGFWha-HSkDLoWObHgIi0nqUpVQyLaLf8VqMSJpH19Em8QZ-k2DH8GXovInX5xjOoRqQzTLixi70W-oB9-aPQ__

 

7. Create a Signed URL Using Java

아래 링크를 참고하면 JetS3t Library를 사용하여 Signed URL을 만들 수 있다.

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CFPrivateDistJavaDevelopment.html

 

8. Edge 서버에 Cache되는 시간 설정.

Edge 서버에 얼마나 오래 데이터를 캐싱하고 있을지는 CDN을 사용할 때, 항상 고려되어야 하는 부분이다.  Origin Data가 변경될 일이 거의 없는 경우라면 당연히 Longer is better다. 다만 Origin Data가 변경될 확률이 있다면, 이를 잘 고려해야한다.

* S3 Object의 Metadata중 Cache-Control 값을 통해 캐싱 시간을 설정할 수 있다. (Default는 24 hour.)

e.g) Cache-Control: max-age=seconds

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html

 

9. Check Cached? or Not?

CloudFront를 사용해서 데이터를 요청할 때, Edge 서버에 제대로 캐싱이 됐는지 확인하려면 Response Header의 X-Cache 필드를 확인하면된다.

Edge 서버에서 데이터를 내려줄 때는 ‘Hit from cloudfront’, Origin server에서 내려줄 경우에는 ‘Miss from cloudfront’ 라고 전달된다.

 

10. Edge 서버에 캐싱된 데이터 제거.

Edge 서버에 캐싱된 데이터가 유효하지 않다고 판단될 때, 캐싱된 데이터를 제거할 수 있다.

Invalidating Object 문서를 참고하자.

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html

 

* References