• 포스트
  • 도구
  • 작업
  • 포스트
  • 도구
  • 작업
로그인회원가입

© 2005 kaisa.co.kr. All Rights Reserved.

소개개인정보처리방침7083620@hanmail.net
← 목록으로
2024-08-14

S3 버킷·접근 제어·수명주기

S3 버킷·접근 제어·수명주기

요약: 객체 스토리지(S3)를 퍼블릭 차단·최소 IAM·수명주기로 안전하게 쓰는 기본선을 정리한다.


1. 언제 S3인가

S3는 Simple Storage Service, 객체 스토리지다. 파일을 경로처럼 보이지만 실제는 버킷 + 키다. 무제한에 가깝게 늘리고, HTTP로 읽고 쓴다.

맞는 경우 덜 맞는 경우
업로드 이미지, 백업, 로그, 정적 자산 자주 바꾸는 운영체제 디스크 (EBS)
데이터 레이크, 덤프, 산출물 보관 밀리초 단위 키-값 캐시 (Redis)
CloudFront 앞단 정적 웹 관계형 조회·트랜잭션 (RDS)
다른 리전 복제로 DR 동시에 같은 파일을 락 잡고 쓰는 공유 디스크

기본 원칙은 한 줄이다. 버킷은 비공개로 만들고, 필요할 때만 앞단을 연다. Block Public Access를 끄고 “일단 퍼블릭 읽기”는 유출 사고의 정석이다. 정적 웹이 필요하면 CloudFront + OAC를 검토한다. OAC는 Origin Access Control, CDN만 원본을 읽게 하는 장치다.


2. 핵심 개념

버킷은 리전 단위 컨테이너다. 이름은 전역에서 유일하다. 추측하기 쉬운 이름 + 민감 파일은 스캔 대상이다.

객체 키는 logs/2026/08/app.json 같은 문자열이다. 폴더처럼 보이지만 prefix일 뿐이다.

권한 세 겹.

방식 용도
IAM 정책 누가(역할/사용자) 무엇을
버킷 정책 이 버킷 리소스에 대한 정책
ACL 레거시. 신규 버킷은 ACL 끄기가 기본

앱은 IAM 역할로 s3:GetObject / PutObject만 연다. Resource를 arn:aws:s3:::YOUR_BUCKET/*처럼 버킷으로 좁힌다. * 버킷 와일드카드는 피한다.

암호화. SSE-S3(S3 관리 키) 또는 SSE-KMS. KMS는 Key Management Service다. 민감하면 KMS + 키 정책으로 누가 쓰는지 남긴다.

버전 관리. 덮어쓰기·삭제 실수에서 이전 버전을 남긴다. 용량이 늘므로 수명주기와 세트로 켠다.

수명주기(Lifecycle). 오래된 로그를 삭제하거나 Glacier로 내린다. Glacier는 저렴한 아카이브 계층이다. 복원에 시간이 걸린다.


3. 최소 예제 — 비공개 업로드

앱이 사용자 업로드를 받는다고 가정한다. 브라우저에 액세스 키를 심지 않는다. 서버(또는 서명 URL)가 넣는다.

버킷 정책 예. 퍼블릭 허용이 아니다. CloudFront OAC 전제는 별도 문서의 ARN으로 좁힌다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowAppRolePut",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::YOUR_ACCOUNT_ID:role/app-api-role"
      },
      "Action": ["s3:PutObject", "s3:GetObject"],
      "Resource": "arn:aws:s3:::app-uploads-prod/*"
    }
  ]
}

수명주기 규칙 예:

{
  "Rules": [{
    "ID": "expire-old-logs",
    "Status": "Enabled",
    "Filter": { "Prefix": "logs/" },
    "Expiration": { "Days": 90 }
  }]
}

CLI 확인. 자격은 역할 또는 로컬 프로필. 키 값은 적지 않는다.

aws s3api get-public-access-block --bucket app-uploads-prod
aws s3 ls s3://app-uploads-prod/logs/ --profile work

BlockPublicAcls·RestrictPublicBuckets가 true인지 본다. false면 이유가 문서에 있어야 한다.

서명 URL은 만료를 짧게 둔다. 만료 없는 퍼블릭 객체로 우회하지 않는다. 서버가 SDK로 서명을 만들고, 브라우저는 그 URL로만 PUT/GET 한다. 만료는 분 단위가 안전하다.

업로드 용량 상한과 Content-Type을 앱에서 검사한다. S3는 시킨 대로 저장할 뿐이다. 실행 가능한 파일을 공개 prefix에 두면 다른 사고의 시작이다.


4. 운영 시 주의

보안. 개발 편의로 퍼블릭 읽기를 켜지 않는다. 액세스 키를 프론트·모바일 앱에 넣지 않는다. 오픈된 버킷은 검색 엔진과 봇이 먼저 찾는다.

비용. 저장 단가는 낮고 요청 수·트래픽·잘못된 LIST가 비용을 만든다. 로그를 무기한 두면 용량이 선형으로 는다. 수명주기를 첫날 켠다. Intelligent-Tiering은 접근 패턴이 제각각일 때 검토한다.

백업. 버전 관리 + 다른 리전 복제는 DR용이다. “버킷 하나 = 원본”이면 계정 사고에 같이 죽는다. 중요 백업은 별도 계정·리전을 검토한다.

실수 방지. MFA Delete, 오브젝트 잠금은 규제 데이터에 검토한다. aws s3 rm recursive는 프로덕션에서 보호한다.

명명. 환경별로 버킷을 나눈다. app-uploads-dev와 app-uploads-prod를 같은 정책으로 묶지 않는다.

접근 로그. 서버 액세스 로그 또는 CloudTrail 데이터 이벤트로 “누가 객체를 읽었는지”를 남긴다. 전 버킷 데이터 이벤트는 비용이 난다. 민감 버킷만 켠다.

CORS. 브라우저에서 다른 도메인이 버킷에 붙으면 CORS가 필요하다. * 오리진은 개발용이다. 프로덕션은 사이트 도메인만. CORS를 연 것과 퍼블릭 객체를 연 것은 다르다. CORS만으로 익명 읽기가 되지는 않는다.


5. 정리

S3는 편하다. 그래서 퍼블릭 차단 + 최소 IAM + 수명주기를 기본값으로 둔다. 웹에 파일을 보여 줄 때는 버킷을 열지 말고 CDN 뒤에서 연다.

체크리스트

  • Block Public Access를 켠 채로 둔다. 기본 공개는 유출이다.
  • 앱은 IAM 역할로 특정 버킷·액션만 허용한다. 키를 프론트에 심지 않는다.
  • 버전 관리 또는 수명주기 중 운영 목적을 정한다. 무한 보관은 비용이다.
  • 암호화(SSE-S3 또는 KMS)를 기본으로 둔다.
  • get-public-access-block으로 공개 여부를 주기적으로 확인한다.

연습

  1. 비공개 버킷을 만들고 역할로만 PutObject가 되는지 확인한다. 브라우저 익명 GET이 거절되어야 한다.
  2. logs/ prefix 90일 삭제 규칙을 적용하고 콘솔에서 규칙이 보이는지 본다.
  3. Block Public Access 네 항목이 모두 켜져 있는지 CLI로 출력한다.

정적 사이트라도 버킷 정책을 Principal: "*" s3:GetObject로 여는 구성을 기본으로 두지 않는다. 옛날 튜토리얼이 많다. CloudFront OAC가 표준에 가깝다. 꼭 버킷 웹 호스팅을 쓰면 개인정보·백업 prefix는 그 버킷에 넣지 않는다. 사이트용과 업로드용을 나눈다.

멀티파트 업로드가 실패하면 불완전 파트가 요금을 남긴다. 수명주기에서 미완료 업로드를 며칠 뒤 지운다. 큰 영상·덤프를 쓰는 버킷이면 특히 그렇다.

객체 키에 사용자 입력을 그대로 넣지 않는다. ../와 이상한 문자는 앱에서 걸러 키를 uploads/{userId}/{uuid}처럼 만든다.


댓글

0

아직 댓글이 없습니다. 첫 댓글을 남겨보세요.

이전 글EC2 인스턴스 기초와 운영 포인트다음 글RDS로 관리형 데이터베이스 운영하기
← 목록으로