S3 Security
Access Control, Encryption, Block Public Access, Pre-signed URLs, VPC Endpoints
Tổng quan
S3 Security dựa trên nguyên tắc Defense in Depth - nhiều lớp bảo vệ chồng lên nhau:
Mặc định: Buckets và objects là private - chỉ owner có quyền access.
Access Control
So sánh các phương pháp
| Method | Scope | Attach vào | Use Case |
|---|---|---|---|
| IAM Policies | User/Role | IAM User, Group, Role | Internal users, services trong cùng account |
| Bucket Policies | Bucket | S3 Bucket | Cross-account, public access, IP restrictions |
| Access Points | Named endpoint | S3 Bucket | Multi-team access, simplified permissions |
| ACLs | Object/Bucket | Object hoặc Bucket | ⚠️ Legacy, không khuyến khích |
IAM Policies vs Bucket Policies
Bucket Policy Examples
1. Public Read (cho static website):
2. Cross-Account Access:
3. Restrict by IP (chỉ cho phép từ office IP):
4. Force HTTPS (deny HTTP):
S3 Access Points
Simplify access management cho shared datasets - tạo nhiều "cổng vào" riêng cho cùng 1 bucket.
Vấn đề: 1 Bucket Policy cho nhiều teams
Khi nhiều teams cùng dùng 1 bucket, bạn phải viết 1 bucket policy rất dài và phức tạp:
Giải pháp: Mỗi team có Access Point riêng
Ví dụ cụ thể
Bucket company-data chứa 3 folders: /ml/, /analytics/, /mkt/
Access Point cho team Data Science - chỉ được đọc/ghi /ml/:
Access Point cho team Marketing - chỉ được đọc /mkt/:
Cách team sử dụng
Mỗi team gọi qua access point của mình thay vì bucket trực tiếp:
Endpoint format: https://<access-point-name>-<account-id>.s3-accesspoint.<region>.amazonaws.com
So sánh có và không có Access Points
| Không có Access Points | Có Access Points |
|---|---|
| 1 bucket policy cho tất cả | Mỗi team có policy riêng |
| Policy dài, phức tạp | Mỗi policy ngắn, đơn giản |
| Giới hạn 20KB | Không lo giới hạn |
| Thay đổi ảnh hưởng tất cả | Thay đổi chỉ ảnh hưởng 1 team |
| Khó debug khi có lỗi | Dễ xác định lỗi ở team nào |
💡 Hiểu đơn giản: Access Point giống như tạo nhiều "cổng vào" cho cùng 1 kho hàng, mỗi cổng có bảo vệ riêng, quy định riêng về ai được vào và lấy gì.
Encryption
⚡ Default Encryption (Từ Jan 2023)
Quan trọng: Từ tháng 1/2023, AWS đã bật SSE-S3 encryption mặc định cho TẤT CẢ objects mới upload lên S3. Bạn không cần làm gì!
| Aspect | Default Behavior |
|---|---|
| Encryption type | SSE-S3 (AES-256) |
| Key management | AWS quản lý hoàn toàn |
| Cost | Free |
| Bạn cần làm gì? | Không cần làm gì! |
| Có thể đổi? | Có - đổi sang SSE-KMS nếu cần audit |
Server-Side Encryption (SSE)
S3 tự động encrypt data khi lưu và decrypt khi GET:
| Type | Key quản lý | Audit | Khi nào dùng |
|---|---|---|---|
| SSE-S3 | AWS (tự động) | ❌ | Default, đơn giản nhất |
| SSE-KMS | Bạn (KMS) | ✅ CloudTrail | Compliance, audit trail |
| SSE-C | Bạn (gửi mỗi request) | ❌ | Full control |
| DSSE-KMS | KMS, dual-layer | ✅ | Extra security |
Client-Side Encryption
- Encrypt trước khi upload
- Decrypt sau khi download
- AWS không bao giờ thấy plaintext data
Bucket Default Encryption
Bật encryption mặc định cho bucket (tất cả objects mới sẽ được encrypt):
Force Encryption with Bucket Policy
Tại sao cần Force khi đã có Default?
Default encryption chỉ áp dụng khi client không specify encryption. Client vẫn có thể override bằng header:
Bucket Policy để Force SSE-KMS:
Kết quả:
- Upload với SSE-S3 → ❌ DENIED
- Upload với SSE-KMS → ✅ ALLOWED
- Upload không specify → ❌ DENIED
Khi nào cần Force Encryption?
| Scenario | Cần Force? |
|---|---|
| Dữ liệu thông thường | ❌ Default SSE-S3 đủ |
| Cần audit log (ai đọc/ghi) | ✅ Force SSE-KMS |
| Compliance (HIPAA, PCI, SOC2) | ✅ Force SSE-KMS |
| Dùng customer-managed key | ✅ Force SSE-KMS với specific key |
S3 Block Public Access
Safety net để ngăn accidentally expose data ra public:
Có thể apply ở 2 levels:
- Account level - apply cho tất cả buckets trong account
- Bucket level - apply cho specific bucket
💡 Best Practice: Enable tất cả 4 settings ở Account level, chỉ disable ở bucket level khi thực sự cần public access.
CORS
CORS (Cross-Origin Resource Sharing) - cơ chế cho phép web browser gọi đến S3 bucket từ domain khác.
Vấn đề: Same-Origin Policy
Browser có Same-Origin Policy - chặn requests đến domain khác vì lý do bảo mật:
Làm thế nào để Browser kết nối được S3?
Có 2 cách chính:
Cách 1: Cấu hình CORS trên S3 bucket (Browser gọi trực tiếp)
Cách 2: Đi qua Backend (Proxy) - không cần CORS
| Phương pháp | Cần CORS? | Khi nào dùng |
|---|---|---|
| Browser → S3 trực tiếp | ✅ Cần | Upload/download file trực tiếp, static assets |
| Browser → Backend → S3 | ❌ Không | Cần xử lý logic, bảo mật sensitive operations |
💡 Key insight: Same-Origin Policy là browser chặn, không phải S3. CORS là cách S3 nói với browser "tao cho phép origin này gọi tao".
CORS giải quyết thế nào?
Cấu hình CORS trên S3
Bucket → Permissions → Cross-origin resource sharing (CORS):
Giải thích các fields
| Field | Mô tả | Ví dụ |
|---|---|---|
| AllowedOrigins | Domains được phép gọi | ["https://myapp.com"] hoặc ["*"] (all) |
| AllowedMethods | HTTP methods được phép | ["GET", "PUT", "POST", "DELETE"] |
| AllowedHeaders | Headers client được gửi | ["*"] hoặc ["Content-Type", "Authorization"] |
| ExposeHeaders | Headers S3 trả về mà JS có thể đọc | ["ETag", "x-amz-meta-*"] |
| MaxAgeSeconds | Cache preflight response (giây) | 3600 (1 hour) |
Use Cases phổ biến
Ví dụ: Allow all origins (Development)
⚠️ Cảnh báo: Không dùng
"*"cho production với write operations!
Troubleshooting CORS Errors
MFA Delete
MFA Delete - yêu cầu MFA (Multi-Factor Authentication) để thực hiện các thao tác xóa quan trọng trên S3.
Tại sao cần MFA Delete?
MFA Delete bảo vệ những gì?
| Action | Cần MFA? |
|---|---|
| Delete object version (permanently delete) | ✅ Cần MFA |
| Suspend/Disable versioning | ✅ Cần MFA |
| Delete object (tạo delete marker) | ❌ Không cần |
| Enable versioning | ❌ Không cần |
| List/Get objects | ❌ Không cần |
💡 Lưu ý: MFA Delete chỉ bảo vệ permanent delete (xóa version cụ thể), không phải soft delete (tạo delete marker).
Yêu cầu để enable MFA Delete
Cách enable MFA Delete
Khi delete cần MFA
MFA Delete vs Object Lock
| Feature | MFA Delete | Object Lock |
|---|---|---|
| Bảo vệ | Cần MFA để delete | Không ai có thể delete |
| Linh hoạt | Vẫn có thể delete (với MFA) | Hoàn toàn không thể delete |
| Use case | Chống unauthorized delete | Compliance (WORM) |
| Enable bởi | Root account only | Khi tạo bucket |
Khi nào dùng MFA Delete?
| Scenario | Recommendation |
|---|---|
| Critical backups | ✅ Enable MFA Delete |
| Compliance data (WORM required) | ✅ Use Object Lock thay vì MFA Delete |
| Shared AWS account | ✅ Enable MFA Delete |
| Data có thể recreate | ❌ Không cần |
⚠️ Lưu ý quan trọng: MFA Delete chỉ có thể enable/disable bởi root account. Nếu root account bị mất access, bạn không thể tắt MFA Delete!
Pre-signed URLs
Tạo temporary URLs để grant access không cần AWS credentials:
AWS CLI:
Pre-signed URL format:
Use cases:
- Allow downloads without AWS credentials
- Allow uploads to specific path
- Temporary access for external users
VPC Endpoints
Truy cập S3 qua private network thay vì internet:
2 loại VPC Endpoints cho S3:
| Type | Network | Cost | Use Case |
|---|---|---|---|
| Gateway Endpoint | Route table entry | Free | Default choice |
| Interface Endpoint | ENI with private IP | ~$7/month | On-premises access, specific compliance |
Bucket Policy restrict to VPC Endpoint:
S3 Access Logs
S3 Access Logs ghi lại mọi requests đến bucket - ai truy cập, làm gì, khi nào.
Cách hoạt động
Log format (các fields quan trọng)
Cách enable S3 Access Logs
Console: Bucket → Properties → Server access logging → Edit → Enable
CLI:
Target Bucket Policy
Target bucket cần có policy cho phép S3 log delivery:
Use Cases
| Use Case | Mô tả |
|---|---|
| Security audit | Ai đã truy cập sensitive files? |
| Access patterns | Files nào được access nhiều nhất? |
| Cost analysis | Requests đến từ đâu, bao nhiêu? |
| Troubleshooting | Tại sao request failed? (error codes) |
| Compliance | Chứng minh access history |
Lưu ý quan trọng
| Điểm cần lưu ý | Chi tiết |
|---|---|
| Best-effort delivery | Không đảm bảo 100% logs được ghi |
| Delay | Logs có thể delay vài phút |
| Cost | Chỉ tốn phí storage cho log files |
| Format | Text files, space-delimited |
S3 Access Logs vs CloudTrail
| Feature | S3 Access Logs | CloudTrail |
|---|---|---|
| Scope | Requests đến bucket | AWS API calls |
| Chi tiết | Rất chi tiết (bytes, latency) | Ít chi tiết hơn |
| Delivery | Best-effort | Near real-time |
| Cost | Storage only | Per event (data events) |
| Analysis | Athena, custom scripts | CloudWatch, Athena |
| Use case | Deep analysis | Audit, compliance |
💡 Recommendation: Dùng cả hai cho comprehensive monitoring. CloudTrail cho real-time audit, Access Logs cho detailed analysis.
Logging & Monitoring
CloudTrail
Log management events (bucket creation, policy changes) và data events (GetObject, PutObject):
- Management events: mặc định đã log
- Data events: phải bật riêng (tốn phí)
Amazon Macie
Tự động discover sensitive data (PII, credentials) trong S3:
- Scan buckets tìm sensitive data
- Alert về public buckets, unencrypted data
- Compliance reports
Best Practices
Checklist bảo mật S3
| Category | Action | Priority |
|---|---|---|
| Access | Enable S3 Block Public Access ở account level | 🔴 Critical |
| Access | Disable ACLs (dùng Bucket owner enforced) | 🟠 High |
| Access | Sử dụng least privilege IAM policies | 🟠 High |
| Encryption | Enable default encryption (SSE-S3 hoặc SSE-KMS) | 🟠 High |
| Encryption | Force HTTPS với bucket policy | 🟡 Medium |
| Data Protection | Enable versioning cho critical data | 🟠 High |
| Data Protection | Enable MFA Delete cho critical buckets | 🟡 Medium |
| Network | Sử dụng VPC Endpoints | 🟡 Medium |
| Monitoring | Enable S3 Access Logs | 🟡 Medium |
| Monitoring | Enable CloudTrail data events | 🟡 Medium |
| Compliance | Sử dụng Object Lock cho WORM requirements | 🟡 As needed |
Common Mistakes
Liên kết
- S3 - Main S3 documentation
- AWS KMS - Key Management Service
- VPC Endpoints - Private access to AWS services
- IAM - Identity and Access Management
- Amazon Macie - Sensitive data discovery