Presigned URL 이란 AWS 자원에 대한 접근 권한을 제공하기 위해서 사용되는 이름 그대로 사전에 적절한 권한을 가진 자격증명에 의하여 Signed 된 URL 을 말합니다. AWS 에서는 Presigned URL 을 다양한 서비스에서 활용이 가능한데요. Sagemake 에서 사용하는 Notebook 을 위한 Presigned URL, CloudFront 에서 사용하는 Signed URL, S3 에서 사용하는 Presigned URL 등이 모두 비슷한 개념이라고 생각하시면 될 것 같습니다.
이 포스트에서는 S3 에 활용할 수 있는 Presigned URL 을 생성하고 사용하는 방법에 대해 살펴 보도록 하겠습니다.
Presigned URL 은 Presigned URL 다양한 도구들을 통해 생성할 수 있는데요. 대표적으로 REST API 나 AWS CLI 그리고 AWS SDK 를 통해서 Java, .Net, Ruby, PHP, Node.js, Python 등을 통해 생성할 수 있습니다.
가장 간편하게 사용할 수 있는 방법인 AWS CLI 를 통해 Presigned URL 을 생성해보도록 하겠습니다.
기본적인 문법은 아래와 같습니다.
aws s3 presign “s3://S3 Object Path” --expires-in "만료시간" --region “대상 리전"
실제 생성할 때는 아래와 같이 따옴표를 제외하고 값을 입력한 후에 사용하면 됩니다.
aws s3 presign s3://seoul.mysharedbucket/shared/object1.pdf --expires-in 120 --region ap-northeast-2
정상적으로 Presigned URL 이 생성이 되면 아래와 같은 접속 가능한 URL 정보를 획득하게 됩니다. ( 아래의 URL 은 S3 의 특정 Object 를 다운로드할 수있는 권한이 적용되어 있는 URL 입니다. )
https://s3.ap-northeast-1.amazonaws.com/seoul.mysharedbucket/shared/object1.pdf?AWSAccessKeyId=AKIA4M5UW2CW6AUA12XF&Signature=znGxUR6m9hXe9HdNbGEWAlewFeM%3D&Expires=1594605140
이렇게 생성된 URL 을 사용하면 해당 URL 에 접근하는 모든 사람은 IAM 권한이 없더라도 Presigned URL 에 공유되어 있는 Object 를 다운로드할 수 있게 됩니다.
AWS CLI 에 설정된 자격증명의 Region 과 사용하고자하는 S3 Bucket 의 Region 이 서로 다른 상황일 때 AWS CLI 에서 Region 을 명시하지 않고 Presigned URL 을 생성하면 아래와 같은 Error 가 발생하게 됩니다.
따라서, AWS CLI 를 사용하는 경우라면 Presigned URL 생성 시 사용하는 IAM 자격증명의 Region 과 S3 Bucket 의 Region 이 다를 수 있으므로 항상 Region 을 지정하여 Presigned URL 을 생성하는 것을 권고합니다.
Presigned URL 은 S3 Bucket 을 공유할 때(다운로드 or 업로드) 편리하게 사용할 수 있다는 장점이 있지만 S3 Bucket 에 대한 권한이 없는 환경에서도 Bucket 에 대한 접근 권한을 줄 수 있다는 점에서 조심스럽게 사용되어야 합니다. 아래의 AWS 링크는 Presigned URL 을 사용할 때 참고하여야 할 몇가지 사항에 대해 안내하고 있습니다.
S3 Presigned URL 을 생성하는데에는 별도의 Permission 이 필요하지 않습니다. 즉, 누구나 Presigned URL 을 생성할 수 있으며 공유 대상이 되는 S3 Bucket 도 별도의 제한없이 지정이 가능합니다. 왜냐하면 S3 Presigned URL 은 공유 대상이 되는 S3 Bucket 과 Object 를 지정하고 공유를 하는 IAM 자격증명의 권한을 함께 지정함으로써 최종적으로 누군가가 Presigned URL 로 접근했을 때 Presigned URL 에 포함되어 있는 권한을 검사하여 해당 요청을 허용/차단하도록 동작하기 때문입니다. 즉, 최종적인 권한 검사는 Presigned URL 을 이용한 요청이 유입되었을 때 이루어지기 때문에 Presigned URL 을 생성하는 단계에서 어떤 제한을 적용할 수는 없습니다. 따라서, Bucket Policy 나 IAM Policy 에 다양한 Condition 을 적용하여 권한을 적절하게 제한하여 사용하는 것이 중요합니다.
예를 들어, 아래와 같은 Bucket Policy 를 적용한다면 Presigned URL 을 생성한 사용자가 적절한 권한을 가지고 있다고 하더라도 해당 Presignged URL 을 이용해서 지정된 VPC 외부로 S3 에 저장된 데이터를 공유하는 것을 방지할 수 있습니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Allow Bucket Access From specified VPC only",
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/username"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::bucketname/*",
"Condition": {
"StringNotEquals": {
"aws:sourceVpce": "vpce-xxxxxxxx"
}
}
}
]
}
아래는 Script 를 이용하여 Presigned URL 을 생성하는 방법을 설명하는 AWS Tech Blog 입니다.
감사합니다.