AWS 버킷 권한과의 씨름...

반응형

S3 권한이 뭔데 나를 이렇게 힘들게 하나요

배경

본인은 현재 소프트웨어 마에스트로 프로젝트를 하면서 설문에 대한 유저의 이미지 업로드 관련하여 S3를 사용할 일이 생겼다.

아참, 소프트웨어 마에스트로에 대해서는 글을 쓴다 쓴다 하면서 아직까지 못 쓰고 있는데.......(추후 쓸 예정)

어찌됐든 구글폼, 네이버폼 보다 이쁜 폼, 폼나는 폼을 만들 수 있는 웹 서비스를 제작중에 있다.

더폼 - 모든 폼을 대신하는 폼나는 설문조사
폼, 설문조사, 신청서, 자기소개서, 지원서, 만족도조사, 선호도조사,
https://the-form.io/

이때 S3 권한에 대한 요구사항은 이러하다.

  • 접근 허가된 유저만 이미지를 업로드(쓰기) 할 수 있어야 한다.
  • 업로드 된 사진은 모두에게 퍼블릭하게 읽기가 되어야 한다.

삽질

권한은 크게 3가지로 나뉜다.

  • 퍼블릭 액세스 차단(버킷 설정)
  • 버킷 정책
  • ACL(액세스 제어 목록)

이렇게 3가지가 존재한다.

여러 번의 실험 끝에 내린 결론은 이러하다.

2번을 설정해준다는 가정하에, 1번의 경우 전부 다 비활성 해줘야만 원하는 요구사항대로 동작했다.

그 이유는 이러하다.

  • IAM 유저에게 S3fullaccess도 주고, 2번 정책에서 PutObjectAcl, PutObject를 설정해주었지만, 위에서 새 ACL을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단과 ‘임의의 ACL을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단’이 이를 못하게 하기 때문이다.
  • 나머지 아래 두개인 새 퍼블릭 버킷 또는 액세스 지점 정책을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단, 임의의 퍼블릭 버킷 또는 액세스 지점 정책을 통해 부여된 버킷 및 객체에 대한 퍼블릭 및 교차 계정 액세스 차단 같은 경우는 퍼블릭 설정을 함부로 바꾸지 못하게 하는 설정 이라 보통 활성을 해준다고 하지만, 나같은 경우는 두개를 활성해주었을때 퍼블릭하게 읽기가 설정된 파일에도 접근이 잘 안되었다..

3번 같은 경우도 말하자면, 보통 나와 같이 서버에서 이미지 업로드를 한다는 가정하로는, 서버 측 코드 베이스로

각 파일에 대한 ACL을 설정하게 되므로 굳이 따로 설정해줄 필요는 없을 것 같다.

또한 우선순위는 1 > 2 = 3으로 적용되는 것을 확인했다.

또한 2번 정책보다는 IAM 사용자의 정책 S3fullaccess가 우선순위로 메겨지는 것 같다.(추후 실험 필요)


버킷 정책에서는

{
    "Version": "2012-10-17",
    "Id": "정책 만들면 생성되는 id",
    "Statement": [
        {
            "Sid": "정책 만들면 생성되는 sid",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::버킷 이름/surveys/*"
        },
        {
            "Sid": "정책 만들면 생성되는 sid",
            "Effect": "Allow",
            "Principal": {
                "AWS": "내 iam 유저"
            },
            "Action": [
                "s3:DeleteObject",
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::버킷 이름/*"
        }
    ]
}

이와 같이 설정해었는데, 즉 public하게 읽기 접근이 가능한 것은 버킷 내 surveys 폴더만 가능하게 설정을 해두었다.

실험 1

실제 코드에서는

  1. ACL의 public-read 설정 없이 업로드 해보았다.
//MULTER-S3 설정
const upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: "the-form-images/surveys",
    // acl: "public-read",
    contentType: multerS3.AUTO_CONTENT_TYPE,
    key: function (req, file, cb) {
      cb(null, Date.now() + "." + file.originalname.split(".").pop()); // 이름 설정
    },
  }),
});

결과

  • 객체 URL로 퍼블릭하게 읽기가 가능하다.

  1. ACL의 public-read 설정 있이 업로드 해보았다.
//MULTER-S3 설정
const upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: "the-form-images/surveys",
    acl: "public-read",
    contentType: multerS3.AUTO_CONTENT_TYPE,
    key: function (req, file, cb) {
      cb(null, Date.now() + "." + file.originalname.split(".").pop()); // 이름 설정
    },
  }),
});

결과

  • 객체 URL로 퍼블릭하게 읽기가 가능하다.

실험 2

  1. 코드를 이와 같이 버킷 정책에서 퍼블릭으로 설정한 surveys 이하가 아닌 버킷 자체로 업로드하였고, acl은 public-read를 해제해보았다.
//MULTER-S3 설정
const upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: "the-form-images",
    // acl: "public-read",
    contentType: multerS3.AUTO_CONTENT_TYPE,
    key: function (req, file, cb) {
      cb(null, Date.now() + "." + file.originalname.split(".").pop()); // 이름 설정
    },
  }),
});

결과

  • 정상적으로 접근 제한이 된다.

  1. 한번 acl 부분의 주석을 풀어보자..
//MULTER-S3 설정
const upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: "the-form-images",
    acl: "public-read",
    contentType: multerS3.AUTO_CONTENT_TYPE,
    key: function (req, file, cb) {
      cb(null, Date.now() + "." + file.originalname.split(".").pop()); // 이름 설정
    },
  }),
});

결과

  • 객체 URL로 퍼블릭하게 읽기가 가능하다.

결론

  • 버킷 정책 설정에서 읽기 설정이 되어 있거나, 파일을 업로드 하며 acl 설정을 해준것은 둘 중에 하나만 되어 있어도 정상 동작한다!
  • 즉 정책 설정을 해주었다면 굳이 파일을 업로드할 때 acl을 안붙여도 된다는 의미다!
  • 반대로 정책 설정에서는 읽기 허가를 안했어도 파일을 업로드할 때 acl을 붙이면 정상적으로 퍼블릭 읽기가 된다.

알아봐야할 점

  • 새 퍼블릭 버킷 또는 액세스 지점 정책을 통해 부여된 버킷 및 객체에 대한 퍼블릭 액세스 차단
  • 임의의 퍼블릭 버킷 또는 액세스 지점 정책을 통해 부여된 버킷 및 객체에 대한 퍼블릭 및 교차 계정 액세스 차단

위 두개의 활성화, 비활성화에 대한 파급 효과를 알아봐야겠다.

나의 경우에는 위 2개를 켜주면 아예 public하게 접근이 안되었다..

참고 자료

반응형