ความปลอดภัยของ Amazon S3 บน AWS

Vit Niennattrakul
AWS User Group (Thailand)
5 min readApr 18, 2018

— พื้นฐานการรักษาข้อมูลให้ปลอดภัย

Amazon S3 (ย่อมาจาก Amazon Simple Storage Service) เป็นบริการแรกๆ ที่ให้บริการของ AWS ที่ไว้เก็บข้อมูลไฟล์แบบ Object Storage ในบทความนี้จะอธิบายเกี่ยวกับการตัั้งค่าความปลอดภัยของ Amazon S3 เพื่อการรักษาข้อมูลที่ปลอดภัย

ความปลอดภัยทางด้าน Infrastructure ของ S3

Amazon Web Services เป็นผู้ดูแลทางด้าน Infrastructure ของ S3 โดย Amazon Web Services ได้มี Compliance/Certificate ระบบ Global ได้แก่ CSA, ISO 9001/27001/27017/27018, PCI DSS Level 1, SOC 1/2/3 รวมถึงพึ่งได้มีการประกาศว่า AWS ได้มีการรับรองตามมาตราฐานของ GDPR ของทางยุโรปเรียบร้อยแล้วเช่นกัน

Compliance/Certificate ระดับ Global

โดยที่ Amazon S3 ได้ Compliance/Certificate ในทุกตัวที่ได้กล่าวมา Ref: https://aws.amazon.com/compliance/services-in-scope/

Amazon S3

โครงสร้างของ Amazon S3 ประกอบไปด้วย 2 ส่วน ได้แก่

  1. Bucket เป็นถังเก็บข้อมูลที่ไว้เก็บ Object โดยสามารถเก็บจำนวนข้อมูลได้ไม่จำกัด โดยชื่อของ Bucket จะเป็น Unique กันระดับ Global นั่นคือเราจะตั้งชื่อ Bucket ซ้ำกับคนอื่นไม่ได้
  2. Object เป็นเนื้อข้อมูลโดยประกอบไปด้วย 2 ส่วน ได้แก่ 1. เนื้อข้อมูลดิบ 2. คำอธิบายข้อมูล (Metadata) เช่น การประเภทของข้อมูล (Content-type) หรือการเก็บ Cache (Cache-header) เป็นต้น โดยชื่อ Object จะเป็น Key

เมื่อเรา Upload ไฟล์ขึ้นไปภายใต้ S3 Bucket ทาง S3 จะสร้าง URL ประจำตัวสำหรับไฟล์นั้น เช่น ผมสร้าง Bucket ชื่อ demo-s3-security และ Upload File ชื่อ aws.png

ตัวระบบจะทำการ Generate URL ให้อัตโนมัติสำหรับแต่ละไฟล์โดยใช้ชื่อ Bucket และ Key ของ Object เป็นส่วนประกอบของ URL เช่นในกรณีนี้ที่ไฟล์ aws.png อยู่ใน Bucket demo-s3-security จะมีให้ดังนี้ https://s3-ap-southeast-1.amazonaws.com/demo-s3-security/aws.png

รูปแสดง Link

แต่อย่างไรก็ตาม โดย Default แล้วเมื่อเราสร้าง Bucket ขึ้นมาและ Upload ไฟล์ขึ้นไปไฟล์ที่อยู่ภายใต้ S3 Bucket นั้นจะเป็น Private นั่นคือหากมีการเรียกไฟล์ (URL) นั้นจะขึ้น Error 403 Forbidden

ข้อความ Access Denied เมื่อพยายามเข้าถึงข้อมูล

ความปลอดภัยจากการตั้งค่าต่างๆ ของ AWS

ในการเข้าถึงไฟล์จากผู้ใช้ภายนอก โดย Default จะเป็น Private นั่นคือเราไม่สามารถเข้าถึงไฟล์ได้จาก Internet หากเราไม่ได้ให้ Permission เพิ่มเติม

ในการให้ Permission เพิ่มเติม เราจะมีการตั้ง Permission Policy โดยการตั้งค่าแต่ละแบบขึ้นอยู่กับ Use Case ของการใช้งานโดยเราสามารถตั้งค่าได้ 3 ส่วนได้แก่

  1. การตั้ง Policy บน Bucket (Bucket Policy) เป็นการตั้ง Permission ของ S3 Bucket
  2. การตั้ง Policy บน IAM (IAM Policy) เป็นการตั้ง Permission ให้กับผู้ใช้งานบน Amazon Web Services
  3. การตั้ง ACL บน Bucket (ACL) เป็นการตั้ง Permission ของไฟล์ (ไม่ขออธิบายในบทความนี้ เนื่องจากส่วนใหญ่สามารถใช้ Bucket Policy ในการใช้งานได้)

การตั้ง Policy บน Bucket (Bucket Policy)

เป็นการตั้ง Permission ให้กับ Object ใน Bucket นั้นๆ โดยทั่วไปแล้ว Bucket Policy จะไม่มีการกำหนดค่าไว้ (Default จะเป็น Deny) ใน Use Case ทั่วไป การตั้งค่า Bucket Policy จะมีการตั้งค่าให้ในกรณีที่เราต้องการให้ไฟล์ที่อยู่ใน Bucket นั้นสามารถเข้าถึงได้จากภายนอก หากเราต้องการให้ Bucket demo-s3-security สามารถอ่านได้เท่านั้น (Read only) จาก Internet เช่น เราได้ทำเว็บไซต์ข่าวสารแล้วมีการเก็บรูปภาพไว้ ต้องการให้ S3 เป็น File Server โดยที่ให้ Web Browser เรียกไฟล์ใน S3 ได้โดยตรงเราสามารถตั้งค่า Policy ได้ดังนี้

การตั้งค่า Bucket Policy ให้ Read Only จากใครก็ได้

ใน Policy จะมีสิ่งที่ต้องกำหนดอยู่ 4 ส่วนหลัก ได้แก่

  1. Effect — เป็นการบอกว่า Allow/Deny “Allow” คืออนุญาตให้มี Permission
  2. Principle —เป็นการบอกว่าใคร ในที่นี้ให้เป็น “*” แปลว่าให้กับทุกคน
  3. Action — เป็นการบอกว่าทำอะไร ในที่นี้เป็น “S3:GetObject” ที่ให้อ่านไฟล์ S3 ได้อย่างเดียว
  4. Resources — เป็นการบอกว่าที่ไหน ในที่นี้เป็น S3 Bucket ชื่อ demo-s3-security และเป็น /* คือไฟล์ทัั้งหมดใน Bucket นี้

นำมารวมกันแล้วจะได้ว่าให้ Permission กับทุกคนในการอ่านไฟล์ S3 ที่ไฟล์ใน S3 Bucket ทั้งหมด

เมื่อเราสร้าง Bucket Policy ขึ้นมาเรียบร้อย จะเห็นส่วนที่แสดงว่าเป็น Public ขึ้นมา

จะมีขึ้นเตือนหาก Bucket Policy เป็นแบบ Public (มีการอนุญาตให้ใครก็ได้เข้าถึง)

ในการกำหนดสิทธิ์ที่ต้องการให้สามารถเข้าถึงได้ เราสามารถกำหนดสิทธิ์เป็นระดับ Prefix ของไฟล์ได้ เพราะว่าในบางทีเราใช้ Bucket รวมกันทั้งข้อมูลที่เป็น Public และ Private เราสามารถตั้งค่าโดยใส่เป็น Prefix ลงไปใน Bucket Policy ได้เช่น หากต้องการให้ข้อมูลที่อยู่ใน Prefix ของ /public เราสามารถที่จะตั้ง Bucket Policy ได้เช่น

สามารถใส่ Prefix ให้เฉพาะ Folder ที่ต้องการให้เป็น Public ได้

เราสามารถใช้ส่วนของ Condition ในการตั้งค่าความปลอดภัยของ Bucket Policy ของเราได้ เช่น การกำหนดช่วง IP Address ที่ต้องการให้มา Access ได้ เช่น หากเราต้องการให้ Bucket นี้สามารถเข้าถึงได้จากบริษัทของเราเท่านั้น เราสามารถใส่ Public IP Address ขององค์กรของเราได้ เช่น

กำหนดช่วง IP Address ให้อ่านข้อมูลได้เฉพาะ IP Address ที่กำหนด

นอกจากนั้น สำหรับหน่วยงานที่ได้ทำ Site-to-site VPN กับ VPC (Virtual Private Cloud) แล้วเราสามารถกำหนด VPC Private Endpoint และกำหนดค่า IP Address ที่เป็น Private IP ได้เช่นกัน

รายละเอียดตัวอย่างเพิ่มเติมของ Bucket Policy สามารถดูเพิ่มได้จาก https://docs.aws.amazon.com/AmazonS3/latest/dev/example-bucket-policies.html

ดังนั้น ในการตั้ง Bucket Policy จึงเหมาะกับการตั้ง Permission ให้กับ Resources ไฟล์ทั้งหมดของ Bucket นั้น แต่หากเราต้องการให้ข้อมูลใน S3 เป็น Private Content แต่ต้องการให้เฉพาะคนที่ต้องการ Login เข้าถึง Content ได้ เช่น Web Application / Mobile Application ที่มีการเก็บข้อมูล Software ให้ดาวโหลด หรือมีการเก็บข้อมูล Private ของลูกค้า หรือข้อมูล Report ทางการเงินเป็นต้น เราสามารถใช้ Feature ของ S3 ที่เรียกว่า Signed URL เหมือนเป็น One-time Link โดยผมจะขออธิบายในหัวข้อ การตั้ง Policy บน IAM ครับ

การตั้ง Policy บน IAM (IAM Policy)

เป็นการตั้ง Permission ให้กับผู้ใช้งาน (IAM User) หรือ Role (IAM Role) โดยเป็นการจำกัดว่าใครจะสามารถเข้าถึงไฟล์นี้ได้บ้าง โดย User จะต้องเป็นผู้ใช้งานบน Account ของ Amazon Web Services ของตัวเองเท่านั้น หรือ Service เช่น EC2 ของ AWS ของเราที่มี Permission ซึ่งเราจะต้องสร้าง Policy และนำ Policy นี้ไปผูกกับ IAM User หรือ IAM Role เพื่อให้ IAM User หรือ IAM Role นั้นๆ มี Permission ตามที่ Policy นั้นกำหนด

จากรูปตัวอย่าง Policy จะเป็นการให้ Permission ในการเข้าถึง Bucket ที่ชื่อ demo-s3-security ในการ Upload และ Download File ได้

ตัวอย่างของ Policy ที่อนุญาตให้สามารถ Upload/Download ไฟล์ที่อยู่ใน S3 Bucket ชื่อ demo-s3-security ได้

โดย Use Case ทั่วไปแล้วหากเราต้องการให้ Web Application ให้มีการ Upload / Download File ไปยัง S3 เช่น มีการ Upload รูป Profile หรือมีการสร้าง PDF เราสามารถใช้ SDK ภาษาต่างๆ เพื่อให้สามารถ Upload/Download ได้โดยเราต้องใช้ Access Key และ Secret Key ที่ได้จาก IAM User และ Assign IAM Role ให้กับเครื่อง EC2 ของเรา

การให้ Permission กับ Application จะแบ่งออกเป็น 2 ส่วนหลักๆ ได้แก่

  1. IAM User — จะเป็นการสร้าง Access Key ID และ Secret Access Key โดยเราสามารถสร้าง Key จะได้จาก Console นำมาใส่ใน SDK หรือ CLI
สร้าง Access Key ID และ Secret Access Key ที่มี Policy ตามที่ต้องการ
นำ Key ที่ได้มาใส่ใน CLI หรือ SDK ในโปรแกรมของเรา

2. IAM Role (แนะนำ)— จะเป็นการให้ Permission กับเครื่อง EC2 ของเรา โดยการสร้าง IAM

ขั้นตอนการ Assign IAM Role ให้กับเครื่อง EC2
เลือก Policy ทีต้องการให้ EC2 นั้นมี Permission

หมายเหตุ ไม่ควรนำ Access Key และ Secret Access Key ใส่เข้าไปใน Code หรือ Commit ขึ้น Git/SVN เนื่องจากอาจจะทำให้ Security Breachได้

แต่ในบางที เราต้องการให้ Permission ชั่วคราวสำหรับการ Download / Upload ไฟล์ หรือ Content ที่ Sensitive เช่น ในกรณีที่ Web Application ต้องมีการ Sign in เพื่อดูข้อมูลทางด้านการเงิน หรือข้อมูลไฟล์ที่มีความ Sensitive เราสามารถสร้าง Link ชั่วคราวในการ Download ได้ที่เรียกว่า Signed URL โดยที่เราไม่ต้องเปิด Bucket ให้เป็น Public

การให้ Permission ชั่วคราวกับ Signed URL

ตัว Signed URL เป็น URL อนุญาตให้ Download / Upload ได้ชั่วคราวและเฉพาะไฟล์นั้น โดยจะมีการกำหนดระยะเวลาในการเข้าถึงได้ โดยที่เราไม่ต้องเปิดให้ Bucket เป็น Public โดยการใช้ Function ของ S3 ที่เรียกว่า Signed URL

ตัวอย่างของ Signed URL เช่น https://demo-s3-security.s3.amazonaws.com/aws.png?AWSAccessKeyId=AKIAIG7DA3WZ6ID6VRYQ&Expires=1524033062&Signature=8jZwjSHJrehqitEe9oeTBDn09eU%3D

ตัวอย่างการใช้งาน CLI กับการทำ S3 Presign

ส่วนประกอบของ Signed URL จะประกอบไปด้วย

  1. ชื่อ Bucket — “demo-s3-security”
  2. Key ของ Object — “aws.png”
  3. Access Key — AKIAIG7DA3WZ6ID6VRYQ
  4. Expires — 1524033062
  5. Signature — 8jZwjSHJrehqitEe9oeTBDn09eU%3D

โดยระยะเวลาจะนับจากระยะเวลาที่ได้ Generate URL ไปให้สามารถกำหนดได้ตั้งแต่ 1 วินาที ถึง 12 ชั่วโมง โดยที่ Link นี้จะมีอายุการใช้งานตามที่กำหนดเท่านั้น ซึ่งหากเราพยายามเข้าถึงจาก Link ที่หมดอายุจะเป็น Access Deny เช่นเดียวกัน

วิธีการใช้งาน Signed URL บน CLI สามารถอ่านได้จาก Link นี้ครับ https://docs.aws.amazon.com/cli/latest/reference/s3/presign.html

สรุป

AWS ได้มี Infrastructure ที่มาตรฐานในการดูแลความปลอดภัยตามมาตรฐานโลก โดยให้เครื่องมือในการตั้งค่าสิทธิ์ขึ้นอยู่กับการใช้งาน (Use Case) ว่าเราต้องการที่จะใช้งานในรูปแบบไหนอย่างไร เราสามารถเลือกการกำหนดสิทธิ์ได้ควรจะเลือกสิทธิ์น้อยสุด (Least Privilege)

ที่สำคัญสำหรับ Bucket ที่ต้องการให้เป็น Private แต่ต้องการให้ Application หรือ Web Browser มีการเรียกใช้งานได้นั้น แนะนำให้ใช้ Signed URL ในการให้ Content เฉพาะเท่าที่มีการ Request ครับ

ติดตามข่าวสารหรือสงสัยปัญหาได้ที่ AWS User Group Thailand — https://www.facebook.com/groups/awsusergroup/

--

--