์ฝ˜ํ…์ธ  ๋Œ€ํ‘œ ์ด๋ฏธ์ง€ - ๐Ÿ” S3 ์ ‘๊ทผ์ œ์–ด ์ •์ฑ… ์™„๋ฒฝ ๊ฐ€์ด๋“œ

๐Ÿ” S3 ์ ‘๊ทผ์ œ์–ด ์ •์ฑ… ์™„๋ฒฝ ๊ฐ€์ด๋“œ

AWS S3 ๋ณด์•ˆ์˜ ๋ชจ๋“  ๊ฒƒ, ์นœ๊ตฌ์ฒ˜๋Ÿผ ์‰ฝ๊ฒŒ ์•Œ๋ ค๋“œ๋ฆด๊ฒŒ์š”!
S3 BUCKET ํ—ˆ์šฉ๋œ ์ ‘๊ทผ ์ฐจ๋‹จ๋œ ์ ‘๊ทผ ๐Ÿ‘ค ๐Ÿ”‘ S3 ์ ‘๊ทผ์ œ์–ด ์‹œ์Šคํ…œ

๐ŸŽฏ S3 ์ ‘๊ทผ์ œ์–ด, ์™œ ์ค‘์š”ํ• ๊นŒ?

์•ˆ๋…•! ์˜ค๋Š˜์€ AWS S3์˜ ์ ‘๊ทผ์ œ์–ด ์ •์ฑ…์— ๋Œ€ํ•ด ์ด์•ผ๊ธฐํ•ด๋ณผ ๊ฑฐ์•ผ. ํด๋ผ์šฐ๋“œ ์‹œ๋Œ€์— ๋ฐ์ดํ„ฐ ๋ณด์•ˆ์€ ์„ ํƒ์ด ์•„๋‹ˆ๋ผ ํ•„์ˆ˜์ž–์•„? ๐Ÿ›ก๏ธ

S3(Simple Storage Service)๋Š” AWS์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฐ์ฒด ์Šคํ† ๋ฆฌ์ง€ ์„œ๋น„์Šค์ธ๋ฐ, ์ „ ์„ธ๊ณ„ ์ˆ˜๋งŽ์€ ๊ธฐ์—…๋“ค์ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์–ด. ๊ทธ๋Ÿฐ๋ฐ ๋ง์ด์•ผ, S3 ๋ฒ„ํ‚ท ํ•˜๋‚˜ ์ž˜๋ชป ์„ค์ •ํ–ˆ๋‹ค๊ฐ€ ํšŒ์‚ฌ ์ „์ฒด ๊ณ ๊ฐ ๋ฐ์ดํ„ฐ๊ฐ€ ์ธํ„ฐ๋„ท์— ๋…ธ์ถœ๋˜๋Š” ์‚ฌ๊ณ ๊ฐ€ ์‹ค์ œ๋กœ ์ผ์–ด๋‚˜๊ณค ํ•ด. ๐Ÿ˜ฑ

2019๋…„ ์บํ”ผํƒˆ ์›(Capital One) ํ•ดํ‚น ์‚ฌ๊ฑด ๊ธฐ์–ต๋‚˜? 1์–ต ๋ช… ์ด์ƒ์˜ ๊ณ ๊ฐ ์ •๋ณด๊ฐ€ ์œ ์ถœ๋๋Š”๋ฐ, ์›์ธ ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฐ”๋กœ ์ž˜๋ชป๋œ S3 ์ ‘๊ทผ์ œ์–ด ์„ค์ •์ด์—ˆ์–ด. ์ด๋Ÿฐ ์‚ฌ๊ณ ๋ฅผ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด S3 ์ ‘๊ทผ์ œ์–ด ์ •์ฑ…์„ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๊ณ  ๊ตฌ์„ฑํ•˜๋Š” ๊ฒŒ ์ •๋ง ์ค‘์š”ํ•ด.

๐Ÿ’ก ์žฌ๋Šฅ๋„ท TIP ํด๋ผ์šฐ๋“œ ๋ณด์•ˆ ์„ค์ •์ด ์–ด๋ ต๊ฒŒ ๋А๊ปด์ง„๋‹ค๋ฉด, ์žฌ๋Šฅ๋„ท์—์„œ AWS ์ „๋ฌธ๊ฐ€๋“ค์˜ ์ปจ์„คํŒ…์„ ๋ฐ›์•„๋ณด๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด์•ผ. ์‹ค๋ฌด ๊ฒฝํ—˜์ด ํ’๋ถ€ํ•œ ์ „๋ฌธ๊ฐ€๋“ค์ด ๋‹น์‹ ์˜ ํ”„๋กœ์ ํŠธ์— ๋งž๋Š” ๋ณด์•ˆ ์„ค์ •์„ ๋„์™€์ค„ ์ˆ˜ ์žˆ๊ฑฐ๋“ !

๐Ÿ” S3 ์ ‘๊ทผ์ œ์–ด์˜ ํ•ต์‹ฌ ๊ฐœ๋…

S3 ์ ‘๊ทผ์ œ์–ด๋ฅผ ์ดํ•ดํ•˜๋ ค๋ฉด ๋จผ์ € ๊ธฐ๋ณธ ๊ฐœ๋…๋ถ€ํ„ฐ ํ™•์‹คํžˆ ์žก๊ณ  ๊ฐ€์•ผ ํ•ด. ๋งˆ์น˜ ์ง‘์„ ์ง€์„ ๋•Œ ๊ธฐ์ดˆ๊ณต์‚ฌ๊ฐ€ ์ค‘์š”ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ง์ด์•ผ! ๐Ÿ—๏ธ

๐Ÿ“ฆ S3์˜ ๊ธฐ๋ณธ ๊ตฌ์กฐ

S3๋Š” ๋ฒ„ํ‚ท(Bucket)๊ณผ ๊ฐ์ฒด(Object)๋ผ๋Š” ๋‘ ๊ฐ€์ง€ ํ•ต์‹ฌ ์š”์†Œ๋กœ ๊ตฌ์„ฑ๋ผ ์žˆ์–ด.

๋ฒ„ํ‚ท์€ ์‰ฝ๊ฒŒ ๋งํ•ด์„œ ์ตœ์ƒ์œ„ ํด๋” ๊ฐ™์€ ๊ฑฐ์•ผ. ์ „ ์„ธ๊ณ„์—์„œ ์œ ์ผํ•œ ์ด๋ฆ„์„ ๊ฐ€์ ธ์•ผ ํ•˜๊ณ , ํ•œ ๋ฒˆ ์ƒ์„ฑํ•˜๋ฉด ์ด๋ฆ„์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†์–ด. ์˜ˆ๋ฅผ ๋“ค์–ด my-company-data-2024 ๊ฐ™์€ ์‹์œผ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์ง€.

๊ฐ์ฒด๋Š” ๋ฒ„ํ‚ท ์•ˆ์— ์ €์žฅ๋˜๋Š” ์‹ค์ œ ํŒŒ์ผ๋“ค์ด์•ผ. ์ด๋ฏธ์ง€, ๋™์˜์ƒ, ๋ฌธ์„œ, ๋กœ๊ทธ ํŒŒ์ผ ๋“ฑ ๋ญ๋“ ์ง€ ์ €์žฅํ•  ์ˆ˜ ์žˆ์–ด. ๊ฐ ๊ฐ์ฒด๋Š” ํ‚ค(Key)๋ผ๋Š” ๊ณ ์œ  ์‹๋ณ„์ž๋ฅผ ๊ฐ€์ง€๋Š”๋ฐ, ์ด๊ฒŒ ์‚ฌ์‹ค์ƒ ํŒŒ์ผ ๊ฒฝ๋กœ๋ผ๊ณ  ๋ณด๋ฉด ๋ผ.

๐ŸŽญ ์ ‘๊ทผ์ œ์–ด์˜ 4๊ฐ€์ง€ ๋ ˆ์ด์–ด

S3 ์ ‘๊ทผ์ œ์–ด๋Š” ์—ฌ๋Ÿฌ ๋ ˆ์ด์–ด๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ์–ด. ๋งˆ์น˜ ์–‘ํŒŒ๊ป์งˆ์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ ๊ฒน์˜ ๋ณด์•ˆ ์žฅ์น˜๊ฐ€ ์žˆ๋Š” ๊ฑฐ์ง€! ๊ฐ ๋ ˆ์ด์–ด๋ฅผ ํ•˜๋‚˜์”ฉ ์‚ดํŽด๋ณผ๊ฒŒ.

1๏ธโƒฃ IAM ์ •์ฑ… (Identity-Based Policies)

IAM ์ •์ฑ…์€ ๋ˆ„๊ฐ€(Who) ๋ฌด์—‡์„ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ์ •์˜ํ•ด. AWS ๊ณ„์ •์˜ ์‚ฌ์šฉ์ž, ๊ทธ๋ฃน, ์—ญํ• ์— ๋ถ€์—ฌ๋˜๋Š” ๊ถŒํ•œ์ด์•ผ.

์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊ฒŒ. ๊ฐœ๋ฐœํŒ€ ์ง์›์—๊ฒŒ๋Š” ๊ฐœ๋ฐœ์šฉ ๋ฒ„ํ‚ท์— ์ฝ๊ธฐ/์“ฐ๊ธฐ ๊ถŒํ•œ์„ ์ฃผ๊ณ , ๋งˆ์ผ€ํŒ…ํŒ€์—๊ฒŒ๋Š” ๋งˆ์ผ€ํŒ… ์ž๋ฃŒ ๋ฒ„ํ‚ท์—๋งŒ ์ฝ๊ธฐ ๊ถŒํ•œ์„ ์ฃผ๋Š” ์‹์ด์ง€. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐ ํŒ€์ด ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค์—๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์„œ ๋ณด์•ˆ์ด ๊ฐ•ํ™”๋ผ.

๐ŸŽ“ ์‹ค๋ฌด ํŒ IAM ์ •์ฑ…์„ ์„ค๊ณ„ํ•  ๋•Œ๋Š” ์ตœ์†Œ ๊ถŒํ•œ ์›์น™(Principle of Least Privilege)์„ ๋”ฐ๋ผ์•ผ ํ•ด. ์ฆ‰, ์—…๋ฌด ์ˆ˜ํ–‰์— ๊ผญ ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ๊ถŒํ•œ๋งŒ ๋ถ€์—ฌํ•˜๋Š” ๊ฑฐ์•ผ. ์ฒ˜์Œ์—๋Š” ๋ถˆํŽธํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์žฅ๊ธฐ์ ์œผ๋กœ ๋ณด์•ˆ ์‚ฌ๊ณ ๋ฅผ ์˜ˆ๋ฐฉํ•˜๋Š” ๊ฐ€์žฅ ํ™•์‹คํ•œ ๋ฐฉ๋ฒ•์ด์•ผ!

2๏ธโƒฃ ๋ฒ„ํ‚ท ์ •์ฑ… (Bucket Policies)

๋ฒ„ํ‚ท ์ •์ฑ…์€ ๋ฌด์—‡์„(What) ๋ˆ„๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๋ฆฌ์†Œ์Šค ๊ด€์ ์—์„œ ์ •์˜ํ•ด. IAM ์ •์ฑ…์ด ์‚ฌ์šฉ์ž ์ค‘์‹ฌ์ด๋ผ๋ฉด, ๋ฒ„ํ‚ท ์ •์ฑ…์€ ๋ฆฌ์†Œ์Šค ์ค‘์‹ฌ์ด์•ผ.

๋ฒ„ํ‚ท ์ •์ฑ…์€ JSON ํ˜•์‹์œผ๋กœ ์ž‘์„ฑ๋˜๋Š”๋ฐ, ์ฒ˜์Œ ๋ณด๋ฉด ์ข€ ๋ณต์žกํ•ด ๋ณด์ผ ์ˆ˜ ์žˆ์–ด. ํ•˜์ง€๋งŒ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•˜๋ฉด ์ƒ๊ฐ๋ณด๋‹ค ๊ฐ„๋‹จํ•ด! ๊ธฐ๋ณธ ๊ตฌ์กฐ๋Š” ์ด๋ ‡๊ฒŒ ์ƒ๊ฒผ์–ด:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/*"
    }
  ]
}

์ด ์ •์ฑ…์€ ๋ชจ๋“  ์‚ฌ๋žŒ(Principal: "*")์ด my-bucket์˜ ๋ชจ๋“  ๊ฐ์ฒด๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก(Action: "s3:GetObject") ํ—ˆ์šฉ(Effect: "Allow")ํ•œ๋‹ค๋Š” ๋œป์ด์•ผ. ๋ฌผ๋ก  ์‹ค์ œ ์šด์˜ ํ™˜๊ฒฝ์—์„œ๋Š” ์ด๋ ‡๊ฒŒ ์—ด์–ด๋‘๋ฉด ์•ˆ ๋˜๊ฒ ์ง€? ๐Ÿ˜…

3๏ธโƒฃ ACL (Access Control Lists)

ACL์€ S3์˜ ๋ ˆ๊ฑฐ์‹œ ์ ‘๊ทผ์ œ์–ด ๋ฐฉ์‹์ด์•ผ. ์š”์ฆ˜์€ ์ž˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํŽธ์ธ๋ฐ, ๊ทธ ์ด์œ ๋Š” IAM ์ •์ฑ…๊ณผ ๋ฒ„ํ‚ท ์ •์ฑ…์ด ํ›จ์”ฌ ๋” ์„ธ๋ฐ€ํ•˜๊ณ  ๊ฐ•๋ ฅํ•œ ์ œ์–ด๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์•ผ.

ACL์€ ๋ฒ„ํ‚ท ๋ ˆ๋ฒจ๊ณผ ๊ฐ์ฒด ๋ ˆ๋ฒจ์—์„œ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด. ์ฃผ๋กœ ๋‹ค๋ฅธ AWS ๊ณ„์ •์— ๊ฐ„๋‹จํ•œ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•  ๋•Œ ์‚ฌ์šฉํ–ˆ์—ˆ์ง€. ํ•˜์ง€๋งŒ AWS๋„ ๊ณต์‹์ ์œผ๋กœ ACL ๋Œ€์‹  ๋ฒ„ํ‚ท ์ •์ฑ… ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ์–ด.

โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ 2023๋…„ 4์›”๋ถ€ํ„ฐ ์ƒˆ๋กœ ์ƒ์„ฑ๋˜๋Š” S3 ๋ฒ„ํ‚ท์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ACL์ด ๋น„ํ™œ์„ฑํ™”๋ผ. AWS๊ฐ€ ๋ณด์•ˆ ๊ฐ•ํ™”๋ฅผ ์œ„ํ•ด ์ •์ฑ…์„ ๋ณ€๊ฒฝํ•œ ๊ฑฐ์•ผ. ๊ธฐ์กด ์‹œ์Šคํ…œ์„ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•  ๋•Œ๋Š” ์ด ์ ์„ ๊ผญ ํ™•์ธํ•ด์•ผ ํ•ด!

4๏ธโƒฃ ๋ธ”๋ก ํผ๋ธ”๋ฆญ ์•ก์„ธ์Šค (Block Public Access)

์ด๊ฑด 2018๋…„์— ๋„์ž…๋œ ๋น„๊ต์  ์ตœ์‹  ๊ธฐ๋Šฅ์ด์•ผ. S3 ๋ฒ„ํ‚ท์ด ์‹ค์ˆ˜๋กœ ๊ณต๊ฐœ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ์•ˆ์ „์žฅ์น˜๋ผ๊ณ  ๋ณด๋ฉด ๋ผ. ๐Ÿšจ

4๊ฐ€์ง€ ์„ค์ • ์˜ต์…˜์ด ์žˆ์–ด:
- BlockPublicAcls: ์ƒˆ๋กœ์šด ํผ๋ธ”๋ฆญ ACL ์ฐจ๋‹จ
- IgnorePublicAcls: ๊ธฐ์กด ํผ๋ธ”๋ฆญ ACL ๋ฌด์‹œ
- BlockPublicPolicy: ์ƒˆ๋กœ์šด ํผ๋ธ”๋ฆญ ๋ฒ„ํ‚ท ์ •์ฑ… ์ฐจ๋‹จ
- RestrictPublicBuckets: ํผ๋ธ”๋ฆญ ๋ฒ„ํ‚ท ์ •์ฑ…์ด ์žˆ๋Š” ๋ฒ„ํ‚ท์˜ ์ ‘๊ทผ ์ œํ•œ

๊ธฐ๋ณธ์ ์œผ๋กœ ์ด 4๊ฐ€์ง€๊ฐ€ ๋ชจ๋‘ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์–ด. ์›น์‚ฌ์ดํŠธ ํ˜ธ์ŠคํŒ…์ฒ˜๋Ÿผ ์ •๋ง ํผ๋ธ”๋ฆญ ์ ‘๊ทผ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด, ์ด ์„ค์ •์„ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒŒ ์ข‹์•„!


๐Ÿ› ๏ธ IAM ์ •์ฑ… ์ƒ์„ธ ๊ฐ€์ด๋“œ

์ž, ์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ๊ฐ ์ ‘๊ทผ์ œ์–ด ๋ฐฉ์‹์„ ๊นŠ์ด ์žˆ๊ฒŒ ํŒŒํ—ค์ณ๋ณผ ์‹œ๊ฐ„์ด์•ผ! ๋จผ์ € IAM ์ •์ฑ…๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด๋ณด์ž. ๐Ÿ’ช

๐Ÿ“‹ IAM ์ •์ฑ…์˜ ๊ตฌ์กฐ

IAM ์ •์ฑ…๋„ JSON ํ˜•์‹์œผ๋กœ ์ž‘์„ฑ๋ผ. ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•˜๋ฉด ๋ณต์žกํ•œ ์ •์ฑ…๋„ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด. ์ฃผ์š” ์š”์†Œ๋“ค์„ ์‚ดํŽด๋ณผ๊ฒŒ:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowS3ReadAccess",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-bucket",
        "arn:aws:s3:::my-bucket/*"
      ],
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "203.0.113.0/24"
        }
      }
    }
  ]
}

๊ฐ ์š”์†Œ๋ฅผ ํ•˜๋‚˜์”ฉ ๋œฏ์–ด๋ณด์ž:

Version: ์ •์ฑ… ์–ธ์–ด ๋ฒ„์ „์ด์•ผ. ๊ฑฐ์˜ ํ•ญ์ƒ "2012-10-17"์„ ์‚ฌ์šฉํ•ด. ์ด๊ฒŒ ์ตœ์‹  ๋ฒ„์ „์ด๊ฑฐ๋“ .

Statement: ์‹ค์ œ ๊ถŒํ•œ ๊ทœ์น™๋“ค์ด ๋“ค์–ด๊ฐ€๋Š” ๋ฐฐ์—ด์ด์•ผ. ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ทœ์น™์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ์–ด.

Sid: Statement ID์˜ ์•ฝ์ž๋กœ, ๊ฐ ๊ทœ์น™์— ๋ถ™์ด๋Š” ์„ค๋ช… ๋ผ๋ฒจ์ด์•ผ. ์„ ํƒ์‚ฌํ•ญ์ด์ง€๋งŒ ๊ด€๋ฆฌํ•˜๊ธฐ ํŽธํ•˜๊ฒŒ ๋ถ™์—ฌ์ฃผ๋Š” ๊ฒŒ ์ข‹์•„.

Effect: "Allow" ๋˜๋Š” "Deny" ๋‘˜ ์ค‘ ํ•˜๋‚˜์•ผ. ํ•ด๋‹น ์•ก์…˜์„ ํ—ˆ์šฉํ• ์ง€ ๊ฑฐ๋ถ€ํ• ์ง€ ๊ฒฐ์ •ํ•ด.

Action: ํ—ˆ์šฉํ•˜๊ฑฐ๋‚˜ ๊ฑฐ๋ถ€ํ•  AWS ์ž‘์—…๋“ค์ด์•ผ. S3์˜ ๊ฒฝ์šฐ s3:GetObject, s3:PutObject ๊ฐ™์€ ์‹์œผ๋กœ ์ž‘์„ฑํ•ด.

Resource: ์ •์ฑ…์ด ์ ์šฉ๋  AWS ๋ฆฌ์†Œ์Šค๋ฅผ ARN(Amazon Resource Name) ํ˜•์‹์œผ๋กœ ์ง€์ •ํ•ด.

Condition: ์„ ํƒ์ ์œผ๋กœ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ์กฐ๊ฑด๋ฌธ์ด์•ผ. IP ์ฃผ์†Œ, ์‹œ๊ฐ„, MFA ์ธ์ฆ ์—ฌ๋ถ€ ๋“ฑ ๋‹ค์–‘ํ•œ ์กฐ๊ฑด์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด.

๐ŸŽฏ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” S3 ์•ก์…˜๋“ค

S3์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์•ก์…˜์€ ์ •๋ง ๋งŽ์•„. ํ•˜์ง€๋งŒ ์‹ค๋ฌด์—์„œ ์ž์ฃผ ์“ฐ์ด๋Š” ๊ฒƒ๋“ค๋งŒ ์ถ”๋ ค๋ณด๋ฉด ์ด ์ •๋„์•ผ:

์•ก์…˜ ์„ค๋ช… ์‚ฌ์šฉ ์˜ˆ์‹œ
s3:ListBucket ๋ฒ„ํ‚ท ๋‚ด ๊ฐ์ฒด ๋ชฉ๋ก ์กฐํšŒ ํŒŒ์ผ ํƒ์ƒ‰๊ธฐ์ฒ˜๋Ÿผ ๋ฒ„ํ‚ท ๋‚ด์šฉ ๋ณด๊ธฐ
s3:GetObject ๊ฐ์ฒด ๋‹ค์šด๋กœ๋“œ/์ฝ๊ธฐ ํŒŒ์ผ ๋‚ด์šฉ ์ฝ๊ธฐ, ๋‹ค์šด๋กœ๋“œ
s3:PutObject ๊ฐ์ฒด ์—…๋กœ๋“œ/์ƒ์„ฑ ์ƒˆ ํŒŒ์ผ ์—…๋กœ๋“œ, ๊ธฐ์กด ํŒŒ์ผ ๋ฎ์–ด์“ฐ๊ธฐ
s3:DeleteObject ๊ฐ์ฒด ์‚ญ์ œ ํŒŒ์ผ ์‚ญ์ œ
s3:GetBucketLocation ๋ฒ„ํ‚ท ๋ฆฌ์ „ ์ •๋ณด ์กฐํšŒ ๋ฒ„ํ‚ท์ด ์–ด๋А ์ง€์—ญ์— ์žˆ๋Š”์ง€ ํ™•์ธ
s3:ListAllMyBuckets ๊ณ„์ •์˜ ๋ชจ๋“  ๋ฒ„ํ‚ท ๋ชฉ๋ก ์กฐํšŒ ์†Œ์œ ํ•œ ๋ฒ„ํ‚ท ์ „์ฒด ๋ฆฌ์ŠคํŠธ ๋ณด๊ธฐ

์™€์ผ๋“œ์นด๋“œ(*)๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ์•ก์…˜์„ ํ•œ ๋ฒˆ์— ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ์–ด. ์˜ˆ๋ฅผ ๋“ค์–ด s3:Get*๋Š” GetObject, GetObjectVersion, GetBucketLocation ๋“ฑ Get์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” ๋ชจ๋“  ์•ก์…˜์„ ํฌํ•จํ•ด.

๐Ÿ” ์‹ค์ „ IAM ์ •์ฑ… ์˜ˆ์ œ

์˜ˆ์ œ 1: ์ฝ๊ธฐ ์ „์šฉ ์ ‘๊ทผ ๊ถŒํ•œ

๋ฐ์ดํ„ฐ ๋ถ„์„ํŒ€์—๊ฒŒ ํŠน์ • ๋ฒ„ํ‚ท์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ์ˆ˜๋งŒ ์žˆ๊ณ  ์ˆ˜์ •์€ ๋ชปํ•˜๊ฒŒ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด?

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadOnlyAccess",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::analytics-data-bucket",
        "arn:aws:s3:::analytics-data-bucket/*"
      ]
    }
  ]
}

์ด ์ •์ฑ…์€ analytics-data-bucket์˜ ๊ฐ์ฒด๋ฅผ ์ฝ๊ณ  ๋ชฉ๋ก์„ ๋ณผ ์ˆ˜ ์žˆ์ง€๋งŒ, ์—…๋กœ๋“œ๋‚˜ ์‚ญ์ œ๋Š” ํ•  ์ˆ˜ ์—†์–ด. ๊น”๋”ํ•˜์ง€? ๐Ÿ˜Š

์˜ˆ์ œ 2: ํŠน์ • ํด๋”์—๋งŒ ์ ‘๊ทผ ํ—ˆ์šฉ

S3์—๋Š” ์‹ค์ œ๋กœ ํด๋” ๊ฐœ๋…์ด ์—†์ง€๋งŒ, ํ‚ค(๊ฒฝ๋กœ)๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํด๋”์ฒ˜๋Ÿผ ๊ตฌ์กฐํ™”ํ•  ์ˆ˜ ์žˆ์–ด. ์‚ฌ์šฉ์ž๋ณ„๋กœ ์ž๊ธฐ ํด๋”์—๋งŒ ์ ‘๊ทผํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowUserToSeeTheBucketInTheConsole",
      "Effect": "Allow",
      "Action": [
        "s3:ListAllMyBuckets",
        "s3:GetBucketLocation"
      ],
      "Resource": "arn:aws:s3:::*"
    },
    {
      "Sid": "AllowListingOfUserFolder",
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::user-data-bucket",
      "Condition": {
        "StringLike": {
          "s3:prefix": [
            "${aws:username}/*",
            "${aws:username}"
          ]
        }
      }
    },
    {
      "Sid": "AllowAllS3ActionsInUserFolder",
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::user-data-bucket/${aws:username}/*"
    }
  ]
}

์ด ์ •์ฑ…์€ ์ข€ ๋ณต์žกํ•ด ๋ณด์ด์ง€๋งŒ, ์›๋ฆฌ๋Š” ๊ฐ„๋‹จํ•ด. ${aws:username} ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ ์‚ฌ์šฉ์ž๊ฐ€ ์ž๊ธฐ ์ด๋ฆ„์˜ ํด๋”์—๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“  ๊ฑฐ์•ผ. ์˜ˆ๋ฅผ ๋“ค์–ด john์ด๋ผ๋Š” ์‚ฌ์šฉ์ž๋Š” user-data-bucket/john/ ๊ฒฝ๋กœ์—๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด.

์˜ˆ์ œ 3: ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ์ œ์–ด

์—…๋ฌด ์‹œ๊ฐ„์—๋งŒ S3 ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด? Condition์„ ํ™œ์šฉํ•˜๋ฉด ๋ผ!

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowAccessDuringBusinessHours",
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::company-data/*"
      ],
      "Condition": {
        "DateGreaterThan": {
          "aws:CurrentTime": "2024-01-01T09:00:00Z"
        },
        "DateLessThan": {
          "aws:CurrentTime": "2024-12-31T18:00:00Z"
        }
      }
    }
  ]
}

๋ฌผ๋ก  ์‹ค์ œ๋กœ๋Š” ๋งค์ผ ๋ฐ˜๋ณต๋˜๋Š” ์‹œ๊ฐ„ ์กฐ๊ฑด์„ ์„ค์ •ํ•˜๋ ค๋ฉด ๋‹ค๋ฅธ ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ด์•ผ ํ•˜์ง€๋งŒ, ์ด๋Ÿฐ ์‹์œผ๋กœ ์‹œ๊ฐ„ ๊ธฐ๋ฐ˜ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฑธ ์•Œ ์ˆ˜ ์žˆ์–ด!

์˜ˆ์ œ 4: IP ์ฃผ์†Œ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ์ œ์–ด

ํšŒ์‚ฌ ์‚ฌ๋ฌด์‹ค IP์—์„œ๋งŒ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowFromOfficeIP",
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::secure-data-bucket",
        "arn:aws:s3:::secure-data-bucket/*"
      ],
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": [
            "203.0.113.0/24",
            "198.51.100.0/24"
          ]
        }
      }
    }
  ]
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ง€์ •๋œ IP ๋Œ€์—ญ์—์„œ๋งŒ ๋ฒ„ํ‚ท์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด. ์žฌํƒ๊ทผ๋ฌด๊ฐ€ ๋งŽ์•„์ง„ ์š”์ฆ˜์—๋Š” VPN๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ํšจ๊ณผ์ ์ด์•ผ! ๐Ÿข

๐Ÿ’ก ํ”„๋กœ ํŒ IP ๊ธฐ๋ฐ˜ ์ œ์–ด๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” aws:SourceIp ๋Œ€์‹  aws:VpcSourceIp๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด VPC ๋‚ด๋ถ€ IP๋„ ์ฒดํฌํ•  ์ˆ˜ ์žˆ์–ด. VPC ์—”๋“œํฌ์ธํŠธ๋ฅผ ํ†ตํ•œ ์ ‘๊ทผ์„ ์ œ์–ดํ•  ๋•Œ ์œ ์šฉํ•ด!

๐Ÿšซ Deny ์ •์ฑ…์˜ ํ™œ์šฉ

AWS IAM์—์„œ๋Š” ๋ช…์‹œ์  Deny๊ฐ€ ๋ชจ๋“  Allow๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’์•„. ์ด๊ฑธ ํ™œ์šฉํ•˜๋ฉด ๊ฐ•๋ ฅํ•œ ๋ณด์•ˆ ์ •์ฑ…์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyDeleteActions",
      "Effect": "Deny",
      "Action": [
        "s3:DeleteObject",
        "s3:DeleteObjectVersion",
        "s3:DeleteBucket"
      ],
      "Resource": [
        "arn:aws:s3:::critical-data-bucket",
        "arn:aws:s3:::critical-data-bucket/*"
      ]
    }
  ]
}

์ด ์ •์ฑ…์„ ์ ์šฉํ•˜๋ฉด, ๋‹ค๋ฅธ ์ •์ฑ…์—์„œ ์‚ญ์ œ ๊ถŒํ•œ์„ ํ—ˆ์šฉํ•˜๋”๋ผ๋„ ์ด ๋ฒ„ํ‚ท์˜ ๋ฐ์ดํ„ฐ๋Š” ์ ˆ๋Œ€ ์‚ญ์ œํ•  ์ˆ˜ ์—†์–ด. ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณดํ˜ธํ•˜๋Š” ์ตœํ›„์˜ ๋ฐฉ์–ด์„ ์ด ๋˜๋Š” ๊ฑฐ์ง€! ๐Ÿ›ก๏ธ

๐Ÿ”„ ์ •์ฑ… ๋ณ€์ˆ˜ ํ™œ์šฉํ•˜๊ธฐ

AWS๋Š” ์ •์ฑ…์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ ๋ณ€์ˆ˜๋ฅผ ์ œ๊ณตํ•ด. ์ด๊ฑธ ํ™œ์šฉํ•˜๋ฉด ๋™์ ์ด๊ณ  ์œ ์—ฐํ•œ ์ •์ฑ…์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด:

๋ณ€์ˆ˜ ์„ค๋ช… ์˜ˆ์‹œ ๊ฐ’
${aws:username} IAM ์‚ฌ์šฉ์ž ์ด๋ฆ„ john.doe
${aws:userid} IAM ์‚ฌ์šฉ์ž ID AIDAI23HXX2LO4example
${aws:PrincipalTag/department} ์‚ฌ์šฉ์ž์˜ ํƒœ๊ทธ ๊ฐ’ engineering
${aws:CurrentTime} ํ˜„์žฌ ์‹œ๊ฐ„ 2024-01-15T10:30:00Z
${aws:SourceIp} ์š”์ฒญ ์ถœ์ฒ˜ IP 203.0.113.42

ํŠนํžˆ ํƒœ๊ทธ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ์ œ์–ด(TBAC)๋Š” ์š”์ฆ˜ ๋งŽ์ด ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด์•ผ. ์‚ฌ์šฉ์ž๋‚˜ ๋ฆฌ์†Œ์Šค์— ํƒœ๊ทธ๋ฅผ ๋ถ™์ด๊ณ , ๊ทธ ํƒœ๊ทธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ๊ฑฐ์ง€.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowAccessBasedOnTags",
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "arn:aws:s3:::project-data-bucket/*",
      "Condition": {
        "StringEquals": {
          "s3:ExistingObjectTag/project": "${aws:PrincipalTag/project}"
        }
      }
    }
  ]
}

์ด ์ •์ฑ…์€ ์‚ฌ์šฉ์ž์˜ project ํƒœ๊ทธ์™€ ๊ฐ์ฒด์˜ project ํƒœ๊ทธ๊ฐ€ ์ผ์น˜ํ•  ๋•Œ๋งŒ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•ด. ํ”„๋กœ์ ํŠธ๋ณ„๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒฉ๋ฆฌํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์™„๋ฒฝํ•œ ๋ฐฉ๋ฒ•์ด์•ผ! ๐ŸŽฏ


๐Ÿ“œ ๋ฒ„ํ‚ท ์ •์ฑ… ๋งˆ์Šคํ„ฐํ•˜๊ธฐ

์ด์ œ ๋ฒ„ํ‚ท ์ •์ฑ…์œผ๋กœ ๋„˜์–ด๊ฐ€๋ณผ๊นŒ? IAM ์ •์ฑ…๊ณผ ๋น„์Šทํ•ด ๋ณด์ด์ง€๋งŒ, ์‚ฌ์šฉ ๋ชฉ์ ๊ณผ ์ ์šฉ ๋ฐฉ์‹์ด ๋‹ฌ๋ผ. ๋ฒ„ํ‚ท ์ •์ฑ…์€ ๋ฆฌ์†Œ์Šค ๊ธฐ๋ฐ˜ ์ •์ฑ…์ด๋ผ์„œ ๋ฒ„ํ‚ท ์ž์ฒด์— ์ง์ ‘ ์—ฐ๊ฒฐ๋ผ.

๐Ÿ†š IAM ์ •์ฑ… vs ๋ฒ„ํ‚ท ์ •์ฑ…

๋‘˜์˜ ์ฐจ์ด๋ฅผ ๋ช…ํ™•ํžˆ ์ดํ•ดํ•˜๋Š” ๊ฒŒ ์ค‘์š”ํ•ด. ํ‘œ๋กœ ์ •๋ฆฌํ•ด๋ณผ๊ฒŒ:

๊ตฌ๋ถ„ IAM ์ •์ฑ… ๋ฒ„ํ‚ท ์ •์ฑ…
์—ฐ๊ฒฐ ๋Œ€์ƒ ์‚ฌ์šฉ์ž, ๊ทธ๋ฃน, ์—ญํ•  S3 ๋ฒ„ํ‚ท
๊ด€์  ์‹ ์›(Identity) ์ค‘์‹ฌ ๋ฆฌ์†Œ์Šค(Resource) ์ค‘์‹ฌ
ํฌ๋กœ์Šค ๊ณ„์ • ์ œํ•œ์  ์‰ฝ๊ฒŒ ๊ฐ€๋Šฅ
ํฌ๊ธฐ ์ œํ•œ 6,144์ž (๊ด€๋ฆฌํ˜• ์ •์ฑ…) 20KB
Principal ์ง€์ • ๋ถˆ๊ฐ€๋Šฅ ํ•„์ˆ˜
์ฃผ ์‚ฌ์šฉ ์ผ€์ด์Šค ๋‚ด๋ถ€ ์‚ฌ์šฉ์ž ๊ถŒํ•œ ๊ด€๋ฆฌ ์™ธ๋ถ€ ์ ‘๊ทผ, ํผ๋ธ”๋ฆญ ์ ‘๊ทผ ์ œ์–ด

๊ฐ„๋‹จํžˆ ๋งํ•˜๋ฉด, IAM ์ •์ฑ…์€ "์ด ์‚ฌ๋žŒ์ด ๋ญ˜ ํ•  ์ˆ˜ ์žˆ๋‚˜?"๋ฅผ ์ •์˜ํ•˜๊ณ , ๋ฒ„ํ‚ท ์ •์ฑ…์€ "์ด ๋ฒ„ํ‚ท์— ๋ˆ„๊ฐ€ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‚˜?"๋ฅผ ์ •์˜ํ•˜๋Š” ๊ฑฐ์•ผ. ๐Ÿค”

๐ŸŒ ํผ๋ธ”๋ฆญ ์›น์‚ฌ์ดํŠธ ํ˜ธ์ŠคํŒ…

S3๋กœ ์ •์  ์›น์‚ฌ์ดํŠธ๋ฅผ ํ˜ธ์ŠคํŒ…ํ•˜๋Š” ๊ฑด ์ •๋ง ํ”ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€์•ผ. ์ด๋•Œ ํ•„์š”ํ•œ ๋ฒ„ํ‚ท ์ •์ฑ…์€:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-website-bucket/*"
    }
  ]
}

Principal: "*"๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ์„ ์˜๋ฏธํ•ด. ์ฆ‰, ์ธํ„ฐ๋„ท์˜ ๋ˆ„๊ตฌ๋‚˜ ์ด ๋ฒ„ํ‚ท์˜ ๊ฐ์ฒด๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ด์ง€. ๋ฌผ๋ก  ์ด๋ ‡๊ฒŒ ์„ค์ •ํ•˜๋ ค๋ฉด ๋ธ”๋ก ํผ๋ธ”๋ฆญ ์•ก์„ธ์Šค ์„ค์ •์„ ํ•ด์ œํ•ด์•ผ ํ•ด.

ํ•˜์ง€๋งŒ ์š”์ฆ˜์€ S3 ์›น์‚ฌ์ดํŠธ ํ˜ธ์ŠคํŒ…๋ณด๋‹ค CloudFront๋ฅผ ์•ž์— ๋‘๊ณ  S3๋Š” ํ”„๋ผ์ด๋น—์œผ๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒŒ ๋” ์ผ๋ฐ˜์ ์ด์•ผ. ์„ฑ๋Šฅ๋„ ์ข‹๊ณ  ๋ณด์•ˆ๋„ ๊ฐ•ํ™”๋˜๊ฑฐ๋“ ! ๐Ÿš€

๐Ÿ”— ํฌ๋กœ์Šค ๊ณ„์ • ์ ‘๊ทผ ์„ค์ •

๋‹ค๋ฅธ AWS ๊ณ„์ •์— ๋ฒ„ํ‚ท ์ ‘๊ทผ ๊ถŒํ•œ์„ ์ฃผ๊ณ  ์‹ถ์„ ๋•Œ ๋ฒ„ํ‚ท ์ •์ฑ…์ด ๋น›์„ ๋ฐœํ•ด:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCrossAccountAccess",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::shared-data-bucket/*"
    }
  ]
}

์—ฌ๊ธฐ์„œ 123456789012๋Š” ๋‹ค๋ฅธ AWS ๊ณ„์ • ID์•ผ. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•ด๋‹น ๊ณ„์ •์˜ ์‚ฌ์šฉ์ž๋“ค์ด ์ด ๋ฒ„ํ‚ท์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด. ํŒŒํŠธ๋„ˆ์‚ฌ์™€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•˜๊ฑฐ๋‚˜, ๋ฉ€ํ‹ฐ ๊ณ„์ • ์•„ํ‚คํ…์ฒ˜๋ฅผ ๊ตฌ์„ฑํ•  ๋•Œ ํ•„์ˆ˜์ ์ด์•ผ!

๐Ÿ” ๋ณด์•ˆ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค
ํฌ๋กœ์Šค ๊ณ„์ • ์ ‘๊ทผ์„ ์„ค์ •ํ•  ๋•Œ๋Š” ๊ณ„์ • ์ „์ฒด(root)๋ณด๋‹ค๋Š” ํŠน์ • ์—ญํ• (Role)์„ ์ง€์ •ํ•˜๋Š” ๊ฒŒ ๋” ์•ˆ์ „ํ•ด. ์˜ˆ๋ฅผ ๋“ค์–ด:
"AWS": "arn:aws:iam::123456789012:role/DataAccessRole"
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๋” ์„ธ๋ฐ€ํ•œ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•ด!

๐Ÿ”’ ์•”ํ˜ธํ™” ๊ฐ•์ œํ•˜๊ธฐ

๋ฐ์ดํ„ฐ ๋ณด์•ˆ์„ ์œ„ํ•ด ์•”ํ˜ธํ™”๋˜์ง€ ์•Š์€ ๊ฐ์ฒด ์—…๋กœ๋“œ๋ฅผ ์ฐจ๋‹จํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyUnencryptedObjectUploads",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::secure-bucket/*",
      "Condition": {
        "StringNotEquals": {
          "s3:x-amz-server-side-encryption": [
            "AES256",
            "aws:kms"
          ]
        }
      }
    }
  ]
}

์ด ์ •์ฑ…์€ ์„œ๋ฒ„ ์ธก ์•”ํ˜ธํ™” ํ—ค๋”๊ฐ€ ์—†๋Š” ์—…๋กœ๋“œ๋ฅผ ๋ชจ๋‘ ๊ฑฐ๋ถ€ํ•ด. AES256(S3 ๊ด€๋ฆฌํ˜• ํ‚ค) ๋˜๋Š” aws:kms(KMS ๊ด€๋ฆฌํ˜• ํ‚ค) ์•”ํ˜ธํ™”๋ฅผ ์‚ฌ์šฉํ•ด์•ผ๋งŒ ์—…๋กœ๋“œ๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง€๋Š” ๊ฑฐ์ง€. ๐Ÿ’ช

๐ŸŒ ์ง€์—ญ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ ์ œ์–ด

ํŠน์ • ๊ตญ๊ฐ€์—์„œ๋งŒ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ๋„ ์žˆ์–ด. GDPR ๊ฐ™์€ ๊ทœ์ • ์ค€์ˆ˜๋ฅผ ์œ„ํ•ด์„œ ๋ง์ด์•ผ:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowOnlyFromSpecificCountries",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::eu-data-bucket",
        "arn:aws:s3:::eu-data-bucket/*"
      ],
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": [
            "eu-west-1",
            "eu-central-1"
          ]
        }
      }
    }
  ]
}

์ด ์ •์ฑ…์€ EU ๋ฆฌ์ „์—์„œ์˜ ์š”์ฒญ๋งŒ ํ—ˆ์šฉํ•˜๊ณ  ๋‚˜๋จธ์ง€๋Š” ๋ชจ๋‘ ์ฐจ๋‹จํ•ด. ๋ฐ์ดํ„ฐ ์ฃผ๊ถŒ(Data Sovereignty) ์š”๊ตฌ์‚ฌํ•ญ์„ ์ถฉ์กฑ์‹œํ‚ฌ ์ˆ˜ ์žˆ์–ด!

๐Ÿ“ MFA ์ธ์ฆ ๊ฐ•์ œ

์ค‘์š”ํ•œ ์ž‘์—…์—๋Š” MFA(๋‹ค์ค‘ ์ธ์ฆ)๋ฅผ ์š”๊ตฌํ•  ์ˆ˜ ์žˆ์–ด:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "RequireMFAForDelete",
      "Effect": "Deny",
      "Principal": "*",
      "Action": [
        "s3:DeleteObject",
        "s3:DeleteBucket"
      ],
      "Resource": [
        "arn:aws:s3:::critical-bucket",
        "arn:aws:s3:::critical-bucket/*"
      ],
      "Condition": {
        "BoolIfExists": {
          "aws:MultiFactorAuthPresent": "false"
        }
      }
    }
  ]
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด MFA ์ธ์ฆ ์—†์ด๋Š” ์ ˆ๋Œ€ ์‚ญ์ œํ•  ์ˆ˜ ์—†์–ด. ์‹ค์ˆ˜๋กœ ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์šฐ๋Š” ์‚ฌ๊ณ ๋ฅผ ์˜ˆ๋ฐฉํ•  ์ˆ˜ ์žˆ์ง€! ๐Ÿ”

๐ŸŽจ ๋ณต์žกํ•œ ์กฐ๊ฑด ์กฐํ•ฉํ•˜๊ธฐ

์—ฌ๋Ÿฌ ์กฐ๊ฑด์„ ์กฐํ•ฉํ•˜๋ฉด ์ •๋ง ์„ธ๋ฐ€ํ•œ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•ด. ์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊ฒŒ:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ComplexConditionExample",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/AppRole"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::app-data-bucket/*",
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "203.0.113.0/24"
        },
        "StringEquals": {
          "s3:ExistingObjectTag/classification": "public"
        },
        "DateGreaterThan": {
          "aws:CurrentTime": "2024-01-01T00:00:00Z"
        },
        "DateLessThan": {
          "aws:CurrentTime": "2024-12-31T23:59:59Z"
        }
      }
    }
  ]
}

์ด ์ •์ฑ…์€:
- ํŠน์ • ์—ญํ• (AppRole)์ด
- ํŠน์ • IP ๋Œ€์—ญ(203.0.113.0/24)์—์„œ
- public์œผ๋กœ ํƒœ๊ทธ๋œ ๊ฐ์ฒด๋งŒ
- 2024๋…„ ๋™์•ˆ๋งŒ
์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด. ์—„์ฒญ ๊ตฌ์ฒด์ ์ด์ง€? ๐Ÿ˜Ž

๐ŸŽ“ ์‹ค๋ฌด ์กฐ์–ธ ์ •์ฑ…์ด ๋ณต์žกํ•ด์งˆ์ˆ˜๋ก ํ…Œ์ŠคํŠธ๊ฐ€ ์ค‘์š”ํ•ด์ ธ. AWS IAM Policy Simulator๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ •์ฑ…์„ ์‹ค์ œ๋กœ ์ ์šฉํ•˜๊ธฐ ์ „์— ์‹œ๋ฎฌ๋ ˆ์ด์…˜ํ•ด๋ณผ ์ˆ˜ ์žˆ์–ด. ์‹ค์ˆ˜๋ฅผ ๋ฏธ๋ฆฌ ์žก์„ ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ๋„๊ตฌ์•ผ!

๐ŸŽญ S3 ์•ก์„ธ์Šค ํฌ์ธํŠธ ํ™œ์šฉํ•˜๊ธฐ

S3 ์•ก์„ธ์Šค ํฌ์ธํŠธ๋Š” 2019๋…„์— ๋„์ž…๋œ ๋น„๊ต์  ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์ด์•ผ. ๋ณต์žกํ•œ ๋ฒ„ํ‚ท ์ •์ฑ…์„ ๋‹จ์ˆœํ™”ํ•˜๊ณ , ๋Œ€๊ทœ๋ชจ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ ‘๊ทผ ๊ด€๋ฆฌ๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด์ค˜. ๐ŸŽฏ

๐Ÿค” ์•ก์„ธ์Šค ํฌ์ธํŠธ๊ฐ€ ๋ญ์•ผ?

๊ฐ„๋‹จํžˆ ๋งํ•˜๋ฉด, ํ•˜๋‚˜์˜ ๋ฒ„ํ‚ท์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ "์ถœ์ž…๊ตฌ"๋ฅผ ๋งŒ๋“œ๋Š” ๊ฑฐ์•ผ. ๊ฐ ์ถœ์ž…๊ตฌ๋งˆ๋‹ค ๋‹ค๋ฅธ ์ •์ฑ…์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์–ด์„œ, ๋ณต์žกํ•œ ๋ฒ„ํ‚ท ์ •์ฑ…์„ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ„๋‹จํ•œ ์ •์ฑ…์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์ง€.

์˜ˆ๋ฅผ ๋“ค์–ด๋ณผ๊ฒŒ. ํ•˜๋‚˜์˜ ๋ฐ์ดํ„ฐ ๋ ˆ์ดํฌ ๋ฒ„ํ‚ท์ด ์žˆ๋Š”๋ฐ:
- ๋ถ„์„ํŒ€์€ /analytics ๊ฒฝ๋กœ๋งŒ ์ฝ๊ธฐ
- ๊ฐœ๋ฐœํŒ€์€ /development ๊ฒฝ๋กœ์— ์ฝ๊ธฐ/์“ฐ๊ธฐ
- ๋งˆ์ผ€ํŒ…ํŒ€์€ /marketing ๊ฒฝ๋กœ๋งŒ ์ฝ๊ธฐ

์ด๊ฑธ ํ•˜๋‚˜์˜ ๋ฒ„ํ‚ท ์ •์ฑ…์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด ์ •๋ง ๋ณต์žกํ•ด์ ธ. ํ•˜์ง€๋งŒ ์•ก์„ธ์Šค ํฌ์ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ ํŒ€๋ณ„๋กœ ๋…๋ฆฝ์ ์ธ ์ •์ฑ…์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด!

๐Ÿ› ๏ธ ์•ก์„ธ์Šค ํฌ์ธํŠธ ์ƒ์„ฑํ•˜๊ธฐ

AWS CLI๋กœ ์•ก์„ธ์Šค ํฌ์ธํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•:

aws s3control create-access-point \
  --account-id 123456789012 \
  --name analytics-access-point \
  --bucket data-lake-bucket \
  --vpc-configuration VpcId=vpc-12345678

๊ทธ๋ฆฌ๊ณ  ๊ฐ ์•ก์„ธ์Šค ํฌ์ธํŠธ์— ์ •์ฑ…์„ ์ ์šฉํ•ด:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/AnalyticsRole"
      },
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:us-east-1:123456789012:accesspoint/analytics-access-point",
        "arn:aws:s3:us-east-1:123456789012:accesspoint/analytics-access-point/object/analytics/*"
      ]
    }
  ]
}

์ด์ œ ๋ถ„์„ํŒ€์€ ์ด ์•ก์„ธ์Šค ํฌ์ธํŠธ๋ฅผ ํ†ตํ•ด์„œ๋งŒ ๋ฒ„ํ‚ท์— ์ ‘๊ทผํ•˜๋ฉด ๋ผ. ์ž๋™์œผ๋กœ /analytics ๊ฒฝ๋กœ๋งŒ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋˜๋Š” ๊ฑฐ์ง€!

๐ŸŒ VPC ์ „์šฉ ์•ก์„ธ์Šค ํฌ์ธํŠธ

์•ก์„ธ์Šค ํฌ์ธํŠธ๋ฅผ ํŠน์ • VPC์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ์ œํ•œํ•  ์ˆ˜๋„ ์žˆ์–ด. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ธํ„ฐ๋„ท์„ ํ†ตํ•œ ์ ‘๊ทผ์„ ์™„์ „ํžˆ ์ฐจ๋‹จํ•˜๊ณ , VPC ๋‚ด๋ถ€์—์„œ๋งŒ S3์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ผ:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:us-east-1:123456789012:accesspoint/internal-access-point",
        "arn:aws:s3:us-east-1:123456789012:accesspoint/internal-access-point/object/*"
      ],
      "Condition": {
        "StringEquals": {
          "s3:DataAccessPointAccount": "123456789012"
        }
      }
    }
  ]
}

์ด๊ฑด ํŠนํžˆ ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ ์œ ์šฉํ•ด. ์™ธ๋ถ€ ์ธํ„ฐ๋„ท ๋…ธ์ถœ ์œ„ํ—˜์„ ์™„์ „ํžˆ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๊ฑฐ๋“ ! ๐Ÿ”’

๐Ÿ“Š ๋ฉ€ํ‹ฐ ๋ฆฌ์ „ ์•ก์„ธ์Šค ํฌ์ธํŠธ

2021๋…„์— ์ถ”๊ฐ€๋œ ๋ฉ€ํ‹ฐ ๋ฆฌ์ „ ์•ก์„ธ์Šค ํฌ์ธํŠธ๋Š” ์ •๋ง ํ˜์‹ ์ ์ด์•ผ. ์—ฌ๋Ÿฌ ๋ฆฌ์ „์˜ ๋ฒ„ํ‚ท์„ ํ•˜๋‚˜์˜ ๊ธ€๋กœ๋ฒŒ ์—”๋“œํฌ์ธํŠธ๋กœ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์–ด.

์˜ˆ๋ฅผ ๋“ค์–ด ๋ฏธ๊ตญ, ์œ ๋Ÿฝ, ์•„์‹œ์•„์— ๊ฐ๊ฐ ๋ฒ„ํ‚ท์ด ์žˆ๋‹ค๋ฉด, ๋ฉ€ํ‹ฐ ๋ฆฌ์ „ ์•ก์„ธ์Šค ํฌ์ธํŠธ๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ฒ„ํ‚ท์œผ๋กœ ์ž๋™ ๋ผ์šฐํŒ…ํ•  ์ˆ˜ ์žˆ์–ด. ๋ ˆ์ดํ„ด์‹œ๊ฐ€ ํ™• ์ค„์–ด๋“ค์ง€! ๐ŸŒ

aws s3control create-multi-region-access-point \
  --account-id 123456789012 \
  --details '{
    "Name": "global-data-access",
    "Regions": [
      {"Bucket": "data-us-east-1"},
      {"Bucket": "data-eu-west-1"},
      {"Bucket": "data-ap-northeast-1"}
    ]
  }'

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ๋Š” ํ•˜๋‚˜์˜ ์—”๋“œํฌ์ธํŠธ๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๊ณ , AWS๊ฐ€ ์•Œ์•„์„œ ์ตœ์ ์˜ ๋ฒ„ํ‚ท์œผ๋กœ ์—ฐ๊ฒฐํ•ด์ค˜. ๊ธ€๋กœ๋ฒŒ ์„œ๋น„์Šค๋ฅผ ์šด์˜ํ•œ๋‹ค๋ฉด ์ •๋ง ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์ด์•ผ!


๐Ÿ” S3 Object Lock๊ณผ ๋ฒ„์ „ ๊ด€๋ฆฌ

๋ฐ์ดํ„ฐ ๋ณดํ˜ธ์˜ ๋˜ ๋‹ค๋ฅธ ์ค‘์š”ํ•œ ์ธก๋ฉด์€ ์‹ค์ˆ˜๋‚˜ ์•…์˜์ ์ธ ์‚ญ์ œ๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€ํ‚ค๋Š” ๊ฑฐ์•ผ. S3๋Š” ์ด๋ฅผ ์œ„ํ•œ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ๋“ค์„ ์ œ๊ณตํ•ด!

๐Ÿ“š ๋ฒ„์ „ ๊ด€๋ฆฌ (Versioning)

S3 ๋ฒ„์ „ ๊ด€๋ฆฌ๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋ฉด ๊ฐ์ฒด์˜ ๋ชจ๋“  ๋ฒ„์ „์ด ๋ณด์กด๋ผ. ํŒŒ์ผ์„ ๋ฎ์–ด์“ฐ๊ฑฐ๋‚˜ ์‚ญ์ œํ•ด๋„ ์ด์ „ ๋ฒ„์ „์„ ๋ณต๊ตฌํ•  ์ˆ˜ ์žˆ์–ด. ๋งˆ์น˜ Git์ฒ˜๋Ÿผ ๋ง์ด์•ผ! ๐Ÿ”„

๋ฒ„์ „ ๊ด€๋ฆฌ๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฑด ๊ฐ„๋‹จํ•ด:

aws s3api put-bucket-versioning \
  --bucket my-bucket \
  --versioning-configuration Status=Enabled

๋ฒ„์ „ ๊ด€๋ฆฌ๊ฐ€ ํ™œ์„ฑํ™”๋˜๋ฉด:
- ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ ๋ฒ„์ „ ID๊ฐ€ ์ƒ์„ฑ๋ผ
- ์‚ญ์ œํ•ด๋„ ์‹ค์ œ๋กœ๋Š” ์‚ญ์ œ ๋งˆ์ปค๋งŒ ์ถ”๊ฐ€๋ผ
- ์–ธ์ œ๋“  ์ด์ „ ๋ฒ„์ „์œผ๋กœ ๋กค๋ฐฑ ๊ฐ€๋Šฅํ•ด

๋‹จ์ ์€? ์Šคํ† ๋ฆฌ์ง€ ๋น„์šฉ์ด ์ฆ๊ฐ€ํ•œ๋‹ค๋Š” ๊ฑฐ์•ผ. ๋ชจ๋“  ๋ฒ„์ „์„ ์ €์žฅํ•˜๋‹ˆ๊นŒ ๋‹น์—ฐํ•˜์ง€. ๊ทธ๋ž˜์„œ ๋ผ์ดํ”„์‚ฌ์ดํด ์ •์ฑ…๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์„œ ์˜ค๋ž˜๋œ ๋ฒ„์ „์€ ์ž๋™์œผ๋กœ ์‚ญ์ œํ•˜๋Š” ๊ฒŒ ์ข‹์•„.

๐Ÿ”’ S3 Object Lock

Object Lock์€ WORM(Write Once Read Many) ๋ชจ๋ธ์„ ๊ตฌํ˜„ํ•ด. ํ•œ ๋ฒˆ ์“ฐ๋ฉด ์ง€์ •๋œ ๊ธฐ๊ฐ„ ๋™์•ˆ ์ ˆ๋Œ€ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ์ˆ˜ ์—†์–ด. ๊ทœ์ • ์ค€์ˆ˜๊ฐ€ ์ค‘์š”ํ•œ ์‚ฐ์—…(๊ธˆ์œต, ์˜๋ฃŒ ๋“ฑ)์—์„œ ํ•„์ˆ˜์ ์ด์•ผ! ๐Ÿ›๏ธ

Object Lock์—๋Š” ๋‘ ๊ฐ€์ง€ ๋ชจ๋“œ๊ฐ€ ์žˆ์–ด:

1๏ธโƒฃ Governance ๋ชจ๋“œ

ํŠน๋ณ„ํ•œ ๊ถŒํ•œ์„ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž๋Š” ๋ณดํ˜ธ๋ฅผ ํ•ด์ œํ•˜๊ฑฐ๋‚˜ ๋ณด์กด ๊ธฐ๊ฐ„์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์–ด. ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ์ž๋Š” ๋ณดํ˜ธ๋˜์ง€๋งŒ, ๊ด€๋ฆฌ์ž๋Š” ํ•„์š”์‹œ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑฐ์ง€.

2๏ธโƒฃ Compliance ๋ชจ๋“œ

๋ฃจํŠธ ์‚ฌ์šฉ์ž๋ฅผ ํฌํ•จํ•ด์„œ ๋ˆ„๊ตฌ๋„ ๋ณดํ˜ธ๋ฅผ ํ•ด์ œํ•  ์ˆ˜ ์—†์–ด. ๋ณด์กด ๊ธฐ๊ฐ„์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ์ ˆ๋Œ€์ ์œผ๋กœ ๋ณดํ˜ธ๋ผ. ๋ฒ•์  ์š”๊ตฌ์‚ฌํ•ญ์„ ์ถฉ์กฑ์‹œํ‚ฌ ๋•Œ ์‚ฌ์šฉํ•ด.

Object Lock์„ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•:

aws s3api put-object-lock-configuration \
  --bucket compliance-bucket \
  --object-lock-configuration '{
    "ObjectLockEnabled": "Enabled",
    "Rule": {
      "DefaultRetention": {
        "Mode": "COMPLIANCE",
        "Days": 365
      }
    }
  }'

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์—…๋กœ๋“œ๋˜๋Š” ๋ชจ๋“  ๊ฐ์ฒด๊ฐ€ 1๋…„ ๋™์•ˆ ์ž๋™์œผ๋กœ ์ž ๊ฒจ. ๊ธˆ์œต ๊ฑฐ๋ž˜ ๊ธฐ๋ก์ด๋‚˜ ์˜๋ฃŒ ๊ธฐ๋ก์ฒ˜๋Ÿผ ๋ฒ•์ ์œผ๋กœ ๋ณด์กด ๊ธฐ๊ฐ„์ด ์ •ํ•ด์ง„ ๋ฐ์ดํ„ฐ์— ์™„๋ฒฝํ•ด! ๐Ÿ“‹

โš–๏ธ Legal Hold

Legal Hold๋Š” ๋ณด์กด ๊ธฐ๊ฐ„๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ๊ฐ์ฒด๋ฅผ ๋ฌด๊ธฐํ•œ ๋ณดํ˜ธํ•  ์ˆ˜ ์žˆ์–ด. ์†Œ์†ก์ด๋‚˜ ์กฐ์‚ฌ๊ฐ€ ์ง„ํ–‰ ์ค‘์ผ ๋•Œ ์ฆ๊ฑฐ ์ž๋ฃŒ๋ฅผ ๋ณดํ˜ธํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉํ•ด:

aws s3api put-object-legal-hold \
  --bucket evidence-bucket \
  --key important-document.pdf \
  --legal-hold Status=ON

Legal Hold๊ฐ€ ์„ค์ •๋˜๋ฉด s3:PutObjectLegalHold ๊ถŒํ•œ์„ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž๋งŒ ํ•ด์ œํ•  ์ˆ˜ ์žˆ์–ด. ๋ณด์กด ๊ธฐ๊ฐ„์ด ๋๋‚˜๋„ Legal Hold๊ฐ€ ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์œผ๋ฉด ์‚ญ์ œํ•  ์ˆ˜ ์—†์ง€.

โš ๏ธ ์ค‘์š”ํ•œ ์ฃผ์˜์‚ฌํ•ญ Object Lock์€ ๋ฒ„ํ‚ท ์ƒ์„ฑ ์‹œ์—๋งŒ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์–ด. ๊ธฐ์กด ๋ฒ„ํ‚ท์—๋Š” ๋‚˜์ค‘์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†์œผ๋‹ˆ, ์ฒ˜์Œ๋ถ€ํ„ฐ ์‹ ์ค‘ํ•˜๊ฒŒ ๊ณ„ํšํ•ด์•ผ ํ•ด! ๋˜ํ•œ Object Lock์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ฒ„์ „ ๊ด€๋ฆฌ๊ฐ€ ํ•„์ˆ˜๋กœ ํ™œ์„ฑํ™”๋˜์–ด์•ผ ํ•ด.

๐Ÿš€ S3 ์ ‘๊ทผ ๋กœ๊น…๊ณผ ๋ชจ๋‹ˆํ„ฐ๋ง

์•„๋ฌด๋ฆฌ ์™„๋ฒฝํ•œ ์ ‘๊ทผ์ œ์–ด ์ •์ฑ…์„ ๋งŒ๋“ค์–ด๋„, ์‹ค์ œ๋กœ ์–ด๋–ค ์ผ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜์ง€ ์•Š์œผ๋ฉด ์†Œ์šฉ์—†์–ด. ๋กœ๊น…๊ณผ ๋ชจ๋‹ˆํ„ฐ๋ง์€ ๋ณด์•ˆ์˜ ํ•ต์‹ฌ์ด์•ผ! ๐Ÿ‘€

๐Ÿ“ S3 ์„œ๋ฒ„ ์•ก์„ธ์Šค ๋กœ๊น…

S3 ์„œ๋ฒ„ ์•ก์„ธ์Šค ๋กœ๊น…์„ ํ™œ์„ฑํ™”ํ•˜๋ฉด ๋ฒ„ํ‚ท์— ๋Œ€ํ•œ ๋ชจ๋“  ์š”์ฒญ์ด ๊ธฐ๋ก๋ผ. ๋ˆ„๊ฐ€, ์–ธ์ œ, ์–ด๋–ค ์ž‘์—…์„ ํ–ˆ๋Š”์ง€ ์ƒ์„ธํ•˜๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์–ด:

aws s3api put-bucket-logging \
  --bucket my-bucket \
  --bucket-logging-status '{
    "LoggingEnabled": {
      "TargetBucket": "my-logs-bucket",
      "TargetPrefix": "s3-access-logs/"
    }
  }'

๋กœ๊ทธ ํŒŒ์ผ์€ ์ด๋Ÿฐ ํ˜•์‹์œผ๋กœ ์ €์žฅ๋ผ:

79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be my-bucket [06/Feb/2024:00:00:01 +0000] 192.0.2.3 79a59df900b949e55d96a1e698fbacedfd6e09d98eacf8f8d5218e7cd47ef2be 3E57427F3EXAMPLE REST.GET.VERSIONING - "GET /my-bucket?versioning HTTP/1.1" 200 - 113 - 7 - "-" "S3Console/0.4" - s9lzHYrFp76ZVxRcpX9+5cjAnEH2ROuNkd2BHfIa6UkFVdtjf5mKR3/eTPFvsiP/XV/VLi31234= SigV2 ECDHE-RSA-AES128-GCM-SHA256 AuthHeader my-bucket.s3.amazonaws.com TLSV1.2

๋ณต์žกํ•ด ๋ณด์ด์ง€๋งŒ, ๊ฐ ํ•„๋“œ๊ฐ€ ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋ฅผ ์•Œ๋ฉด ์œ ์šฉํ•œ ์ •๋ณด๊ฐ€ ๋งŽ์•„:
- ์š”์ฒญ์ž IP ์ฃผ์†Œ
- ์š”์ฒญ ์‹œ๊ฐ„
- ์ˆ˜ํ–‰๋œ ์ž‘์—…
- HTTP ์ƒํƒœ ์ฝ”๋“œ
- ์—๋Ÿฌ ์ฝ”๋“œ (์žˆ๋‹ค๋ฉด)
- ์ „์†ก๋œ ๋ฐ”์ดํŠธ ์ˆ˜

์ด ๋กœ๊ทธ๋ฅผ ๋ถ„์„ํ•˜๋ฉด ๋น„์ •์ƒ์ ์ธ ์ ‘๊ทผ ํŒจํ„ด์„ ์ฐพ์•„๋‚ผ ์ˆ˜ ์žˆ์–ด!

๐Ÿ” AWS CloudTrail

CloudTrail์€ AWS API ํ˜ธ์ถœ์„ ๊ธฐ๋กํ•ด. S3 ์„œ๋ฒ„ ์•ก์„ธ์Šค ๋กœ๊ทธ๋ณด๋‹ค ๋” ์ƒ์„ธํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๊ณ , ๊ด€๋ฆฌ ์ด๋ฒคํŠธ์™€ ๋ฐ์ดํ„ฐ ์ด๋ฒคํŠธ๋ฅผ ๋ชจ๋‘ ์ถ”์ ํ•  ์ˆ˜ ์žˆ์–ด.

ํŠนํžˆ S3 ๋ฐ์ดํ„ฐ ์ด๋ฒคํŠธ ๋กœ๊น…์„ ํ™œ์„ฑํ™”ํ•˜๋ฉด:

aws cloudtrail put-event-selectors \
  --trail-name my-trail \
  --event-selectors '[
    {
      "ReadWriteType": "All",
      "IncludeManagementEvents": true,
      "DataResources": [
        {
          "Type": "AWS::S3::Object",
          "Values": ["arn:aws:s3:::my-bucket/*"]
        }
      ]
    }
  ]'

CloudTrail ๋กœ๊ทธ๋Š” JSON ํ˜•์‹์ด๋ผ ํŒŒ์‹ฑํ•˜๊ธฐ ์‰ฌ์›Œ:

{
  "eventVersion": "1.08",
  "userIdentity": {
    "type": "IAMUser",
    "principalId": "AIDAI23HXX2LO4example",
    "arn": "arn:aws:iam::123456789012:user/Alice",
    "accountId": "123456789012",
    "userName": "Alice"
  },
  "eventTime": "2024-01-15T10:30:00Z",
  "eventSource": "s3.amazonaws.com",
  "eventName": "GetObject",
  "awsRegion": "us-east-1",
  "sourceIPAddress": "203.0.113.42",
  "requestParameters": {
    "bucketName": "my-bucket",
    "key": "sensitive-data.csv"
  },
  "responseElements": null,
  "requestID": "EXAMPLE123456789",
  "eventID": "EXAMPLE-8752-4fc8-b0e6-example",
  "readOnly": true,
  "resources": [
    {
      "type": "AWS::S3::Object",
      "ARN": "arn:aws:s3:::my-bucket/sensitive-data.csv"
    }
  ],
  "eventType": "AwsApiCall",
  "recipientAccountId": "123456789012"
}

์ด ์ •๋ณด๋กœ ๋ˆ„๊ฐ€(Alice), ์–ธ์ œ(2024-01-15 10:30), ์–ด๋””์„œ(203.0.113.42), ๋ฌด์—‡์„(sensitive-data.csv ์ฝ๊ธฐ) ํ–ˆ๋Š”์ง€ ์ •ํ™•ํžˆ ์•Œ ์ˆ˜ ์žˆ์–ด! ๐Ÿ•ต๏ธ

๐Ÿ“Š Amazon Macie๋กœ ๋ฏผ๊ฐ ๋ฐ์ดํ„ฐ ํƒ์ง€

Amazon Macie๋Š” ๋จธ์‹ ๋Ÿฌ๋‹์„ ์‚ฌ์šฉํ•ด์„œ S3์— ์ €์žฅ๋œ ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ž๋™์œผ๋กœ ์ฐพ์•„๋‚ด. ๊ฐœ์ธ์ •๋ณด, ์‹ ์šฉ์นด๋“œ ๋ฒˆํ˜ธ, API ํ‚ค ๊ฐ™์€ ๊ฑธ ํƒ์ง€ํ•  ์ˆ˜ ์žˆ์–ด.

Macie๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋ฉด:

aws macie2 enable-macie

๊ทธ๋ฆฌ๊ณ  ๋ถ„๋ฅ˜ ์ž‘์—…์„ ์ƒ์„ฑํ•ด:

aws macie2 create-classification-job \
  --job-type ONE_TIME \
  --s3-job-definition '{
    "bucketDefinitions": [
      {
        "accountId": "123456789012",
        "buckets": ["my-bucket"]
      }
    ]
  }' \
  --name "Sensitive Data Discovery" \
  --description "Find PII in my-bucket"

Macie๋Š” ์ž๋™์œผ๋กœ ๋ฒ„ํ‚ท์„ ์Šค์บ”ํ•˜๊ณ , ๋ฐœ๊ฒฌํ•œ ๋ฏผ๊ฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฆฌํฌํŠธํ•ด์ค˜. ์‹ค์ˆ˜๋กœ ๋ฏผ๊ฐํ•œ ์ •๋ณด๊ฐ€ ๋…ธ์ถœ๋˜๋Š” ๊ฑธ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์ง€! ๐Ÿ›ก๏ธ

โšก Amazon GuardDuty

GuardDuty๋Š” ์œ„ํ˜‘ ํƒ์ง€ ์„œ๋น„์Šค์•ผ. CloudTrail ๋กœ๊ทธ, VPC Flow Logs, DNS ๋กœ๊ทธ๋ฅผ ๋ถ„์„ํ•ด์„œ ์˜์‹ฌ์Šค๋Ÿฌ์šด ํ™œ๋™์„ ์ฐพ์•„๋‚ด.

S3 ๊ด€๋ จํ•ด์„œ๋Š” ์ด๋Ÿฐ ์œ„ํ˜‘์„ ํƒ์ง€ํ•  ์ˆ˜ ์žˆ์–ด:
- ๋น„์ •์ƒ์ ์ธ API ํ˜ธ์ถœ ํŒจํ„ด
- ์ต๋ช… ์‚ฌ์šฉ์ž์˜ ์ ‘๊ทผ ์‹œ๋„
- ์•Œ๋ ค์ง„ ์•…์„ฑ IP์—์„œ์˜ ์ ‘๊ทผ
- ๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ ์œ ์ถœ ์‹œ๋„

GuardDuty๊ฐ€ ์œ„ํ˜‘์„ ํƒ์ง€ํ•˜๋ฉด ์ž๋™์œผ๋กœ ์•Œ๋ฆผ์„ ๋ณด๋‚ด์ค˜. EventBridge์™€ ์—ฐ๋™ํ•˜๋ฉด ์ž๋™ ๋Œ€์‘๋„ ๊ฐ€๋Šฅํ•ด!

๐Ÿ’ก ์‹ค์ „ ํŒ ๋กœ๊ทธ๋ฅผ ๊ทธ๋ƒฅ ์Œ“์•„๋‘๊ธฐ๋งŒ ํ•˜๋ฉด ์˜๋ฏธ๊ฐ€ ์—†์–ด. Amazon Athena๋กœ S3 ๋กœ๊ทธ๋ฅผ ์ฟผ๋ฆฌํ•˜๊ฑฐ๋‚˜, Amazon OpenSearch Service๋กœ ์‹œ๊ฐํ™”ํ•˜๋ฉด ํ›จ์”ฌ ์œ ์šฉํ•ด. ์ด์ƒ ํŒจํ„ด์„ ๋น ๋ฅด๊ฒŒ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ๊ฑฐ๋“ !

๐ŸŽฏ ์‹ค์ „ ์‹œ๋‚˜๋ฆฌ์˜ค๋ณ„ ์ ‘๊ทผ์ œ์–ด ๊ตฌ์„ฑ

์ด๋ก ์€ ์ถฉ๋ถ„ํžˆ ๋ฐฐ์› ์œผ๋‹ˆ, ์ด์ œ ์‹ค์ œ ์ƒํ™ฉ์—์„œ ์–ด๋–ป๊ฒŒ ์ ์šฉํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด์ž! ๋‹ค์–‘ํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ค€๋น„ํ–ˆ์–ด. ๐ŸŽฌ

๐Ÿข ์‹œ๋‚˜๋ฆฌ์˜ค 1: ๊ธฐ์—… ๋ฐ์ดํ„ฐ ๋ ˆ์ดํฌ

๋Œ€๊ธฐ์—…์—์„œ ๋ฐ์ดํ„ฐ ๋ ˆ์ดํฌ๋ฅผ ๊ตฌ์ถ•ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ์—ฌ๋Ÿฌ ๋ถ€์„œ๊ฐ€ ๊ฐ™์€ ๋ฒ„ํ‚ท์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ๊ฐ์ž ์ž๊ธฐ ๋ถ€์„œ ๋ฐ์ดํ„ฐ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ด.

์š”๊ตฌ์‚ฌํ•ญ:
- ๊ฐ ๋ถ€์„œ๋Š” ์ž๊ธฐ ํด๋”์—๋งŒ ์ ‘๊ทผ
- ๋ฐ์ดํ„ฐ ๊ณผํ•™ํŒ€์€ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ ๊ฐ€๋Šฅ
- ์‚ญ์ œ๋Š” ๊ด€๋ฆฌ์ž๋งŒ ๊ฐ€๋Šฅ
- ๋ชจ๋“  ์ ‘๊ทผ์€ VPC ๋‚ด๋ถ€์—์„œ๋งŒ

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:

1. ๋จผ์ € ๋ถ€์„œ๋ณ„ IAM ์—ญํ• ์„ ๋งŒ๋“ค์–ด:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket"
      ],
      "Resource": "arn:aws:s3:::company-datalake",
      "Condition": {
        "StringLike": {
          "s3:prefix": [
            "${aws:PrincipalTag/department}/*"
          ]
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": "arn:aws:s3:::company-datalake/${aws:PrincipalTag/department}/*"
    }
  ]
}

2. ๋ฐ์ดํ„ฐ ๊ณผํ•™ํŒ€์—๋Š” ๋ณ„๋„ ์ •์ฑ…:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::company-datalake",
        "arn:aws:s3:::company-datalake/*"
      ]
    }
  ]
}

3. ๋ฒ„ํ‚ท ์ •์ฑ…์œผ๋กœ VPC ์ œํ•œ๊ณผ ์‚ญ์ œ ๋ฐฉ์ง€:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VPCOnly",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::company-datalake",
        "arn:aws:s3:::company-datalake/*"
      ],
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpc": "vpc-12345678"
        }
      }
    },
    {
      "Sid": "DenyDeleteExceptAdmin",
      "Effect": "Deny",
      "NotPrincipal": {
        "AWS": "arn:aws:iam::123456789012:role/AdminRole"
      },
      "Action": [
        "s3:DeleteObject",
        "s3:DeleteBucket"
      ],
      "Resource": [
        "arn:aws:s3:::company-datalake",
        "arn:aws:s3:::company-datalake/*"
      ]
    }
  ]
}

์ด๋ ‡๊ฒŒ ๊ตฌ์„ฑํ•˜๋ฉด ๊ฐ ๋ถ€์„œ๋Š” ์ž๊ธฐ ๋ฐ์ดํ„ฐ๋งŒ ๊ด€๋ฆฌํ•˜๊ณ , ๋ฐ์ดํ„ฐ ๊ณผํ•™ํŒ€์€ ๋ถ„์„์„ ์œ„ํ•ด ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์„ ์ˆ˜ ์žˆ์–ด. ๊ทธ๋ฆฌ๊ณ  ์‹ค์ˆ˜๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์šฐ๋Š” ์ผ๋„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์ง€! ๐Ÿ‘

๐ŸŒ ์‹œ๋‚˜๋ฆฌ์˜ค 2: ๊ธ€๋กœ๋ฒŒ CDN ์ฝ˜ํ…์ธ  ๋ฐฐํฌ

์ „ ์„ธ๊ณ„ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ •์  ์ฝ˜ํ…์ธ ๋ฅผ ์ œ๊ณตํ•˜๋Š” ์„œ๋น„์Šค๋ฅผ ์šด์˜ํ•œ๋‹ค๊ณ  ํ•ด๋ณด์ž. CloudFront์™€ S3๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ์ „ํ˜•์ ์ธ ํŒจํ„ด์ด์•ผ.

์š”๊ตฌ์‚ฌํ•ญ:
- S3๋Š” ํผ๋ธ”๋ฆญ ์ ‘๊ทผ ์ฐจ๋‹จ
- CloudFront๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ
- ํŠน์ • ๊ตญ๊ฐ€๋Š” ์ฐจ๋‹จ (์ง€์—ญ ์ œํ•œ)
- ํ•ซ๋งํฌ ๋ฐฉ์ง€

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:

1. CloudFront Origin Access Identity(OAI) ์ƒ์„ฑ:

aws cloudfront create-cloud-front-origin-access-identity \
  --cloud-front-origin-access-identity-config \
    CallerReference=my-oai-$(date +%s),Comment="OAI for my-website"

2. S3 ๋ฒ„ํ‚ท ์ •์ฑ…์—์„œ OAI๋งŒ ํ—ˆ์šฉ:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCloudFrontOAI",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity EXAMPLE123"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-website-bucket/*"
    }
  ]
}

3. CloudFront ๋ฐฐํฌ์—์„œ ์ง€์—ญ ์ œํ•œ ์„ค์ •:

{
  "GeoRestriction": {
    "RestrictionType": "blacklist",
    "Quantity": 2,
    "Items": ["KP", "IR"]
  }
}

4. Referer ํ—ค๋” ์ฒดํฌ๋กœ ํ•ซ๋งํฌ ๋ฐฉ์ง€:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PreventHotlinking",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-website-bucket/*",
      "Condition": {
        "StringNotLike": {
          "aws:Referer": [
            "https://mywebsite.com/*",
            "https://*.cloudfront.net/*"
          ]
        }
      }
    }
  ]
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด S3๋Š” ์™„์ „ํžˆ ํ”„๋ผ์ด๋น—ํ•˜๊ฒŒ ์œ ์ง€ํ•˜๋ฉด์„œ๋„, CloudFront๋ฅผ ํ†ตํ•ด ์ „ ์„ธ๊ณ„์— ์ฝ˜ํ…์ธ ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์–ด! ๐ŸŒ

๐Ÿ’ผ ์‹œ๋‚˜๋ฆฌ์˜ค 3: ํŒŒํŠธ๋„ˆ์‚ฌ์™€ ๋ฐ์ดํ„ฐ ๊ณต์œ 

์™ธ๋ถ€ ํŒŒํŠธ๋„ˆ์‚ฌ์™€ ์•ˆ์ „ํ•˜๊ฒŒ ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ์„ ์ฃผ๊ณ ๋ฐ›์•„์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด์•ผ.

์š”๊ตฌ์‚ฌํ•ญ:
- ํŒŒํŠธ๋„ˆ์‚ฌ AWS ๊ณ„์ •์—์„œ ์ ‘๊ทผ
- ํŠน์ • ํด๋”๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ
- ์—…๋กœ๋“œ๋Š” ๊ฐ€๋Šฅํ•˜์ง€๋งŒ ์‚ญ์ œ๋Š” ๋ถˆ๊ฐ€
- ์ ‘๊ทผ ๋กœ๊ทธ ์ƒ์„ธ ๊ธฐ๋ก

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:

1. ํŒŒํŠธ๋„ˆ์‚ฌ ๊ณ„์ •์˜ ์—ญํ• ์— ๊ถŒํ•œ ๋ถ€์—ฌ:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowPartnerAccess",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::PARTNER-ACCOUNT-ID:role/DataExchangeRole"
      },
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::shared-data-bucket/partner-exchange/*"
      ],
      "Condition": {
        "StringEquals": {
          "s3:x-amz-server-side-encryption": "AES256"
        }
      }
    },
    {
      "Sid": "DenyDelete",
      "Effect": "Deny",
      "Principal": {
        "AWS": "arn:aws:iam::PARTNER-ACCOUNT-ID:role/DataExchangeRole"
      },
      "Action": [
        "s3:DeleteObject",
        "s3:DeleteObjectVersion"
      ],
      "Resource": "arn:aws:s3:::shared-data-bucket/*"
    }
  ]
}

2. ํŒŒํŠธ๋„ˆ์‚ฌ ๊ณ„์ •์—์„œ ์—ญํ•  ์ƒ์„ฑ (ํŒŒํŠธ๋„ˆ์‚ฌ๊ฐ€ ํ•ด์•ผ ํ•  ์ž‘์—…):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::PARTNER-ACCOUNT-ID:root"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

3. CloudTrail ๋ฐ์ดํ„ฐ ์ด๋ฒคํŠธ ๋กœ๊น… ํ™œ์„ฑํ™”:

aws cloudtrail put-event-selectors \
  --trail-name partner-access-trail \
  --event-selectors '[
    {
      "ReadWriteType": "All",
      "IncludeManagementEvents": false,
      "DataResources": [
        {
          "Type": "AWS::S3::Object",
          "Values": ["arn:aws:s3:::shared-data-bucket/partner-exchange/*"]
        }
      ]
    }
  ]'

์ด์ œ ํŒŒํŠธ๋„ˆ์‚ฌ๋Š” ์ž๊ธฐ AWS ๊ณ„์ •์—์„œ ์—ญํ• ์„ assumeํ•˜๊ณ , ์ง€์ •๋œ ํด๋”์— ์•ˆ์ „ํ•˜๊ฒŒ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•  ์ˆ˜ ์žˆ์–ด. ๋ชจ๋“  ํ™œ๋™์€ CloudTrail์— ๊ธฐ๋ก๋˜๊ณ ! ๐Ÿ“

๐Ÿ”ฌ ์‹œ๋‚˜๋ฆฌ์˜ค 4: ์—ฐ๊ตฌ ๋ฐ์ดํ„ฐ ๊ณต๊ฐœ

๋Œ€ํ•™์ด๋‚˜ ์—ฐ๊ตฌ์†Œ์—์„œ ์—ฐ๊ตฌ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต๊ฐœํ•˜๋ ค๊ณ  ํ•ด. ๋ˆ„๊ตฌ๋‚˜ ๋‹ค์šด๋กœ๋“œํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋น„์šฉ์€ ๋‹ค์šด๋กœ๋“œํ•˜๋Š” ์‚ฌ๋žŒ์ด ๋ถ€๋‹ดํ•˜๊ฒŒ ํ•˜๊ณ  ์‹ถ์–ด.

์š”๊ตฌ์‚ฌํ•ญ:
- ํผ๋ธ”๋ฆญ ์ฝ๊ธฐ ์ ‘๊ทผ
- Requester Pays ํ™œ์„ฑํ™”
- ๋Œ€์šฉ๋Ÿ‰ ๋‹ค์šด๋กœ๋“œ ์ œํ•œ
- ํ†ต๊ณ„ ์ˆ˜์ง‘

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•:

1. Requester Pays ํ™œ์„ฑํ™”:

aws s3api put-bucket-request-payment \
  --bucket research-data-bucket \
  --request-payment-configuration '{"Payer":"Requester"}'

2. ๋ฒ„ํ‚ท ์ •์ฑ… ์„ค์ •:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadWithRequesterPays",
      "Effect": "Allow",
      "Principal": "*",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::research-data-bucket",
        "arn:aws:s3:::research-data-bucket/*"
      ]
    }
  ]
}

3. ๋Œ€์šฉ๋Ÿ‰ ๋‹ค์šด๋กœ๋“œ ์ œํ•œ (Lambda@Edge ์‚ฌ์šฉ):

exports.handler = async (event) => {
  const request = event.Records[0].cf.request;
  const headers = request.headers;
  
  // ํ•˜๋ฃจ ๋‹ค์šด๋กœ๋“œ ์ œํ•œ ์ฒดํฌ (DynamoDB ๋“ฑ ํ™œ์šฉ)
  const clientIp = headers['x-forwarded-for'] ? 
    headers['x-forwarded-for'][0].value : 
    headers['cloudfront-viewer-address'][0].value;
  
  const downloadCount = await checkDownloadCount(clientIp);
  
  if (downloadCount > 100) {
    return {
      status: '429',
      statusDescription: 'Too Many Requests',
      body: 'Daily download limit exceeded'
    };
  }
  
  return request;
};

Requester Pays๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต๊ฐœํ•˜๋ฉด์„œ๋„ ์ „์†ก ๋น„์šฉ ๋ถ€๋‹ด์„ ์ค„์ผ ์ˆ˜ ์žˆ์–ด. ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ์…‹์„ ๊ณต์œ ํ•  ๋•Œ ์œ ์šฉํ•œ ๋ฐฉ๋ฒ•์ด์•ผ! ๐Ÿ’ฐ

๐ŸŽ“ ์žฌ๋Šฅ๋„ท์—์„œ ๋ฐฐ์šฐ๊ธฐ ์ด๋Ÿฐ ๋ณต์žกํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค๋“ค์„ ์‹ค์ œ๋กœ ๊ตฌํ˜„ํ•˜๋‹ค ๋ณด๋ฉด ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ œ๋“ค์ด ์ƒ๊ธฐ๊ณค ํ•ด. ์žฌ๋Šฅ๋„ท์—์„œ AWS ์ „๋ฌธ๊ฐ€์˜ 1:1 ๋ฉ˜ํ† ๋ง์„ ๋ฐ›์œผ๋ฉด ์‹œํ–‰์ฐฉ์˜ค๋ฅผ ์ค„์ด๊ณ  ๋น ๋ฅด๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์–ด. ์‹ค๋ฌด ๊ฒฝํ—˜์ด ํ’๋ถ€ํ•œ ์ „๋ฌธ๊ฐ€๋“ค์ด ๋‹น์‹ ์˜ ํŠน์ˆ˜ํ•œ ์ƒํ™ฉ์— ๋งž๋Š” ์†”๋ฃจ์…˜์„ ์ œ์‹œํ•ด์ค„ ๊ฑฐ์•ผ!

๐Ÿ›ก๏ธ ๋ณด์•ˆ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค

์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ, S3 ์ ‘๊ทผ์ œ์–ด์˜ ๋ณด์•ˆ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค๋ฅผ ์ •๋ฆฌํ•ด๋ณผ๊ฒŒ. ์ด๊ฑธ ๋”ฐ๋ฅด๋ฉด ๋Œ€๋ถ€๋ถ„์˜ ๋ณด์•ˆ ์‚ฌ๊ณ ๋ฅผ ์˜ˆ๋ฐฉํ•  ์ˆ˜ ์žˆ์–ด! ๐ŸŽฏ

1๏ธโƒฃ ์ตœ์†Œ ๊ถŒํ•œ ์›์น™ (Principle of Least Privilege)

ํ•ญ์ƒ ํ•„์š”ํ•œ ์ตœ์†Œํ•œ์˜ ๊ถŒํ•œ๋งŒ ๋ถ€์—ฌํ•ด. "์ผ๋‹จ ๋‹ค ์ฃผ๊ณ  ๋‚˜์ค‘์— ์ œํ•œํ•˜์ž"๋Š” ์œ„ํ—˜ํ•œ ์ƒ๊ฐ์ด์•ผ.

๋‚˜์œ ์˜ˆ:

{
  "Effect": "Allow",
  "Action": "s3:*",
  "Resource": "*"
}

์ข‹์€ ์˜ˆ:

{
  "Effect": "Allow",
  "Action": [
    "s3:GetObject",
    "s3:PutObject"
  ],
  "Resource": "arn:aws:s3:::specific-bucket/specific-prefix/*"
}

2๏ธโƒฃ ๋ธ”๋ก ํผ๋ธ”๋ฆญ ์•ก์„ธ์Šค ๊ธฐ๋ณธ ํ™œ์„ฑํ™”

์ •๋ง ํผ๋ธ”๋ฆญ ์ ‘๊ทผ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด, ๋ธ”๋ก ํผ๋ธ”๋ฆญ ์•ก์„ธ์Šค ์„ค์ •์„ ์ ˆ๋Œ€ ํ•ด์ œํ•˜์ง€ ๋งˆ. ์ด๊ฒŒ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ด๋ฉด์„œ๋„ ๊ฐ•๋ ฅํ•œ ๋ฐฉ์–ด๋ง‰์ด์•ผ! ๐Ÿšง

3๏ธโƒฃ ์•”ํ˜ธํ™”๋Š” ํ•„์ˆ˜

๋ชจ๋“  S3 ๋ฒ„ํ‚ท์— ๊ธฐ๋ณธ ์•”ํ˜ธํ™”๋ฅผ ์„ค์ •ํ•ด:

aws s3api put-bucket-encryption \
  --bucket my-bucket \
  --server-side-encryption-configuration '{
    "Rules": [
      {
        "ApplyServerSideEncryptionByDefault": {
          "SSEAlgorithm": "AES256"
        },
        "BucketKeyEnabled": true
      }
    ]
  }'

๋” ๊ฐ•๋ ฅํ•œ ๋ณด์•ˆ์ด ํ•„์š”ํ•˜๋ฉด AWS KMS๋ฅผ ์‚ฌ์šฉํ•ด. ํ‚ค ๋กœํ…Œ์ด์…˜, ์ ‘๊ทผ ๋กœ๊น…, ์„ธ๋ฐ€ํ•œ ๊ถŒํ•œ ์ œ์–ด๊ฐ€ ๊ฐ€๋Šฅํ•ด!

4๏ธโƒฃ MFA Delete ํ™œ์„ฑํ™”

์ค‘์š”ํ•œ ๋ฒ„ํ‚ท์—๋Š” MFA Delete๋ฅผ ํ™œ์„ฑํ™”ํ•ด์„œ ์‹ค์ˆ˜๋‚˜ ์•…์˜์ ์ธ ์‚ญ์ œ๋ฅผ ๋ฐฉ์ง€ํ•ด:

aws s3api put-bucket-versioning \
  --bucket critical-bucket \
  --versioning-configuration Status=Enabled,MFADelete=Enabled \
  --mfa "arn:aws:iam::123456789012:mfa/root-account-mfa-device 123456"

์ฐธ๊ณ ๋กœ MFA Delete๋Š” ๋ฃจํŠธ ๊ณ„์ •์œผ๋กœ๋งŒ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์–ด. ๊ทธ๋งŒํผ ์ค‘์š”ํ•œ ์„ค์ •์ด๋ผ๋Š” ๋œป์ด์ง€!

5๏ธโƒฃ ์ •๊ธฐ์ ์ธ ์ ‘๊ทผ ๊ฒ€ํ† 

IAM Access Analyzer๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋ฒ„ํ‚ท์„ ์ •๊ธฐ์ ์œผ๋กœ ํ™•์ธํ•ด:

aws accessanalyzer create-analyzer \
  --analyzer-name s3-access-analyzer \
  --type ACCOUNT

Access Analyzer๋Š” ์ž๋™์œผ๋กœ ์™ธ๋ถ€ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ฐพ์•„๋‚ด๊ณ  ์•Œ๋ ค์ค˜. ์˜๋„ํ•˜์ง€ ์•Š์€ ๊ณต๊ฐœ๋ฅผ ๋น ๋ฅด๊ฒŒ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ์–ด! ๐Ÿ”

6๏ธโƒฃ VPC ์—”๋“œํฌ์ธํŠธ ์‚ฌ์šฉ

๊ฐ€๋Šฅํ•˜๋ฉด VPC ์—”๋“œํฌ์ธํŠธ๋ฅผ ํ†ตํ•ด S3์— ์ ‘๊ทผํ•ด. ์ธํ„ฐ๋„ท์„ ๊ฑฐ์น˜์ง€ ์•Š์•„์„œ ๋” ์•ˆ์ „ํ•˜๊ณ  ๋น ๋ฅด๊ฑฐ๋“ :

aws ec2 create-vpc-endpoint \
  --vpc-id vpc-12345678 \
  --service-name com.amazonaws.us-east-1.s3 \
  --route-table-ids rtb-12345678

๊ทธ๋ฆฌ๊ณ  ๋ฒ„ํ‚ท ์ •์ฑ…์—์„œ VPC ์—”๋“œํฌ์ธํŠธ๋ฅผ ํ†ตํ•œ ์ ‘๊ทผ๋งŒ ํ—ˆ์šฉ:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VPCEndpointOnly",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::my-bucket",
        "arn:aws:s3:::my-bucket/*"
      ],
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpce": "vpce-1234567"
        }
      }
    }
  ]
}

7๏ธโƒฃ ํƒœ๊ทธ ๊ธฐ๋ฐ˜ ์ ‘๊ทผ์ œ์–ด ํ™œ์šฉ

๋ฆฌ์†Œ์Šค์™€ ์‚ฌ์šฉ์ž์— ํƒœ๊ทธ๋ฅผ ๋ถ™์ด๊ณ , ํƒœ๊ทธ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ถŒํ•œ์„ ๊ด€๋ฆฌํ•˜๋ฉด ํ™•์žฅ์„ฑ์ด ์ข‹์•„:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "s3:ExistingObjectTag/Environment": "${aws:PrincipalTag/Environment}"
        }
      }
    }
  ]
}

๊ฐœ๋ฐœ ํ™˜๊ฒฝ ํƒœ๊ทธ๋ฅผ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž๋Š” ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ํƒœ๊ทธ๊ฐ€ ๋ถ™์€ ๊ฐ์ฒด๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด. ํ™˜๊ฒฝ ๋ถ„๋ฆฌ๊ฐ€ ์ž๋™์œผ๋กœ ์ด๋ฃจ์–ด์ง€๋Š” ๊ฑฐ์ง€!

8๏ธโƒฃ ๋ผ์ดํ”„์‚ฌ์ดํด ์ •์ฑ…์œผ๋กœ ์˜ค๋ž˜๋œ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ

์˜ค๋ž˜๋œ ๋ฒ„์ „์ด๋‚˜ ๋ถˆ์™„์ „ํ•œ ๋ฉ€ํ‹ฐํŒŒํŠธ ์—…๋กœ๋“œ๋ฅผ ์ž๋™์œผ๋กœ ์ •๋ฆฌํ•ด:

{
  "Rules": [
    {
      "Id": "DeleteOldVersions",
      "Status": "Enabled",
      "NoncurrentVersionExpiration": {
        "NoncurrentDays": 90
      }
    },
    {
      "Id": "CleanupIncompleteUploads",
      "Status": "Enabled",
      "AbortIncompleteMultipartUpload": {
        "DaysAfterInitiation": 7
      }
    }
  ]
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์Šคํ† ๋ฆฌ์ง€ ๋น„์šฉ๋„ ์ ˆ์•ฝํ•˜๊ณ , ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ๋…ธ์ถœ ์œ„ํ—˜๋„ ์ค„์ผ ์ˆ˜ ์žˆ์–ด!

9๏ธโƒฃ ์ •๊ธฐ์ ์ธ ๋ณด์•ˆ ๊ฐ์‚ฌ

AWS Config๋ฅผ ์‚ฌ์šฉํ•ด์„œ S3 ๋ฒ„ํ‚ท ์„ค์ •์„ ์ง€์†์ ์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋งํ•ด:

aws configservice put-config-rule \
  --config-rule '{
    "ConfigRuleName": "s3-bucket-public-read-prohibited",
    "Source": {
      "Owner": "AWS",
      "SourceIdentifier": "S3_BUCKET_PUBLIC_READ_PROHIBITED"
    }
  }'

AWS Config๋Š” ๊ทœ์ •์„ ์œ„๋ฐ˜ํ•˜๋Š” ๋ฒ„ํ‚ท์„ ์ž๋™์œผ๋กœ ์ฐพ์•„๋‚ด๊ณ , ํ•„์š”ํ•˜๋ฉด ์ž๋™ ์ˆ˜์ •(Auto Remediation)๋„ ๊ฐ€๋Šฅํ•ด!

๐Ÿ”Ÿ ์‚ฌ๊ณ  ๋Œ€์‘ ๊ณ„ํš ์ˆ˜๋ฆฝ

์•„๋ฌด๋ฆฌ ์™„๋ฒฝํ•œ ๋ณด์•ˆ ์„ค์ •์„ ํ•ด๋„ ์‚ฌ๊ณ ๋Š” ์ผ์–ด๋‚  ์ˆ˜ ์žˆ์–ด. ์‚ฌ๊ณ  ๋Œ€์‘ ๊ณ„ํš์„ ๋ฏธ๋ฆฌ ๋งŒ๋“ค์–ด๋‘์ž:

1. ํƒ์ง€: CloudWatch ์•Œ๋žŒ, GuardDuty ์•Œ๋ฆผ ์„ค์ •
2. ๊ฒฉ๋ฆฌ: ์˜์‹ฌ์Šค๋Ÿฌ์šด ์ ‘๊ทผ ์ฆ‰์‹œ ์ฐจ๋‹จํ•˜๋Š” Lambda ํ•จ์ˆ˜
3. ์กฐ์‚ฌ: CloudTrail ๋กœ๊ทธ ๋ถ„์„ ์ ˆ์ฐจ
4. ๋ณต๊ตฌ: ๋ฐฑ์—…์—์„œ ๋ณต์›ํ•˜๋Š” ๋ฐฉ๋ฒ•
5. ์‚ฌํ›„ ๋ถ„์„: ์žฌ๋ฐœ ๋ฐฉ์ง€ ๋Œ€์ฑ… ์ˆ˜๋ฆฝ

์ด๋Ÿฐ ๊ณ„ํš์ด ์žˆ์œผ๋ฉด ์‹ค์ œ ์‚ฌ๊ณ ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๋‹นํ™ฉํ•˜์ง€ ์•Š๊ณ  ์‹ ์†ํ•˜๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ์–ด! ๐Ÿšจ

โš ๏ธ ํ”ํ•œ ์‹ค์ˆ˜๋“ค 1. ์™€์ผ๋“œ์นด๋“œ ๋‚จ์šฉ: s3:*๋‚˜ Resource: "*"๋Š” ์ •๋ง ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ฉด ์‚ฌ์šฉํ•˜์ง€ ๋งˆ
2. ํ…Œ์ŠคํŠธ ์„ค์ • ๊ทธ๋Œ€๋กœ ์šด์˜: ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ํŽธ์˜๋ฅผ ์œ„ํ•ด ๋А์Šจํ•˜๊ฒŒ ์„ค์ •ํ•œ ๊ฑธ ์šด์˜์— ๊ทธ๋Œ€๋กœ ๊ฐ€์ ธ๊ฐ€๋ฉด ์•ˆ ๋ผ
3. ์ •์ฑ… ์—…๋ฐ์ดํŠธ ํ›„ ํ…Œ์ŠคํŠธ ์•ˆ ํ•จ: ์ •์ฑ…์„ ๋ณ€๊ฒฝํ•œ ํ›„์—๋Š” ๋ฐ˜๋“œ์‹œ ์˜๋„๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ด
4. ๋กœ๊ทธ ๋ชจ๋‹ˆํ„ฐ๋ง ์•ˆ ํ•จ: ๋กœ๊ทธ๋ฅผ ์Œ“๊ธฐ๋งŒ ํ•˜๊ณ  ํ™•์ธํ•˜์ง€ ์•Š์œผ๋ฉด ์˜๋ฏธ๊ฐ€ ์—†์–ด

๐Ÿ”ง ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ๊ฐ€์ด๋“œ

S3 ์ ‘๊ทผ์ œ์–ด๋ฅผ ์„ค์ •ํ•˜๋‹ค ๋ณด๋ฉด ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ œ๋“ค์ด ์ƒ๊ธฐ๊ณค ํ•ด. ์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋“ค๊ณผ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ •๋ฆฌํ•ด๋ดค์–ด! ๐Ÿ”จ

โŒ ๋ฌธ์ œ 1: "Access Denied" ์—๋Ÿฌ

๊ฐ€์žฅ ํ”ํ•œ ์—๋Ÿฌ์•ผ. ์—ฌ๋Ÿฌ ์›์ธ์ด ์žˆ์„ ์ˆ˜ ์žˆ์–ด:

์›์ธ 1: IAM ์ •์ฑ… ๋ถ€์กฑ
์‚ฌ์šฉ์ž๋‚˜ ์—ญํ• ์— ํ•„์š”ํ•œ ๊ถŒํ•œ์ด ์—†๋Š” ๊ฒฝ์šฐ์•ผ. IAM Policy Simulator๋กœ ํ™•์ธํ•ด๋ด:

aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:user/Alice \
  --action-names s3:GetObject \
  --resource-arns arn:aws:s3:::my-bucket/file.txt

์›์ธ 2: ๋ฒ„ํ‚ท ์ •์ฑ…์—์„œ ๋ช…์‹œ์  Deny
๋ฒ„ํ‚ท ์ •์ฑ…์— Deny ๋ฌธ์ด ์žˆ์œผ๋ฉด IAM ์ •์ฑ…์˜ Allow๋ณด๋‹ค ์šฐ์„ ํ•ด. ๋ฒ„ํ‚ท ์ •์ฑ…์„ ํ™•์ธํ•ด๋ด:

aws s3api get-bucket-policy --bucket my-bucket

์›์ธ 3: ๋ธ”๋ก ํผ๋ธ”๋ฆญ ์•ก์„ธ์Šค ์„ค์ •
ํผ๋ธ”๋ฆญ ์ ‘๊ทผ์ด ํ•„์š”ํ•œ๋ฐ ๋ธ”๋ก ์„ค์ •์ด ํ™œ์„ฑํ™”๋˜์–ด ์žˆ์„ ์ˆ˜ ์žˆ์–ด:

aws s3api get-public-access-block --bucket my-bucket

์›์ธ 4: ๊ฐ์ฒด ์†Œ์œ ๊ถŒ ๋ฌธ์ œ
๋‹ค๋ฅธ ๊ณ„์ •์ด ์—…๋กœ๋“œํ•œ ๊ฐ์ฒด๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์—…๋กœ๋”๊ฐ€ ์†Œ์œ ํ•ด. ๋ฒ„ํ‚ท ์†Œ์œ ์ž๊ฐ€ ์ ‘๊ทผํ•˜๋ ค๋ฉด ๊ฐ์ฒด ์†Œ์œ ๊ถŒ ์„ค์ •์„ ํ™•์ธํ•ด์•ผ ํ•ด:

aws s3api get-bucket-ownership-controls --bucket my-bucket

โŒ ๋ฌธ์ œ 2: CORS ์—๋Ÿฌ

์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ S3์— ์ง์ ‘ ์ ‘๊ทผํ•  ๋•Œ CORS ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด. CORS ์„ค์ •์„ ์ถ”๊ฐ€ํ•ด์ค˜์•ผ ํ•ด:

{
  "CORSRules": [
    {
      "AllowedOrigins": ["https://mywebsite.com"],
      "AllowedMethods": ["GET", "PUT", "POST"],
      "AllowedHeaders": ["*"],
      "ExposeHeaders": ["ETag"],
      "MaxAgeSeconds": 3000
    }
  ]
}
aws s3api put-bucket-cors \
  --bucket my-bucket \
  --cors-configuration file://cors.json

โŒ ๋ฌธ์ œ 3: ์ •์ฑ… ํฌ๊ธฐ ์ œํ•œ ์ดˆ๊ณผ

๋ฒ„ํ‚ท ์ •์ฑ…์€ 20KB๋กœ ์ œํ•œ๋ผ ์žˆ์–ด. ์ •์ฑ…์ด ๋„ˆ๋ฌด ์ปค์ง€๋ฉด:

ํ•ด๊ฒฐ์ฑ… 1: ์•ก์„ธ์Šค ํฌ์ธํŠธ ์‚ฌ์šฉ
๋ณต์žกํ•œ ์ •์ฑ…์„ ์—ฌ๋Ÿฌ ์•ก์„ธ์Šค ํฌ์ธํŠธ๋กœ ๋ถ„์‚ฐ์‹œ์ผœ.

ํ•ด๊ฒฐ์ฑ… 2: IAM ์ •์ฑ…์œผ๋กœ ์ด๋™
๊ฐ€๋Šฅํ•˜๋ฉด IAM ์ •์ฑ…์œผ๋กœ ๊ถŒํ•œ์„ ๊ด€๋ฆฌํ•˜๊ณ , ๋ฒ„ํ‚ท ์ •์ฑ…์€ ํฌ๋กœ์Šค ๊ณ„์ • ์ ‘๊ทผ ๊ฐ™์€ ํ•„์ˆ˜ ์‚ฌํ•ญ๋งŒ ์ฒ˜๋ฆฌํ•ด.

ํ•ด๊ฒฐ์ฑ… 3: ์ •์ฑ… ์ตœ์ ํ™”
์™€์ผ๋“œ์นด๋“œ๋ฅผ ํ™œ์šฉํ•ด์„œ ์—ฌ๋Ÿฌ ๊ทœ์น™์„ ํ•˜๋‚˜๋กœ ํ•ฉ์ณ:

// ๋น„ํšจ์œจ์ 
"Resource": [
  "arn:aws:s3:::my-bucket/folder1/*",
  "arn:aws:s3:::my-bucket/folder2/*",
  "arn:aws:s3:::my-bucket/folder3/*"
]

// ํšจ์œจ์ 
"Resource": "arn:aws:s3:::my-bucket/folder*/*"

โŒ ๋ฌธ์ œ 4: ํฌ๋กœ์Šค ๊ณ„์ • ์ ‘๊ทผ ์•ˆ ๋จ

ํฌ๋กœ์Šค ๊ณ„์ • ์ ‘๊ทผ์„ ์„ค์ •ํ–ˆ๋Š”๋ฐ ์•ˆ ๋˜๋Š” ๊ฒฝ์šฐ:

์ฒดํฌ๋ฆฌ์ŠคํŠธ:
1. ๋ฒ„ํ‚ท ์ •์ฑ…์—์„œ ๋‹ค๋ฅธ ๊ณ„์ • Principal ํ—ˆ์šฉํ–ˆ๋‚˜?
2. ๋‹ค๋ฅธ ๊ณ„์ •์˜ IAM ์ •์ฑ…์—์„œ ๋ฒ„ํ‚ท ์ ‘๊ทผ ํ—ˆ์šฉํ–ˆ๋‚˜?
3. ๊ฐ์ฒด ACL์ด ๋ฒ„ํ‚ท ์†Œ์œ ์ž์—๊ฒŒ ๊ถŒํ•œ์„ ์ฃผ๊ณ  ์žˆ๋‚˜?
4. ๋ธ”๋ก ํผ๋ธ”๋ฆญ ์•ก์„ธ์Šค๊ฐ€ ํฌ๋กœ์Šค ๊ณ„์ • ์ ‘๊ทผ์„ ๋ง‰๊ณ  ์žˆ์ง€ ์•Š๋‚˜?

ํŠนํžˆ ๊ฐ์ฒด ์†Œ์œ ๊ถŒ ๋ฌธ์ œ๊ฐ€ ๋งŽ์•„. ์—…๋กœ๋“œํ•  ๋•Œ --acl bucket-owner-full-control ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•˜๋ฉด ํ•ด๊ฒฐ๋ผ:

aws s3 cp file.txt s3://shared-bucket/ \
  --acl bucket-owner-full-control

โŒ ๋ฌธ์ œ 5: ์•”ํ˜ธํ™” ๊ด€๋ จ ์—๋Ÿฌ

KMS ์•”ํ˜ธํ™”๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๊ถŒํ•œ ๋ฌธ์ œ๊ฐ€ ์ž์ฃผ ๋ฐœ์ƒํ•ด:

์›์ธ: KMS ํ‚ค ์ •์ฑ…์— ๊ถŒํ•œ ์—†์Œ
S3 ๋ฒ„ํ‚ท ์ ‘๊ทผ ๊ถŒํ•œ๋งŒ ์žˆ๊ณ  KMS ํ‚ค ์‚ฌ์šฉ ๊ถŒํ•œ์ด ์—†์œผ๋ฉด ์•”ํ˜ธํ™”๋œ ๊ฐ์ฒด๋ฅผ ์ฝ์„ ์ˆ˜ ์—†์–ด. KMS ํ‚ค ์ •์ฑ…์„ ํ™•์ธํ•ด๋ด:

aws kms get-key-policy \
  --key-id 1234abcd-12ab-34cd-56ef-1234567890ab \
  --policy-name default

ํ•„์š”ํ•œ ๊ถŒํ•œ์„ ์ถ”๊ฐ€ํ•ด์ค˜:

{
  "Sid": "Allow use of the key for S3",
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::123456789012:role/MyRole"
  },
  "Action": [
    "kms:Decrypt",
    "kms:DescribeKey"
  ],
  "Resource": "*"
}

๐Ÿ” ๋””๋ฒ„๊น… ํŒ

๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๋•Œ ์ด๋Ÿฐ ์ˆœ์„œ๋กœ ์ ‘๊ทผํ•˜๋ฉด ํšจ์œจ์ ์ด์•ผ:

1. CloudTrail ๋กœ๊ทธ ํ™•์ธ: ์ •ํ™•ํžˆ ์–ด๋–ค API ํ˜ธ์ถœ์ด ์‹คํŒจํ–ˆ๋Š”์ง€ ํ™•์ธ
2. ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋ถ„์„: AWS ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋Š” ์ƒ๊ฐ๋ณด๋‹ค ์นœ์ ˆํ•ด. ์ž์„ธํžˆ ์ฝ์–ด๋ด
3. IAM Policy Simulator ์‚ฌ์šฉ: ์ •์ฑ…์ด ์˜๋„๋Œ€๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ์‹œ๋ฎฌ๋ ˆ์ด์…˜
4. ๋‹จ๊ณ„๋ณ„ ํ…Œ์ŠคํŠธ: ๋ณต์žกํ•œ ์ •์ฑ…์€ ๋‹จ์ˆœํ•œ ๋ฒ„์ „๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ ์ ์ง„์ ์œผ๋กœ ์ถ”๊ฐ€
5. AWS ๋ฌธ์„œ ์ฐธ์กฐ: AWS ๊ณต์‹ ๋ฌธ์„œ๋Š” ์ •๋ง ์ž˜ ๋˜์–ด ์žˆ์–ด. ์˜์‹ฌ์Šค๋Ÿฌ์šฐ๋ฉด ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•ด๋ด

ํŠนํžˆ CloudTrail ๋กœ๊ทธ๋Š” ์ •๋ง ์œ ์šฉํ•ด. ์‹คํŒจํ•œ API ํ˜ธ์ถœ์˜ ์ •ํ™•ํ•œ ์›์ธ์„ ์•Œ๋ ค์ฃผ๊ฑฐ๋“ :

aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=GetObject \
  --max-results 10
๐Ÿ’ก ํ”„๋กœ ํŒ ๋ณต์žกํ•œ ๊ถŒํ•œ ๋ฌธ์ œ๋ฅผ ๋””๋ฒ„๊น…ํ•  ๋•Œ๋Š” AWS CLI์— --debug ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•˜๋ฉด ์ƒ์„ธํ•œ ๋กœ๊ทธ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์–ด:
aws s3 ls s3://my-bucket --debug
HTTP ์š”์ฒญ/์‘๋‹ต, ์„œ๋ช… ๊ณผ์ • ๋“ฑ์„ ๋ชจ๋‘ ๋ณผ ์ˆ˜ ์žˆ์–ด์„œ ๋ฌธ์ œ ์›์ธ์„ ์ฐพ๊ธฐ ์‰ฌ์›Œ!

๐Ÿš€ ๊ณ ๊ธ‰ ์ฃผ์ œ์™€ ์ตœ์‹  ๊ธฐ๋Šฅ

๊ธฐ๋ณธ์„ ๋งˆ์Šคํ„ฐํ–ˆ๋‹ค๋ฉด, ์ด์ œ ์ข€ ๋” ๊ณ ๊ธ‰ ์ฃผ์ œ๋“ค์„ ์‚ดํŽด๋ณผ ์ฐจ๋ก€์•ผ! AWS๋Š” ๊ณ„์† ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•˜๊ณ  ์žˆ๊ฑฐ๋“ . ๐ŸŒŸ

๐ŸŽฏ S3 Object Lambda

2021๋…„์— ์ถœ์‹œ๋œ S3 Object Lambda๋Š” ์ •๋ง ํ˜์‹ ์ ์ธ ๊ธฐ๋Šฅ์ด์•ผ. ๊ฐ์ฒด๋ฅผ ์ฝ์„ ๋•Œ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์–ด!

์˜ˆ๋ฅผ ๋“ค์–ด:
- ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ์ž๋™์œผ๋กœ ๋งˆ์Šคํ‚น
- ์ด๋ฏธ์ง€ ํฌ๊ธฐ๋ฅผ ์š”์ฒญ์ž์— ๋งž๊ฒŒ ์กฐ์ •
- ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฅธ ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜
- ์›Œํ„ฐ๋งˆํฌ ์ถ”๊ฐ€

์„ค์ • ๋ฐฉ๋ฒ•:

// 1. Lambda ํ•จ์ˆ˜ ์ƒ์„ฑ
exports.handler = async (event) => {
  const { getObjectContext, userRequest } = event;
  const { outputRoute, outputToken, inputS3Url } = getObjectContext;
  
  // ์›๋ณธ ๊ฐ์ฒด ๊ฐ€์ ธ์˜ค๊ธฐ
  const response = await fetch(inputS3Url);
  let data = await response.text();
  
  // ๋ฏผ๊ฐํ•œ ์ •๋ณด ๋งˆ์Šคํ‚น
  data = data.replace(/\d{3}-\d{2}-\d{4}/g, 'XXX-XX-XXXX');
  
  // ๋ณ€ํ™˜๋œ ๋ฐ์ดํ„ฐ ๋ฐ˜ํ™˜
  await s3.writeGetObjectResponse({
    RequestRoute: outputRoute,
    RequestToken: outputToken,
    Body: data
  });
  
  return { statusCode: 200 };
};

// 2. Object Lambda Access Point ์ƒ์„ฑ
aws s3control create-access-point-for-object-lambda \
  --account-id 123456789012 \
  --name my-object-lambda-ap \
  --configuration '{
    "SupportingAccessPoint": "arn:aws:s3:us-east-1:123456789012:accesspoint/my-ap",
    "TransformationConfigurations": [{
      "Actions": ["GetObject"],
      "ContentTransformation": {
        "AwsLambda": {
          "FunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:MyTransformFunction"
        }
      }
    }]
  }'

์ด์ œ Object Lambda Access Point๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ์ฝ์œผ๋ฉด ์ž๋™์œผ๋กœ Lambda ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๊ณ , ๋ณ€ํ™˜๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๊ฒŒ ๋ผ. ์›๋ณธ ๋ฐ์ดํ„ฐ๋Š” ๊ทธ๋Œ€๋กœ ์œ ์ง€๋˜๋ฉด์„œ ๋ง์ด์•ผ! ๐ŸŽจ

๐Ÿ” S3 Access Grants

2023๋…„์— ์ถœ์‹œ๋œ S3 Access Grants๋Š” IAM ์ •์ฑ… ์—†์ด๋„ S3 ์ ‘๊ทผ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค˜. ํŠนํžˆ ๋Œ€๊ทœ๋ชจ ์กฐ์ง์—์„œ ์œ ์šฉํ•ด.

๊ธฐ์กด ๋ฐฉ์‹์˜ ๋ฌธ์ œ์ :
- IAM ์ •์ฑ…์ด ๋„ˆ๋ฌด ๋ณต์žกํ•ด์ง
- ์‚ฌ์šฉ์ž๋งˆ๋‹ค ๊ฐœ๋ณ„ ์ •์ฑ… ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์›€
- ๊ถŒํ•œ ๋ณ€๊ฒฝ์ด ๋А๋ฆผ

Access Grants์˜ ์žฅ์ :
- Active Directory๋‚˜ Okta ๊ฐ™์€ IdP์™€ ์ง์ ‘ ์—ฐ๋™
- ์„ธ์…˜ ๊ธฐ๋ฐ˜ ์ž„์‹œ ์ž๊ฒฉ์ฆ๋ช… ์ž๋™ ๋ฐœ๊ธ‰
- ๋” ์„ธ๋ฐ€ํ•œ ๊ถŒํ•œ ์ œ์–ด

์„ค์ • ์˜ˆ์‹œ:

// 1. Access Grants ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
aws s3control create-access-grants-instance \
  --account-id 123456789012 \
  --identity-center-arn arn:aws:sso:::instance/ssoins-1234567890abcdef

// 2. ์œ„์น˜ ๋“ฑ๋ก
aws s3control create-access-grants-location \
  --account-id 123456789012 \
  --location-scope s3://my-bucket/data/* \
  --iam-role-arn arn:aws:iam::123456789012:role/S3AccessGrantsRole

// 3. ๊ถŒํ•œ ๋ถ€์—ฌ
aws s3control create-access-grant \
  --account-id 123456789012 \
  --access-grants-location-id default \
  --grantee '{
    "GranteeType": "IAM",
    "GranteeIdentifier": "arn:aws:iam::123456789012:user/Alice"
  }' \
  --permission READ \
  --access-grants-location-configuration '{
    "S3SubPrefix": "project-a/*"
  }'

์ด์ œ Alice๋Š” ์ž๋™์œผ๋กœ project-a ํด๋”์— ๋Œ€ํ•œ ์ž„์‹œ ์ž๊ฒฉ์ฆ๋ช…์„ ๋ฐ›์•„์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด. IAM ์ •์ฑ…์„ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†์ง€! ๐ŸŽ‰

๐ŸŒ S3 Express One Zone

2023๋…„ ๋ง์— ์ถœ์‹œ๋œ S3 Express One Zone์€ ์ดˆ๊ณ ์„ฑ๋Šฅ ์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค์•ผ. ์ผ๋ฐ˜ S3๋ณด๋‹ค 10๋ฐฐ ๋น ๋ฅธ ์„ฑ๋Šฅ์„ ์ œ๊ณตํ•ด!

ํŠน์ง•:
- ํ•œ ์ž๋ฆฌ ์ˆ˜ ๋ฐ€๋ฆฌ์ดˆ ๋ ˆ์ดํ„ด์‹œ
- ์ดˆ๋‹น ์ˆ˜์‹ญ๋งŒ ์š”์ฒญ ์ฒ˜๋ฆฌ
- ๋‹จ์ผ ๊ฐ€์šฉ ์˜์—ญ์— ์ €์žฅ
- ๋””๋ ‰ํ† ๋ฆฌ ๋ฒ„ํ‚ท ์‚ฌ์šฉ

์ ‘๊ทผ์ œ์–ด ์ธก๋ฉด์—์„œ ์ฃผ๋ชฉํ•  ์ :

// Express One Zone์€ ์„ธ์…˜ ๊ธฐ๋ฐ˜ ์ธ์ฆ ์‚ฌ์šฉ
aws s3express create-session \
  --bucket my-express-bucket--use1-az1--x-s3

// ์„ธ์…˜ ์ž๊ฒฉ์ฆ๋ช…์œผ๋กœ ์ ‘๊ทผ
aws s3 cp file.txt s3://my-express-bucket--use1-az1--x-s3/ \
  --session-token <session-token>

์ผ๋ฐ˜ S3์™€ ๋‹ค๋ฅด๊ฒŒ ์„ธ์…˜ ๊ธฐ๋ฐ˜ ์ธ์ฆ์„ ์‚ฌ์šฉํ•ด์„œ ์„ฑ๋Šฅ์„ ๊ทน๋Œ€ํ™”ํ–ˆ์–ด. ๊ณ ์„ฑ๋Šฅ์ด ํ•„์š”ํ•œ ML ํ•™์Šต์ด๋‚˜ ์‹ค์‹œ๊ฐ„ ๋ถ„์„์— ์™„๋ฒฝํ•ด! โšก

๐Ÿ”’ S3 Bucket Keys

KMS ์•”ํ˜ธํ™”๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋น„์šฉ์„ ํฌ๊ฒŒ ์ค„์—ฌ์ฃผ๋Š” ๊ธฐ๋Šฅ์ด์•ผ. ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐ์ฒด๋งˆ๋‹ค KMS API๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๋ฐ, Bucket Keys๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฒ„ํ‚ท ๋ ˆ๋ฒจ์—์„œ ํ‚ค๋ฅผ ์ƒ์„ฑํ•ด์„œ ์žฌ์‚ฌ์šฉํ•ด.

๋น„์šฉ ์ ˆ๊ฐ ํšจ๊ณผ:
- KMS API ํ˜ธ์ถœ 99% ๊ฐ์†Œ
- ์•”ํ˜ธํ™” ๋น„์šฉ ๋Œ€ํญ ์ ˆ๊ฐ
- ์„ฑ๋Šฅ๋„ ํ–ฅ์ƒ

ํ™œ์„ฑํ™” ๋ฐฉ๋ฒ•:

aws s3api put-bucket-encryption \
  --bucket my-bucket \
  --server-side-encryption-configuration '{
    "Rules": [{
      "ApplyServerSideEncryptionByDefault": {
        "SSEAlgorithm": "aws:kms",
        "KMSMasterKeyID": "arn:aws:kms:us-east-1:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab"
      },
      "BucketKeyEnabled": true
    }]
  }'

๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฒฝ์šฐ Bucket Keys๋Š” ํ•„์ˆ˜์•ผ. ๋น„์šฉ๊ณผ ์„ฑ๋Šฅ ๋ชจ๋‘ ๊ฐœ์„ ๋˜๊ฑฐ๋“ ! ๐Ÿ’ฐ

๐Ÿ“Š S3 Storage Lens

Storage Lens๋Š” S3 ์‚ฌ์šฉ ํ˜„ํ™ฉ์„ ์‹œ๊ฐํ™”ํ•˜๊ณ  ์ตœ์ ํ™” ๊ถŒ์žฅ์‚ฌํ•ญ์„ ์ œ๊ณตํ•ด. ์ ‘๊ทผ์ œ์–ด ๊ด€์ ์—์„œ๋„ ์œ ์šฉํ•œ ์ธ์‚ฌ์ดํŠธ๋ฅผ ์ค˜:

- ํผ๋ธ”๋ฆญ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋ฒ„ํ‚ท ์‹๋ณ„
- ์•”ํ˜ธํ™”๋˜์ง€ ์•Š์€ ๊ฐ์ฒด ์ฐพ๊ธฐ
- ์˜ค๋ž˜๋œ ๋ฒ„์ „ ์ •๋ฆฌ ๊ถŒ์žฅ
- ๋น„์šฉ ์ตœ์ ํ™” ๊ธฐํšŒ ๋ฐœ๊ฒฌ

๊ณ ๊ธ‰ ๋ฉ”ํŠธ๋ฆญ์„ ํ™œ์„ฑํ™”ํ•˜๋ฉด ๋” ์ƒ์„ธํ•œ ์ •๋ณด๋ฅผ ๋ณผ ์ˆ˜ ์žˆ์–ด:

aws s3control put-storage-lens-configuration \
  --account-id 123456789012 \
  --config-id advanced-metrics-config \
  --storage-lens-configuration '{
    "Id": "advanced-metrics-config",
    "AccountLevel": {
      "BucketLevel": {
        "ActivityMetrics": {
          "IsEnabled": true
        },
        "AdvancedCostOptimizationMetrics": {
          "IsEnabled": true
        },
        "AdvancedDataProtectionMetrics": {
          "IsEnabled": true
        }
      }
    },
    "IsEnabled": true
  }'

Storage Lens ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ์ •๊ธฐ์ ์œผ๋กœ ํ™•์ธํ•˜๋ฉด ๋ณด์•ˆ ์ทจ์•ฝ์ ์„ ์กฐ๊ธฐ์— ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ์–ด! ๐Ÿ“ˆ

๐Ÿค– AI/ML๊ณผ S3 ์ ‘๊ทผ์ œ์–ด

์š”์ฆ˜ AI/ML ์›Œํฌ๋กœ๋“œ๊ฐ€ ๋งŽ์•„์ง€๋ฉด์„œ S3 ์ ‘๊ทผ ํŒจํ„ด๋„ ๋ณ€ํ•˜๊ณ  ์žˆ์–ด. ๋ช‡ ๊ฐ€์ง€ ๊ณ ๋ ค์‚ฌํ•ญ:

1. SageMaker์™€ S3 ํ†ตํ•ฉ
SageMaker๋Š” S3์—์„œ ํ•™์Šต ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ๊ณ  ๋ชจ๋ธ์„ ์ €์žฅํ•ด. ์ ์ ˆํ•œ ๊ถŒํ•œ ์„ค์ •์ด ์ค‘์š”ํ•ด:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::sagemaker-training-data/*",
        "arn:aws:s3:::sagemaker-models/*"
      ]
    }
  ]
}

2. ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ์…‹ ์ ‘๊ทผ ์ตœ์ ํ™”
ML ํ•™์Šต์€ ์ˆ˜๋ฐฑ GB~TB์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด. S3 Select๋‚˜ S3 Object Lambda๋ฅผ ํ™œ์šฉํ•˜๋ฉด ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์–ด:

aws s3api select-object-content \
  --bucket training-data \
  --key dataset.csv \
  --expression "SELECT * FROM S3Object WHERE category = 'positive'" \
  --expression-type SQL \
  --input-serialization '{"CSV": {"FileHeaderInfo": "USE"}}' \
  --output-serialization '{"CSV": {}}' \
  output.csv

3. ๋ชจ๋ธ ์•„ํ‹ฐํŒฉํŠธ ๋ณดํ˜ธ
ํ•™์Šต๋œ ๋ชจ๋ธ์€ ์ค‘์š”ํ•œ ์ž์‚ฐ์ด์•ผ. Object Lock์œผ๋กœ ๋ณดํ˜ธํ•˜๊ณ , ๋ฒ„์ „ ๊ด€๋ฆฌ๋ฅผ ํ™œ์„ฑํ™”ํ•ด์„œ ๋ชจ๋ธ ๋ณ€๊ฒฝ ์ด๋ ฅ์„ ์ถ”์ ํ•ด์•ผ ํ•ด.


๐Ÿ’ผ ๋น„์šฉ ์ตœ์ ํ™” ์ „๋žต

S3 ์ ‘๊ทผ์ œ์–ด๋ฅผ ์„ค์ •ํ•˜๋ฉด์„œ ๋น„์šฉ๋„ ํ•จ๊ป˜ ๊ณ ๋ คํ•ด์•ผ ํ•ด. ๋ณด์•ˆ๊ณผ ๋น„์šฉ, ๋‘ ๋งˆ๋ฆฌ ํ† ๋ผ๋ฅผ ๋‹ค ์žก๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค์ค„๊ฒŒ! ๐Ÿ’ฐ

๐Ÿ“‰ ์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค ์ตœ์ ํ™”

์ ‘๊ทผ ๋นˆ๋„์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ์Šคํ† ๋ฆฌ์ง€ ํด๋ž˜์Šค๋ฅผ ์„ ํƒํ•˜๋ฉด ๋น„์šฉ์„ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์–ด:

- S3 Standard: ์ž์ฃผ ์ ‘๊ทผํ•˜๋Š” ๋ฐ์ดํ„ฐ (๊ฐ€์žฅ ๋น„์Œˆ)
- S3 Intelligent-Tiering: ์ ‘๊ทผ ํŒจํ„ด์ด ๋ณ€ํ•˜๋Š” ๋ฐ์ดํ„ฐ (์ž๋™ ์ตœ์ ํ™”)
- S3 Standard-IA: ๊ฐ€๋” ์ ‘๊ทผํ•˜๋Š” ๋ฐ์ดํ„ฐ
- S3 One Zone-IA: ์ค‘์š”ํ•˜์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ
- S3 Glacier: ์•„์นด์ด๋ธŒ ๋ฐ์ดํ„ฐ
- S3 Glacier Deep Archive: ์žฅ๊ธฐ ๋ณด๊ด€ ๋ฐ์ดํ„ฐ (๊ฐ€์žฅ ์ €๋ ด)

๋ผ์ดํ”„์‚ฌ์ดํด ์ •์ฑ…์œผ๋กœ ์ž๋™ ์ „ํ™˜:

{
  "Rules": [
    {
      "Id": "MoveToIA",
      "Status": "Enabled",
      "Transitions": [
        {
          "Days": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 90,
          "StorageClass": "GLACIER"
        }
      ]
    }
  ]
}

์ ‘๊ทผ์ œ์–ด ๊ด€์ ์—์„œ ์ฃผ์˜ํ•  ์ : Glacier์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์›ํ•  ๋•Œ๋Š” ์ถ”๊ฐ€ ๊ถŒํ•œ์ด ํ•„์š”ํ•ด:

{
  "Effect": "Allow",
  "Action": [
    "s3:RestoreObject",
    "s3:GetObject"
  ],
  "Resource": "arn:aws:s3:::archive-bucket/*"
}

๐Ÿ”„ ์ค‘๋ณต ์ œ๊ฑฐ์™€ ์••์ถ•

S3๋Š” ์ž๋™ ์ค‘๋ณต ์ œ๊ฑฐ๋ฅผ ํ•˜์ง€ ์•Š์•„. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ ˆ๋ฒจ์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•ด:

1. ์—…๋กœ๋“œ ์ „ ์ค‘๋ณต ์ฒดํฌ: ๊ฐ์ฒด์˜ MD5 ํ•ด์‹œ๋ฅผ ๊ณ„์‚ฐํ•˜๊ณ , ์ด๋ฏธ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธ
2. ์••์ถ•: ํ…์ŠคํŠธ ํŒŒ์ผ์€ gzip์œผ๋กœ ์••์ถ•ํ•˜๋ฉด 70-90% ์šฉ๋Ÿ‰ ์ ˆ๊ฐ
3. Delta ์—…๋กœ๋“œ: ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„๋งŒ ์—…๋กœ๋“œ

Lambda ํ•จ์ˆ˜๋กœ ์ž๋™ํ™”ํ•  ์ˆ˜ ์žˆ์–ด:

exports.handler = async (event) => {
  const s3 = new AWS.S3();
  const bucket = event.Records[0].s3.bucket.name;
  const key = event.Records[0].s3.object.key;
  
  // ๊ฐ์ฒด ๋‹ค์šด๋กœ๋“œ
  const object = await s3.getObject({ Bucket: bucket, Key: key }).promise();
  
  // ์••์ถ•
  const compressed = zlib.gzipSync(object.Body);
  
  // ์••์ถ•๋œ ๋ฒ„์ „ ์—…๋กœ๋“œ
  await s3.putObject({
    Bucket: bucket,
    Key: key + '.gz',
    Body: compressed,
    ContentEncoding: 'gzip'
  }).promise();
  
  // ์›๋ณธ ์‚ญ์ œ (์„ ํƒ์‚ฌํ•ญ)
  await s3.deleteObject({ Bucket: bucket, Key: key }).promise();
};

๐Ÿ“Š ์š”์ฒญ ๋น„์šฉ ์ตœ์ ํ™”

S3๋Š” ์š”์ฒญ ํšŸ์ˆ˜์— ๋”ฐ๋ผ์„œ๋„ ๊ณผ๊ธˆ๋ผ. ํŠนํžˆ LIST ์š”์ฒญ์ด ๋น„์‹ธ:

์ตœ์ ํ™” ํŒ:
1. ๋ฐฐ์น˜ ์ฒ˜๋ฆฌ: ์—ฌ๋Ÿฌ ๊ฐ์ฒด๋ฅผ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌ
2. S3 Inventory ์‚ฌ์šฉ: LIST ๋Œ€์‹  Inventory ๋ฆฌํฌํŠธ ํ™œ์šฉ
3. ์บ์‹ฑ: CloudFront๋‚˜ ElastiCache๋กœ ์ž์ฃผ ์ ‘๊ทผํ•˜๋Š” ๋ฐ์ดํ„ฐ ์บ์‹ฑ
4. S3 Select ํ™œ์šฉ: ์ „์ฒด ๊ฐ์ฒด ๋Œ€์‹  ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ ๊ฐ€์ ธ์˜ค๊ธฐ

S3 Inventory ์„ค์ •:

aws s3api put-bucket-inventory-configuration \
  --bucket my-bucket \
  --id daily-inventory \
  --inventory-configuration '{
    "Destination": {
      "S3BucketDestination": {
        "Bucket": "arn:aws:s3:::inventory-bucket",
        "Format": "Parquet"
      }
    },
    "IsEnabled": true,
    "Id": "daily-inventory",
    "IncludedObjectVersions": "Current",
    "Schedule": {
      "Frequency": "Daily"
    }
  }'

Inventory๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด LIST API๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ ๋„ ๋ฒ„ํ‚ท ๋‚ด์šฉ์„ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์–ด. ๋น„์šฉ์ด ํฌ๊ฒŒ ์ ˆ๊ฐ๋ผ! ๐Ÿ“‰

๐ŸŒ ๋ฐ์ดํ„ฐ ์ „์†ก ๋น„์šฉ ์ ˆ๊ฐ

AWS์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด๋ณด๋‚ผ ๋•Œ(egress) ๋น„์šฉ์ด ๋ฐœ์ƒํ•ด. ์ด๋ฅผ ์ค„์ด๋Š” ๋ฐฉ๋ฒ•:

1. CloudFront ์‚ฌ์šฉ: CloudFront๋ฅผ ํ†ตํ•œ ์ „์†ก์ด ์ง์ ‘ S3๋ณด๋‹ค ์ €๋ ดํ•  ์ˆ˜ ์žˆ์–ด
2. ๋ฆฌ์ „ ์„ ํƒ: ์‚ฌ์šฉ์ž์™€ ๊ฐ€๊นŒ์šด ๋ฆฌ์ „ ์‚ฌ์šฉ
3. VPC ์—”๋“œํฌ์ธํŠธ: ๊ฐ™์€ ๋ฆฌ์ „ ๋‚ด ์ „์†ก์€ ๋ฌด๋ฃŒ
4. S3 Transfer Acceleration: ์žฅ๊ฑฐ๋ฆฌ ์ „์†ก ์ตœ์ ํ™”

VPC ์—”๋“œํฌ์ธํŠธ ์ •์ฑ…์œผ๋กœ ๋น„์šฉ ์ œ์–ด:

{
  "Statement": [
    {
      "Sid": "RestrictToVPCEndpoint",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::my-bucket",
        "arn:aws:s3:::my-bucket/*"
      ],
      "Condition": {
        "StringNotEquals": {
          "aws:SourceVpce": "vpce-1234567"
        }
      }
    }
  ]
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด VPC ์—”๋“œํฌ์ธํŠธ๋ฅผ ํ†ตํ•œ ์ ‘๊ทผ๋งŒ ํ—ˆ์šฉํ•ด์„œ ๋ฐ์ดํ„ฐ ์ „์†ก ๋น„์šฉ์„ ์ œ๋กœ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด! ๐ŸŽฏ

๐Ÿ’ก ๋น„์šฉ ๋ชจ๋‹ˆํ„ฐ๋ง

AWS Cost Explorer์™€ S3 Storage Lens๋ฅผ ํ™œ์šฉํ•ด์„œ ๋น„์šฉ์„ ์ง€์†์ ์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋งํ•ด:

๋น„์šฉ ์•Œ๋žŒ ์„ค์ •:

aws cloudwatch put-metric-alarm \
  --alarm-name s3-cost-alarm \
  --alarm-description "Alert when S3 cost exceeds threshold" \
  --metric-name EstimatedCharges \
  --namespace AWS/Billing \
  --statistic Maximum \
  --period 21600 \
  --evaluation-periods 1 \
  --threshold 1000 \
  --comparison-operator GreaterThanThreshold \
  --dimensions Name=ServiceName,Value=AmazonS3

๋น„์šฉ ์ด์ƒ ํƒ์ง€:
AWS Cost Anomaly Detection์„ ํ™œ์„ฑํ™”ํ•˜๋ฉด ๋น„์ •์ƒ์ ์ธ ๋น„์šฉ ์ฆ๊ฐ€๋ฅผ ์ž๋™์œผ๋กœ ๊ฐ์ง€ํ•˜๊ณ  ์•Œ๋ ค์ค˜. ์‹ค์ˆ˜๋กœ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋กœ๋“œํ•˜๊ฑฐ๋‚˜, ๊ณต๊ฒฉ์„ ๋ฐ›๋Š” ๊ฒฝ์šฐ๋ฅผ ๋น ๋ฅด๊ฒŒ ๋ฐœ๊ฒฌํ•  ์ˆ˜ ์žˆ์–ด!

๐Ÿ’ฐ ์‹ค์ „ ๋น„์šฉ ์ ˆ๊ฐ ์‚ฌ๋ก€ ํ•œ ์Šคํƒ€ํŠธ์—…์ด S3 ๋น„์šฉ์„ ์›” $50,000์—์„œ $8,000์œผ๋กœ ์ค„์ธ ๋ฐฉ๋ฒ•:
1. Intelligent-Tiering์œผ๋กœ ์ž๋™ ์ตœ์ ํ™” (40% ์ ˆ๊ฐ)
2. ์˜ค๋ž˜๋œ ๋ฒ„์ „ ์ž๋™ ์‚ญ์ œ (20% ์ ˆ๊ฐ)
3. CloudFront ์บ์‹ฑ ๊ฐ•ํ™” (15% ์ ˆ๊ฐ)
4. ๋ถˆํ•„์š”ํ•œ ๋กœ๊ทธ ์ •๋ฆฌ (9% ์ ˆ๊ฐ)

์ž‘์€ ์ตœ์ ํ™”๋“ค์ด ๋ชจ์—ฌ์„œ ํฐ ํšจ๊ณผ๋ฅผ ๋งŒ๋“ค์–ด๋‚ธ ๊ฑฐ์•ผ!

๐ŸŽ“ ํ•™์Šต ๋ฆฌ์†Œ์Šค์™€ ๋‹ค์Œ ๋‹จ๊ณ„

์—ฌ๊ธฐ๊นŒ์ง€ S3 ์ ‘๊ทผ์ œ์–ด์— ๋Œ€ํ•ด ์ •๋ง ๋งŽ์€ ๊ฑธ ๋ฐฐ์› ์–ด! ํ•˜์ง€๋งŒ ํด๋ผ์šฐ๋“œ ๊ธฐ์ˆ ์€ ๊ณ„์† ๋ฐœ์ „ํ•˜๊ณ  ์žˆ์–ด. ์ง€์†์ ์œผ๋กœ ํ•™์Šตํ•˜๋Š” ๊ฒŒ ์ค‘์š”ํ•ด. ๐Ÿ“š

๐Ÿ“– ์ถ”์ฒœ ํ•™์Šต ์ž๋ฃŒ

๊ณต์‹ ๋ฌธ์„œ:
- AWS S3 User Guide: ๊ฐ€์žฅ ์ •ํ™•ํ•˜๊ณ  ์ตœ์‹  ์ •๋ณด
- AWS Security Best Practices: ๋ณด์•ˆ ๊ถŒ์žฅ์‚ฌํ•ญ
- AWS Well-Architected Framework: ์•„ํ‚คํ…์ฒ˜ ์„ค๊ณ„ ์›์น™

์˜จ๋ผ์ธ ๊ฐ•์˜:
- AWS Skill Builder: AWS ๊ณต์‹ ๋ฌด๋ฃŒ ๊ต์œก
- A Cloud Guru: ์‹ค์Šต ์ค‘์‹ฌ ๊ฐ•์˜
- Udemy: ๋‹ค์–‘ํ•œ ํ•œ๊ธ€ ๊ฐ•์˜

์ž๊ฒฉ์ฆ:
- AWS Certified Solutions Architect: S3 ํฌํ•จ ์ „๋ฐ˜์ ์ธ AWS ์ง€์‹
- AWS Certified Security - Specialty: ๋ณด์•ˆ ์ „๋ฌธ ์ž๊ฒฉ์ฆ
- AWS Certified DevOps Engineer: ์šด์˜ ์ž๋™ํ™” ์ค‘์‹ฌ

์ž๊ฒฉ์ฆ ์ค€๋น„ํ•˜๋ฉด์„œ ์‹ค๋ฌด ์ง€์‹๋„ ํ•จ๊ป˜ ์Œ“์„ ์ˆ˜ ์žˆ์–ด!

๐Ÿ› ๏ธ ์‹ค์Šต ํ”„๋กœ์ ํŠธ ์•„์ด๋””์–ด

์ด๋ก ๋งŒ ๊ณต๋ถ€ํ•˜๋ฉด ๊ธˆ๋ฐฉ ์žŠ์–ด๋ฒ„๋ ค. ์ง์ ‘ ํ•ด๋ณด๋Š” ๊ฒŒ ์ตœ๊ณ ์˜ ํ•™์Šต ๋ฐฉ๋ฒ•์ด์•ผ:

์ดˆ๊ธ‰ ํ”„๋กœ์ ํŠธ:
1. ์ •์  ์›น์‚ฌ์ดํŠธ ํ˜ธ์ŠคํŒ… with CloudFront
2. ์‚ฌ์ง„ ๊ณต์œ  ์•ฑ (์—…๋กœ๋“œ/๋‹ค์šด๋กœ๋“œ ๊ถŒํ•œ ๋ถ„๋ฆฌ)
3. ๋กœ๊ทธ ์ˆ˜์ง‘ ์‹œ์Šคํ…œ (์—ฌ๋Ÿฌ ์†Œ์Šค์—์„œ S3๋กœ)

์ค‘๊ธ‰ ํ”„๋กœ์ ํŠธ:
1. ๋ฉ€ํ‹ฐ ํ…Œ๋„ŒํŠธ SaaS ์Šคํ† ๋ฆฌ์ง€ (ํ…Œ๋„ŒํŠธ๋ณ„ ๊ฒฉ๋ฆฌ)
2. ๋ฐ์ดํ„ฐ ๋ ˆ์ดํฌ ๊ตฌ์ถ• (๋ถ€์„œ๋ณ„ ์ ‘๊ทผ์ œ์–ด)
3. ๋ฐฑ์—… ์ž๋™ํ™” ์‹œ์Šคํ…œ (์•”ํ˜ธํ™”, ๋ฒ„์ „ ๊ด€๋ฆฌ)

๊ณ ๊ธ‰ ํ”„๋กœ์ ํŠธ:
1. ๊ธ€๋กœ๋ฒŒ CDN with ๋ฉ€ํ‹ฐ ๋ฆฌ์ „ ๋ณต์ œ
2. ์ปดํ”Œ๋ผ์ด์–ธ์Šค ์ค€์ˆ˜ ์Šคํ† ๋ฆฌ์ง€ (GDPR, HIPAA)
3. AI/ML ํŒŒ์ดํ”„๋ผ์ธ (SageMaker + S3)

ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ๋ง‰ํžˆ๋Š” ๋ถ€๋ถ„์ด ์žˆ๋‹ค๋ฉด, ์žฌ๋Šฅ๋„ท์—์„œ ๋ฉ˜ํ† ๋ฅผ ์ฐพ์•„๋ณด๋Š” ๊ฒƒ๋„ ์ข‹์€ ๋ฐฉ๋ฒ•์ด์•ผ!

๐ŸŒŸ ์ปค๋ฎค๋‹ˆํ‹ฐ ์ฐธ์—ฌ

ํ˜ผ์ž ๊ณต๋ถ€ํ•˜๋ฉด ์™ธ๋กญ๊ณ  ํž˜๋“ค ์ˆ˜ ์žˆ์–ด. ์ปค๋ฎค๋‹ˆํ‹ฐ์— ์ฐธ์—ฌํ•ด๋ด:

- AWS ํ•œ๊ตญ ์‚ฌ์šฉ์ž ๋ชจ์ž„: ์ •๊ธฐ ๋ฐ‹์—…๊ณผ ์„ธ๋ฏธ๋‚˜
- Reddit r/aws: ๊ธ€๋กœ๋ฒŒ ์ปค๋ฎค๋‹ˆํ‹ฐ
- Stack Overflow: ๊ธฐ์ˆ  Q&A
- AWS re:Post: AWS ๊ณต์‹ ์ปค๋ฎค๋‹ˆํ‹ฐ
- LinkedIn ๊ทธ๋ฃน: ์ „๋ฌธ๊ฐ€ ๋„คํŠธ์›Œํ‚น

๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์˜ ๊ฒฝํ—˜์„ ๋“ฃ๊ณ , ์งˆ๋ฌธํ•˜๊ณ , ๋‹ต๋ณ€ํ•˜๋ฉด์„œ ์‹ค๋ ฅ์ด ์‘ฅ์‘ฅ ๋Š˜์–ด๋‚  ๊ฑฐ์•ผ! ๐Ÿš€

๐Ÿ”ฎ ๋ฏธ๋ž˜ ํŠธ๋ Œ๋“œ

์•ž์œผ๋กœ S3์™€ ํด๋ผ์šฐ๋“œ ์Šคํ† ๋ฆฌ์ง€๋Š” ์–ด๋–ป๊ฒŒ ๋ฐœ์ „ํ• ๊นŒ?

์˜ˆ์ƒ๋˜๋Š” ๋ณ€ํ™”:
1. AI ๊ธฐ๋ฐ˜ ์ž๋™ ์ตœ์ ํ™”: ์ ‘๊ทผ ํŒจํ„ด์„ ํ•™์Šตํ•ด์„œ ์ž๋™์œผ๋กœ ์ •์ฑ… ์กฐ์ •
2. ์ œ๋กœ ํŠธ๋Ÿฌ์ŠคํŠธ ์•„ํ‚คํ…์ฒ˜: ๋ชจ๋“  ์ ‘๊ทผ์„ ๊ฒ€์ฆํ•˜๋Š” ๋ณด์•ˆ ๋ชจ๋ธ
3. ์—ฃ์ง€ ์ปดํ“จํŒ… ํ†ตํ•ฉ: IoT ๊ธฐ๊ธฐ์™€ S3์˜ ๊ธด๋ฐ€ํ•œ ์—ฐ๋™
4. ์–‘์ž ์•”ํ˜ธํ™”: ์–‘์ž ์ปดํ“จํ„ฐ ์‹œ๋Œ€๋ฅผ ๋Œ€๋น„ํ•œ ์•”ํ˜ธํ™”
5. ํƒ„์†Œ ์ค‘๋ฆฝ ์Šคํ† ๋ฆฌ์ง€: ํ™˜๊ฒฝ์„ ๊ณ ๋ คํ•œ ์Šคํ† ๋ฆฌ์ง€ ์„ ํƒ

์ด๋Ÿฐ ํŠธ๋ Œ๋“œ๋ฅผ ๋ฏธ๋ฆฌ ์•Œ๊ณ  ์ค€๋น„ํ•˜๋ฉด ๊ฒฝ์Ÿ๋ ฅ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์–ด!

๐Ÿ’ผ ์ปค๋ฆฌ์–ด ๋ฐœ์ „

S3 ์ ‘๊ทผ์ œ์–ด ์ „๋ฌธ์„ฑ์€ ๋‹ค์–‘ํ•œ ์ปค๋ฆฌ์–ด ๊ฒฝ๋กœ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์–ด:

- ํด๋ผ์šฐ๋“œ ์•„ํ‚คํ…ํŠธ: ์ „์ฒด ์‹œ์Šคํ…œ ์„ค๊ณ„
- ๋ณด์•ˆ ์—”์ง€๋‹ˆ์–ด: ํด๋ผ์šฐ๋“œ ๋ณด์•ˆ ์ „๋ฌธ
- DevOps ์—”์ง€๋‹ˆ์–ด: ์ž๋™ํ™”์™€ ์šด์˜
- ๋ฐ์ดํ„ฐ ์—”์ง€๋‹ˆ์–ด: ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ•
- ์ปจ์„คํ„ดํŠธ: ๊ธฐ์—… ํด๋ผ์šฐ๋“œ ์ „ํ™˜ ์ง€์›

๊ฐ ๋ถ„์•ผ๋งˆ๋‹ค S3 ์ง€์‹์ด ํ•„์ˆ˜์ ์ด์•ผ. ํƒ„ํƒ„ํ•œ ๊ธฐ์ดˆ๋ฅผ ์Œ“์•„๋‘๋ฉด ์–ด๋–ค ๋ฐฉํ–ฅ์œผ๋กœ๋“  ์„ฑ์žฅํ•  ์ˆ˜ ์žˆ์–ด! ๐ŸŒฑ


๐ŸŽฌ ๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

์™€! ์ •๋ง ๊ธด ์—ฌ์ •์ด์—ˆ์ง€? ๐Ÿ˜… S3 ์ ‘๊ทผ์ œ์–ด์˜ ๊ธฐ์ดˆ๋ถ€ํ„ฐ ๊ณ ๊ธ‰ ์ฃผ์ œ๊นŒ์ง€, ์‹ค์ „ ์‹œ๋‚˜๋ฆฌ์˜ค์™€ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…, ๋น„์šฉ ์ตœ์ ํ™”๊นŒ์ง€ ๋ชจ๋‘ ๋‹ค๋ค˜์–ด.

ํ•ต์‹ฌ์„ ๋‹ค์‹œ ํ•œ๋ฒˆ ์ •๋ฆฌํ•˜๋ฉด:

โœ… ๋‹ค์ธต ๋ฐฉ์–ด: IAM ์ •์ฑ…, ๋ฒ„ํ‚ท ์ •์ฑ…, ACL, ๋ธ”๋ก ํผ๋ธ”๋ฆญ ์•ก์„ธ์Šค๋ฅผ ์กฐํ•ฉํ•ด์„œ ์‚ฌ์šฉ
โœ… ์ตœ์†Œ ๊ถŒํ•œ: ๊ผญ ํ•„์š”ํ•œ ๊ถŒํ•œ๋งŒ ๋ถ€์—ฌ
โœ… ์•”ํ˜ธํ™”: ์ €์žฅ ๋ฐ์ดํ„ฐ์™€ ์ „์†ก ๋ฐ์ดํ„ฐ ๋ชจ๋‘ ์•”ํ˜ธํ™”
โœ… ๋ชจ๋‹ˆํ„ฐ๋ง: CloudTrail, GuardDuty, Macie๋กœ ์ง€์†์  ๊ฐ์‹œ
โœ… ์ž๋™ํ™”: Lambda, EventBridge๋กœ ๋ณด์•ˆ ์ •์ฑ… ์ž๋™ ์ ์šฉ
โœ… ํ…Œ์ŠคํŠธ: ์ •์ฑ… ๋ณ€๊ฒฝ ํ›„ ๋ฐ˜๋“œ์‹œ ๊ฒ€์ฆ
โœ… ๋ฌธ์„œํ™”: ์„ค์ • ์ด์œ ์™€ ๋ฐฉ๋ฒ•์„ ๊ธฐ๋ก

S3 ์ ‘๊ทผ์ œ์–ด๋Š” ํ•œ ๋ฒˆ ์„ค์ •ํ•˜๊ณ  ๋๋‚˜๋Š” ๊ฒŒ ์•„๋‹ˆ์•ผ. ์ง€์†์ ์œผ๋กœ ๊ฒ€ํ† ํ•˜๊ณ  ๊ฐœ์„ ํ•ด์•ผ ํ•ด. ์ƒˆ๋กœ์šด ์œ„ํ˜‘์ด ๋‚˜ํƒ€๋‚˜๊ณ , AWS๋„ ๊ณ„์† ์ƒˆ ๊ธฐ๋Šฅ์„ ์ถœ์‹œํ•˜๋‹ˆ๊นŒ ๋ง์ด์•ผ.

์ฒ˜์Œ์—๋Š” ๋ณต์žกํ•˜๊ณ  ์–ด๋ ต๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ์–ด. ํ•˜์ง€๋งŒ ํ•˜๋‚˜์”ฉ ์ฐจ๊ทผ์ฐจ๊ทผ ์ตํžˆ๋‹ค ๋ณด๋ฉด ์–ด๋А์ƒˆ ์ „๋ฌธ๊ฐ€๊ฐ€ ๋˜์–ด ์žˆ์„ ๊ฑฐ์•ผ! ๐Ÿ’ช

ํ˜น์‹œ ๋ง‰ํžˆ๋Š” ๋ถ€๋ถ„์ด ์žˆ๊ฑฐ๋‚˜, ๋” ๊นŠ์ด ๋ฐฐ์šฐ๊ณ  ์‹ถ๋‹ค๋ฉด ์ฃผ์ €ํ•˜์ง€ ๋ง๊ณ  ๋„์›€์„ ์š”์ฒญํ•ด. AWS ์ปค๋ฎค๋‹ˆํ‹ฐ๋Š” ์ •๋ง ์นœ์ ˆํ•˜๊ณ , ์žฌ๋Šฅ๋„ท ๊ฐ™์€ ํ”Œ๋žซํผ์—์„œ๋Š” ์‹ค๋ฌด ์ „๋ฌธ๊ฐ€๋“ค์˜ ์กฐ์–ธ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด.

ํด๋ผ์šฐ๋“œ ๋ณด์•ˆ์€ ์„ ํƒ์ด ์•„๋‹ˆ๋ผ ํ•„์ˆ˜์•ผ. ์˜ค๋Š˜ ๋ฐฐ์šด ๋‚ด์šฉ์„ ๋ฐ”ํƒ•์œผ๋กœ ์•ˆ์ „ํ•˜๊ณ  ํšจ์œจ์ ์ธ S3 ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•˜๊ธธ ๋ฐ”๋ผ! ๐Ÿš€

์งˆ๋ฌธ์ด๋‚˜ ํ”ผ๋“œ๋ฐฑ์ด ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“  ํ™˜์˜์ด์•ผ. ํ•จ๊ป˜ ์„ฑ์žฅํ•˜๋Š” ํด๋ผ์šฐ๋“œ ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ๋งŒ๋“ค์–ด๊ฐ€์ž! ๐ŸŒŸ

ํ–‰์šด์„ ๋นŒ์–ด! Happy Cloud Computing! โ˜๏ธโœจ

๋Œ“๊ธ€ ์ž‘์„ฑ

์ด ๊ธ€์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ƒ๊ฐ์„ ๋“ค๋ ค์ฃผ์„ธ์š”

๋Œ“๊ธ€ 0
๋Œ“๊ธ€์„ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘์ž…๋‹ˆ๋‹ค.

์•„์ง ๋Œ“๊ธ€์ด ์—†์Šต๋‹ˆ๋‹ค.