[AWS] Signed URL로 CloudFront 콘텐츠 사용 제한하기

반응형

이번 글에서는 Signed URL을 활용해 CloudFront의 콘테츠 사용을 제한해보겠습니다.

0. Signed URL이란?

CloudFront로 배포되는 파일의 사용을 제한하는 기능

Signed URL은 특정 날짜가 지나면 파일을 받지 못하게 하고 싶을 때, 특정 날짜 이후에 파일을 받게 하고 싶을 때, 특정 IP에서만 파일을 받을 수 있도록 할때 사용합니다.

Signed URL은 크게 2가지가 있습니다.

Canned Policy Signed URL : 파일 1개의 사용을 제한합니다. 또한, 특정 날짜가 지나면 파일을 받지 못하게 하는 기능만 사용할 수 있습니다.

Custom Policy Signed URL : 파일 여러 개의 사용을 제한합니다. 특정 날짜가 지나면 파일을 받지 못하게 하는 기능, 특정 날짜 이후에 파일을 받을 수 있도록 하는 기능, 특정 IP 혹은 특정 IP 대역에서만 파일을 받을 수 있도록 하는 기능을 사용할 수 있습니다.

자세한 내용은 아래의 책을 참고하시길 바랍니다.

 

아마존 웹 서비스를 다루는 기술:실무에서 알아야 할 기술은 따로 있다!

COUPANG

www.coupang.com

1. Signed URL Behavior 설정

이번 실습에선 이미 S3 버킷과 연결된 CloudFront가 있다고 가정하겠습니다.

먼저 Signed URL을 사용하려면 CloudFront에서 Behavior를 설정해야합니다. 아래와 같이 Distributions 탭에서 'Distribution Setting' 버튼을 눌러줍니다.

image.png

다음으로, 'Behavior' 탭에서 'Defualt'를 선택한 뒤 'Edit' 버튼을 눌러줍니다.

image.png

여기에서 'Restrict Viewer Access'Yes로 선택 후 저장하면 Signed URL을 사용하기위한 설정을 완료했습니다.

image.png

배포 완료 후 기존의 CloudFront의 도메인을 통해 S3에 접근하면 아래와 같이 MissingKey 에러가 발생합니다.

image.png

이제부터는 CloudFront는 SignedURL에 맞는 매개변수를 함께 던져주지않으면 Missing Key 에러를 발생시킵니다.

2. Signed URL 키 쌍 생성하기

자 이제 Signed URL을 생성하기위한 CloudFront 전용 키 쌍과 엑세스 키를 발급해보겠습니다.

먼저 화면 상단의 자신의 이름을 클릭하고, 'My Security Credentials' 탭으로 이동합니다.

image.png

화면에서 'CloudFront key pairs' 탭을 누른뒤, 'Create New Key Pair' 버튼을 누릅니다.

image.png

간단히 키가 발급되었습니다. 이제 'Download Private Key File''Download Public Key File'을 눌러 반듯이 파일을 받아줍니다.

만약 이때 파일을 받지 않는다면, 다시는 해당 파일을 다운로드 할 수 없습니다.

image.png

제가 발급 받은 Access Key ID는 아래와 같습니다.

image.png

또한, 다운로드한 개인 키와 공개 키 파일의 이름은 다음과 같은 형태입니다.

개인키 : pk-<액세스 키>.pem (pk-APKAJRBALJ6CSG6QG7QQ.pem)
공개키 : rsa-<액세스 키>.pem (rsa-APKAJRBALJ6CSG6QG7QQ.pem)

3. Signed URL 생성하기

위에서 발급받은 개인키를 사용해 Signed URL을 생성해 보겠습니다.

Signed URL을 생성하기위해 발급받은 CloudFront 키 쌍의 개인키(Private Key)를 사용해 정책(Policy)서명(Signing)하게 됩니다. 정책을 서명하는 이유는 정책이 변조되었는지 검증하기 위해서입니다. Signed URL에 설정된 정책 내용과 서명 데이터(Signature)가 맞지 않으면 Signed URL은 동작하지 않습니다.

위 내용이 이해가 가지 않을 수 있는데, Canned Policy Signed Url로 간단히 예를 들어보겠습니다.

먼저 아래와 같이 canned_policy 정책을 명시한 json 파일이 있다고 가정해봅시다

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

위의 내용을 해석해보면, d1c82gszbb81mo.cloudfront.net/index.html으로 접근하는 요청은 UTC : 1575393787시간 이내의 경우에만 허용하겠다고 해석 할 수 있습니다. 이러한 내용을 정책(Policy)이라고 합니다.

이 정책(Policy) 파일을 발급받은 개인키 (pk-APKAI2MZSDYSOWMFS35A.pem)로 서명(Signing)을 하게되면 해시함수로 변환된 서명데이터(Signature)가 생성됩니다. (예제에서는 Linux 터미널을 사용했습니다.)

Linux 서명 명령어

cat canned_policy.json | openssl sha1 -sign pk-APKAI2MZSDYSOWMFS35A.pem | openssl base64 | tr '+=/' '-_~'

위의 Linux 명령어를 사용해 발급받은 서명 데이터 (Signature)

e3FXvAcvl7mQ0gZYGJGwrM~Fa4yiATrUW1s5U3DM-ptLzZ3J-XzVCnBN4~Eljaa9
zlT~nO5Qq7BEvfrHHpSvsuyqdxoLnQU1dtoUJz9fUr9SpQJsRqwuh8SOIaeERCm~
abwUfgeuYhufLHZzZeDNAYZ-DgFJ8Q7TP7RZxLo6RyJkhGv9SPVaqkeANzTfe8R3
A29Uu76-vbna1pfnqykuu56sqN8ga2PJA7u-9ZzG-aAMbyiPjK0deys~s-jdNofb
57FTJjlw5vEd7d~psxk1sXA~nrGhlRo8MRpFAJBbDdc2YiOJg-v0KSUlsXYLfO3t
g0Nra187h01PewQfUVMhng__

최종적으로 생성한 서명 데이터(Signature)를 사용해 아래와 같이 Signed URL을 작성합니다.

http://d1c82gszbb81mo.cloudfront.net/index.html?Expires=1575393787&Signature=e3FXvAcvl7mQ0gZYGJGwrM~Fa4yiATrUW1s5U3DM-ptLzZ3J-XzVCnBN4~Eljaa9
zlT~nO5Qq7BEvfrHHpSvsuyqdxoLnQU1dtoUJz9fUr9SpQJsRqwuh8SOIaeERCm~abwUfgeuYhufLHZzZeDNAYZ-DgFJ8Q7TP7RZxLo6RyJkhGv9SPVaqkeANzTfe8R3A29Uu76-vbna1pfnqykuu56sqN8ga2PJA7u-9ZzG-aAMbyiPjK0deys~s-jdNofb57FTJjlw5vEd7d~psxk1sXA~nrGhlRo8MRpFAJBbDdc2YiOJg-v0KSUlsXYLfO3tg0Nra187h01PewQfUVMhng__&Key-Pair-Id=APKAI2MZSDYSOWMFS35A
  1. 최종 SignedURL 작성시 'Expires' 파라미터에는 정책(Policy)에 입력했던 UTC 시간인 1575393787를 입력합니다.
  2. 'Signature' 파라미터에는 생성한 서명 데이터(Signature)를 입력합니다.
  3. 'Key-Pair-Id' 파라미터에는 정책(Policy)을 서명(Signing)할때 사용한 개인키(Private-key)의 이름을 입력합니다.

Canned_policy_signed_url : 도메인 + Expires + Signature + Key-Pair-Id

위처럼 Signed URL에는 정책내용(Expires)과 해당 정책을 서명한 개인키(Private-key), 그리고 서명 데이터(Signature)가 함께 포함되어 있기 때문에 해당 정책이 변조되었는지 아닌지를 판단 할 수 가 있습니다.

4. 주의사항

이번 예제를 진행하는데 있어 주의사항은 다음과 같습니다.

  1. 책의 내용대로 Linux EC2 인스턴스에서 정책을 서명할 경우, 발급받은 CloudFront 개인키를 EC2 인스턴스 서버로 전송해 사용해야합니다. 저는 WinSCP를 사용해 발급받은 개인키를 EC2 인스턴스 서버로 옮겼습니다.

  2. 정책파일(canned_policy.json)에 명시한 'AWS:EpochTime'Signed URL에 입력한 'Expires'의 값이 다를경우 Signed URL은 이를 변조된 URL로 인식해 접근을 거부합니다.

5. 결론

CloudFront로 배포되는 파일의 사용을 제한하고 싶으면?
-> Signed URL을 사용한다.


파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음


반응형

댓글

Designed by JB FACTORY