LabHub
배우기 러닝패스 코스

オブジェクトストレージとS3

ユーザとポリシーでアクセスを制御する

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

목표

서비스 사용자를 만들고 최소 권한 정책을 직접 작성해 부착하면서, 권한 범위를 접두어 단위로 좁히는 습관을 만든다.

왜 중요한가

스토리지 유출 사고의 대부분은 복잡한 공격이 아니라 넓게 열어 둔 권한에서 옵니다. "이미지만 있으니까"라며 버킷을 익명 읽기로 열었는데, 몇 달 뒤 그 버킷 아래에 백업이나 사용자 업로드가 섞여 들어가는 식입니다. 정책의 Resource 를 버킷 전체(arn:aws:s3:::bucket/*)로 잡는 것도 같은 문제입니다 — 서비스 하나의 자격 증명이 새면 버킷 전체가 노출됩니다. 접두어까지 좁혀 두면 피해가 그 접두어 안에 갇힙니다. 그리고 이것은 구현 버그에 대한 방어이기도 합니다. MinIO 의 CVE-2025-62506 은 세션 정책 우회로 권한이 상승하는 취약점이었습니다. 정책을 좁게 쓰는 습관은 그런 순간에 남는 마지막 방어선입니다.

단계

  1. mc admin user add local appuser appuser-secret-123 으로 사용자를 만들고 별칭 app 을 그 자격 증명으로 설정한다.
  2. mc ls app/lab-media 를 시도하고 결과를 /root/pol/denied.txt 에 저장한다. 파일에 denied 또는 Access Denied 문자열이 있어야 한다.
  3. /root/pol/readonly.json 에 정책을 쓴다. s3:GetObjects3:ListBucket 을 허용하고 Resourcearn:aws:s3:::lab-mediaarn:aws:s3:::lab-media/* 두 개다.
  4. mc admin policy create local labreadonly /root/pol/readonly.jsonmc admin policy attach local labreadonly --user appuser 를 실행한다. mc ls app/lab-media 가 성공해야 한다.
  5. mc cp /opt/fixtures/s3/readme.txt app/lab-media/doc/nope.txt 가 실패해야 한다. /root/pol/write.txtwrite_denied=true 를 적는다.
  6. /root/pol/imgonly.jsonResourcearn:aws:s3:::lab-media/img/* 로 좁힌 정책을 쓰고 labimgonly 로 만들어 부착한다. app/lab-media/img/logo.png 조회는 되고 app/lab-media/doc/sales.csv 조회는 실패해야 한다. /root/pol/prefix.txtimg=ok doc=denied 를 적는다.
  7. local/lab-media/public/ 접두어만 익명 다운로드로 연다. 익명 GET 이 public/ 아래 객체에는 200, private/ 아래 객체에는 403 이어야 한다. /root/pol/anon.txtpublic=200 private=403 을 적는다.

참고

서비스 사용자 만들기

mc admin user add local appuser appuser-secret-123 으로 사용자를 만들고 별칭 app 을 그 자격 증명으로 설정한다.

관리자 별칭으로 사용자를 추가합니다. 액세스 키와 시크릿 키를 정해 주세요.

정책 없는 사용자가 거부되는지 확인하기

mc ls app/lab-media 를 시도하고 결과를 /root/pol/denied.txt 에 저장한다. 파일에 denied 또는 Access Denied 문자열이 있어야 한다.

새 별칭으로 목록을 시도하면 거부됩니다. 기본은 아무 권한도 없는 것입니다.

읽기 전용 정책 작성하기

/root/pol/readonly.json 에 정책을 쓴다. s3:GetObjects3:ListBucket 을 허용하고 Resourcearn:aws:s3:::lab-mediaarn:aws:s3:::lab-media/* 두 개다.

JSON 으로 Effect, Action, Resource 를 적습니다. 목록 조회와 객체 읽기는 서로 다른 Action 입니다.

정책 부착하고 읽기 성공시키기

mc admin policy create local labreadonly /root/pol/readonly.jsonmc admin policy attach local labreadonly --user appuser 를 실행한다. mc ls app/lab-media 가 성공해야 한다.

정책을 만들고 사용자에게 붙이는 것은 별도 단계입니다.

쓰기는 여전히 거부되는지 확인하기

mc cp /opt/fixtures/s3/readme.txt app/lab-media/doc/nope.txt 가 실패해야 한다. /root/pol/write.txtwrite_denied=true 를 적는다.

읽기 전용 정책이라면 업로드가 실패해야 합니다. 실패하는 것이 정상입니다.

접두어 한정 정책 만들기

/root/pol/imgonly.jsonResourcearn:aws:s3:::lab-media/img/* 로 좁힌 정책을 쓰고 labimgonly 로 만들어 부착한다. app/lab-media/img/logo.png 조회는 되고 app/lab-media/doc/sales.csv 조회는 실패해야 한다. /root/pol/prefix.txtimg=ok doc=denied 를 적는다.

Resource 에 와일드카드를 접두어까지 붙입니다. img/ 는 되고 doc/ 는 안 되게 하세요.

특정 접두어만 익명 공개하기

local/lab-media/public/ 접두어만 익명 다운로드로 연다. 익명 GET 이 public/ 아래 객체에는 200, private/ 아래 객체에는 403 이어야 한다. /root/pol/anon.txtpublic=200 private=403 을 적는다.

버킷 전체를 여는 것과 접두어 하나만 여는 것은 사고 규모가 다릅니다.

명령 끝의 슬래시 한 글자를 조심하세요. 이 실습의 요지가 거기에 다 들어 있습니다.

mc anonymous set download local/lab-media/public   → Resource: lab-media/public*
mc anonymous set download local/lab-media/public/  → Resource: lab-media/public/*

S3 에 폴더는 없습니다. 정책이 보는 것은 문자열 접두어뿐이라, 슬래시를 빠뜨리면 public-backup.tar 처럼 public 으로 시작하기만 하는 루트 객체까지 함께 열립니다. mc anonymous get-json 으로 서버에 실제로 걸린 Resource 를 확인하세요.

규칙은 걸 때마다 덧붙습니다. 같은 버킷에 두 번 걸면 public*public/* 이 함께 남으니, 범위를 바꿀 때는 mc anonymous set none 으로 먼저 지우고 다시 거세요.