AWS에는 S3(Simple Storage Service)라는 저장소가 존재한다. S3에서는 데이터를 저장하기 위한 기본 컨테이너를 bucket라고 부르는데, 이 bucket에 Referer를 통한 접근제어 정책을 설정 해 특정 도메인에서만 접근할 수 있도록 하는 방법을 정리한다.

S3에서 bucket을 생성할 때 아무 설정도 건드리지 않는다면 기본적으로 bucket과 bucket 내 파일의 접근 권한은 private이 된다. 하지만 웹에서 사용하는 이미지 등을 S3 등에 올리며, 설정을 public으로 바꾸는 경우가 있는 것 같다.

bucket의 접근 권한 설정을 public으로 할 경우 설정에 따라 임의의 사용자가 파일 업로드 및 다운로드 할 수 있으므로 접근제어 정책을 설정 해 주는 것이 좋다. S3 페이지에 접속하여 bucket을 선택한 후, 권한 > 버킷 정책을 선택하면 아래와 같이 버킷 정책 편집기를 확인할 수 있다.

스크롤을 아래로 내려 보면 정책 생성기가 있는데, 이를 선택한다.

아래는 정책 생성기의 기본 페이지 모습이다. 정책을 설정하는 것은 아니고, 버킷 정책 편집기에 들어갈 정책을 format에 맞게 만들어 주는 페이지이다. 만약 정책 설정 format을 모두 알고있다면 굳이 정책 생성기를 사용 할 필요는 없는 것 같다.

정책을 설정하기 위해 아래와 같이 선택한다.

Amazon Resource Name (ARN)은 앞의 버킷 정책 편집기 페이지에서 확인할 수 있다.

모든 정책을 다 적으면 아래와 같다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
* Effect : Allow
* Principal : *
* AWS Service : Amazon S3
* Actions : GetObject
* Amazon Resource Name (ARN) : [버킷 정책 편집기] 페이지에서 확인한 값/*

> Add Conditions (Optional)
* Condition : StringLike
* Key : aws:Referer
* Value : http://DOMAINNAME/*

각 설정에 대한 설명은 다음과 같다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
* Effect : 특정 도메인에 대해 '허용'하는 정책이므로 Allow
* Principal : 정책을 적용할 대상, 웹을 통해 접속하는 모든 사람이 대상이므로 *
* AWS Service : 적용 할 서비스 명
* Actions : 정책이 적용되는 action. S3에서 이미지 파일을 다운로드 하므로 s3:GetObject
* Amazon Resource Name (ARN) : [버킷 정책 편집기] 페이지에서 확인한 값/*

> Add Conditions (Optional)
* Condition : 정책 조건 부여. 특정 도메인을 통할 경우 정책이 적용되어야 하므로 StringLike
* Key : 조건을 어디에 적용할 지. 이 경우 Referer를 통해 확인하므로 aws:Referer
* Value : 허용 할 도메인 값을 입력, http://DOMAINNAME/*
  => if (Referer == "http://DOMAINNAME/*") 와 같음

HTTP Referer란?

  • 웹 브라우저로 World Wide Web을 서핑할 때 하이퍼링크를 통해 각각의 사이트로 방문 시 남는 흔적
  • 예를 들어 A 페이지에서 B 사이트로 이동하는 하이퍼링크가 존재 할 경우, 사용자가 이 하이퍼링크를 클릭하면 웹 브라우저에서 B 사이트로 참조 주소(Referer)를 전송함
  • B 사이트 관리자는 이 Referer를 통해 방문객이 A 사이트를 통해 자신의 사이트에 방문한 것을 알 수 있음

모든 설정을 한 후, Add ConditionAdd Statement를 차례로 눌러 주면 아래와 같이 정책이 생긴 것을 알 수 있다. 이 후 Generate Policy를 눌러 준다.

그 결과 아래와 같이 JSON 형태의 정책을 확인할 수 있다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
    "Version": "2012-10-17",
    "Id": "Policy1586072492270",
    "Statement": [
        {
            "Sid": "Stmt1586072470528",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::OOOOO-test-bucket1/*",
            "Condition": {
                "StringLike": {
                    "aws:Referer": "http://OOOOO.kr/*"
                }
            }
        }
    ]
}

해당 값을 복사한 후 다시 버킷 정책 편집기로 돌아 와 붙여넣기 한 후, 저장 버튼을 선택하면 정책 설정이 완료된다.

접근 권한을 다시 설정하기 위하여 권한 > 퍼블릭 액세스 차단 메뉴로 가 아래와 같이 새 퍼블릭 버킷 또는 액세스 지점 정책을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단을 활성화 해 준다.

아래와 같은 확인 창이 뜨면 확인을 입력하고 확인 버튼을 눌러주면 된다.

위의 과정이 끝나면 퍼블랙 액세스 차단 설정이 아래와 같이 설정 된다.

이제 정책이 정상적으로 적용되었는지 확인 해 보면 된다. 나는 bucket에 flower.png를 넣어 뒀는데, 해당 이미지에 직접 접근하면 아래와 같이 AccessDenied가 뜨는 것을 확인할 수 있다.

이에, 내가 설정한 도메인에서 태그를 통해 해당 이미지를 불러오면 정상적으로 이미지가 출력된다.

이번엔 타인의 AWS CLI를 이용하여 해당 버킷에 접근할 수 있는지 확인 해 보았다. 역시나 AccessDenied가 나오므로, 설정이 정상적으로 적용된 것을 확인할 수 있다.