이 문서는 구글에 널려 있는 서명된 URL 관련 가이드 메뉴얼을 따라할 시 작동되지 않았거나, 용어의 의미가 모호해서 어려움을 겪으신 분들을 위한 자료입니다.
구글에 서명된 URL(Signed URL)
과 관련된 자료를 찾아보았을 때, 용어에 대해 제대로 이해하지 못한 채 작성된 정보, 잘못된 정보들이 꽤 많아서 그러한 가이드를 따라할 시 URL
이 제대로 작동되지 않았습니다.
그래서 최대한 AWS 공식문서
를 참조해 나름대로 Signed URL
을 구현했고, 성공했습니다.
단시간(최소 몇 분) 동안만 유효한 URL을 사용하여 프라이빗 콘텐츠를 배포할 수 있습니다. 이때, 유효한 URL을 서명된 URL(Signed URL)
이라고 합니다.
S3 버킷을 생성하고, 버킷 안에 간단한 index.html
파일을 업로드 합니다. 버킷 앞단에는 CloudFront
를 붙이고, CloudFront
의 서명된 URL
을 이용해서만 버킷의 index.html
에 접근할 수 있도록 합니다.
버킷을 생성합니다.
ACL은 비활성화하고,
퍼블릭 액세스를 허용합니다.
아래와 같은 내용의 index.html
파일을 버킷에 업로드합니다.
<h1>hello world!</h1>
리눅스 서버를 하나 생성합니다.
openssl
패키지를 설치합니다.
(이미 설치되어 있을 수도 있습니다)
% sudo yum install -y openssl
먼저 RSA
알고리즘을 이용한 private key
를 생성합니다.
% openssl genrsa -out private_key.pem
그리고 private key
를 이용해 public key
를 생성합니다.
% openssl rsa -in private_key.pem -out public_key.pem -pubout
[CloudFront 콘솔] > [키 관리] > [퍼블릭 키] > [퍼블릭 키 생성]
생성한 퍼블릭 키 내용을 넣고 생성합니다.
[CloudFront 콘솔] > [키 관리] > [키 그룹] > [키 그룹 생성]
아까 생성한 퍼블릭 키를 선택하고 키 그룹을 생성합니다.
배포
를 생성합니다.
원본 도메인은 이전에 생성한 S3 버킷
을 선택하고, OAI
를 사용하도록 한 뒤, 버킷에 대한 OAI
를 생성합니다.
(OAI
는 CloudFront
를 통해서만 원본에 액세스할 수 있도록 제한합니다)
다른 값들은 기본값으로 하되, 뷰어 액세스 제한
항목을 주목합니다.
뷰어 액세스 제한
을 Yes
로 지정하고, 인증 유형
을 이전에 생성한 키 그룹
으로 지정합니다.
다른 값들은 모두 기본값으로 두고, 배포를 생성
합니다.
다시 리눅스 서버로 돌아옵니다.
아래 내용의 policy
라는 파일을 생성합니다.
% vim policy
{
"Statement": [
{
"Resource": "base URL or stream name",
"Condition": {
"DateLessThan": {
"AWS:EpochTime": ending date and time in Unix time format and UTC
}
}
}
]
}
Resource
속성에는 CloudFront
의 도메인
과 접근할 파일 경로
를 입력합니다.
(프로토콜은 http
또는 https
을 사용할 수 있고, 프로토콜에 따라 서명값이 다르게 나옵니다. 도메인 뒤에 접근 파일 경로
까지 반드시 적어줘야 합니다)
AWS:EpochTime
에는 서명된 URL이 만료될 시간
을 입력합니다.
=> EpochTime 확인 사이트
{
"Statement": [
{
"Resource": "https://dip2vyhcaqkt6.cloudfront.net/index.html",
"Condition": {
"DateLessThan": {
"AWS:EpochTime": 1654909923
}
}
}
]
}
policy
과 private key
을 이용해 서명값을 생성합니다.
한 줄로 된 긴 서명값이 생성됩니다.
% cat policy | tr -d "\n" | tr -d " \t\n\r" | openssl sha1 -sign private_key.pem | openssl base64 -A | tr -- '+=/' '-_~'
ZaXiGaLrSdEj3RXp...YF3T4DBJA__
서명된 URL의 형식은 아래와 같습니다.
<policy에 적힌 resource 값>?Expires=<policy에 적힌 epochtime>&Signature=<생성한 서명값>&Key-Pair-Id=<Cloudfront 퍼블릭 키 ID>
<policy에 적힌 resource 값>
와 <policy에 적힌 epochtime>
는 policy
파일 내용에서 확인 가능합니다.
{
"Statement": [
{
"Resource": "https://dip2vyhcaqkt6.cloudfront.net/index.html",
"Condition": {
"DateLessThan": {
"AWS:EpochTime": 1654909923
}
}
}
]
}
<생성한 서명값>
은 한 줄로 된 긴 값입니다.
ZaXiGaLrSdEj3RXp...YF3T4DBJA__
<Cloudfront 퍼블릭 키 ID>
는 [CloudFront 콘솔] > [키 관리] > [퍼블릭 키]
에서 확인 가능합니다.
결과적으로 생성된 서명된 URL
은 아래와 같습니다.
https://dip2vyhcaqkt6.cloudfront.net/index.html?Expires=1654909923&Signature=ZaXiGaLrSdEj3RXpugEY0TPGlDPtSN44AHGMGPS~1zzicTdU-Hvb-Q2ZY0Nd3-UmEr0HbHtFHDI8HHPU0lbazfUngmX1BTpMSMr53sLdUJRXqxuPF~d-G-9-idGzBO686S1iR-WxisiduG1Se544UE7fNcg6RJOa6UrGyVmbMdbu4hv4Ebt5YxYkQZiDxqyBlPKxBvquny9Bw3OjmVmJNsGZUxdNdg-RlS-31gOLj1e7koI~ZfS1Wb1BVaPcra9WY2Qe1WehQSLjxy7o63vCi1mrzgLCaWuFXLuttRxmrl7fIONHytqfg-joyid8GwEZuR-PCF93tt87GYF3T4DBJA__&Key-Pair-Id=K36JF7FEPZS1C3
단순히 CloudFront 도메인
을 이용해 접속하면 접속되지 않습니다
.
생성한 서명된 URL을 이용하면 정상적으로 접속
되는 것을 확인할 수 있습니다.
Expires
속성에 명시된 만료 EpochTime
이 지나면 해당 서명된 URL은 만료됩니다.
Missing Key
에러가 나타난다면, Key-Pair-Id
속성값이 잘못되었다는 의미입니다.
CloudFront 콘솔
의 퍼블릭 키 ID
를 제대로 입력했는지 확인해보시기 바랍니다.
액세스 거부(403)
는 여러가지 원인으로 발생할 수 있습니다.
EpochTime 불일치
: policy
파일에 적힌 EpochTime
과 동일한지 확인하세요.잘못된 서명값
: policy
파일에 적힌 http
프로토콜과 URL로 접근할 때 http
프로토콜이 같아야 합니다. 예를 들어, policy
파일의 Resource
에는 http
로 적어서 서명값을 만들고, 접근할 때 https
프로토콜을 사용한다면 접근이 제한됩니다.참고 사이트