Bỏ qua để đến nội dung

Amazon S3 – Bảo mật

Dữ liệu nằm trên S3 gần như luôn cần được mã hóa (encryption), và câu hỏi thực sự không phải “có mã hóa hay không” mà là ai giữ chìa khóa. S3 cho bạn 4 phương pháp, khác nhau ở chỗ khóa được tạo và quản lý bởi ai, và việc mã hóa diễn ra ở đâu.

Server-Side Encryption (SSE — mã hóa ở phía server) gồm ba biến thể:

  • SSE-S3 – Server-Side Encryption with Amazon S3-Managed Keys, bật mặc định. Mã hóa object bằng khóa do AWS xử lý, quản lý và sở hữu.
  • SSE-KMS – Server-Side Encryption with KMS Keys stored in AWS KMS. Dùng AWS Key Management Service (AWS KMS) để quản lý khóa mã hóa.
  • SSE-C – Server-Side Encryption with Customer-Provided Keys. Khi bạn muốn tự quản lý khóa của mình.

Phương pháp thứ tư là Client-Side Encryption — mã hóa ngay ở phía client, trước khi dữ liệu rời khỏi máy bạn.

Đây là lựa chọn “không phải nghĩ”: AWS lo toàn bộ phần khóa, bạn chỉ lo upload.

  • Mã hóa bằng khóa do AWS xử lý, quản lý và sở hữu (S3 Owned Key).
  • Object được mã hóa ở phía server.
  • Kiểu mã hóa là AES-256.
  • Phải đặt header "x-amz-server-side-encryption": "AES256".
  • Bật mặc định cho bucket mới và object mới.

Khi bạn cần kiểm soátaudit việc dùng khóa — ví dụ để chứng minh với bộ phận compliance rằng ai đã giải mã dữ liệu gì, lúc nào — thì dùng SSE-KMS.

  • Mã hóa bằng khóa do AWS KMS (Key Management Service) xử lý và quản lý.
  • Ưu điểm của KMS: người dùng kiểm soát được khóa + audit việc sử dụng khóa bằng CloudTrail.
  • Object được mã hóa ở phía server.
  • Phải đặt header "x-amz-server-side-encryption": "aws:kms".

Đổi lại sự kiểm soát, SSE-KMS mang theo quota của KMS, và đây là một điểm rất hay xuất hiện trong đề thi vì nó có thể làm ứng dụng bị throttle mà nhìn vào S3 thì không thấy lý do.

  • Khi upload, S3 gọi API GenerateDataKey của KMS.
  • Khi download, S3 gọi API Decrypt của KMS.
  • Các lệnh gọi này tính vào quota của KMS mỗi giây5.500, 10.000 hoặc 30.000 request/giây tùy region.
  • Bạn có thể yêu cầu tăng quota qua Service Quotas Console.

SSE-C dành cho trường hợp khóa phải nằm ngoài AWS — ví dụ chính sách công ty yêu cầu khóa mã hóa không được lưu ở nhà cung cấp cloud. AWS vẫn làm việc mã hóa hộ bạn, nhưng khóa thì bạn đưa vào theo từng request.

  • Mã hóa ở phía server, nhưng khóa do khách hàng quản lý hoàn toàn, bên ngoài AWS.
  • Amazon S3 KHÔNG lưu khóa mã hóa mà bạn cung cấp.
  • Bắt buộc dùng HTTPS.
  • Khóa mã hóa phải được cung cấp trong HTTP header của mọi request — mất khóa là mất dữ liệu.

Ở phương pháp này, S3 không biết gì về việc mã hóa cả — nó chỉ nhận một file đã là “bí mật” từ trước.

  • Dùng các client library như Amazon S3 Client-Side Encryption Library.
  • Client tự mã hóa dữ liệu trước khi gửi lên Amazon S3.
  • Client tự giải mã dữ liệu khi lấy về từ Amazon S3.
  • Khách hàng quản lý hoàn toàn khóa và toàn bộ chu trình mã hóa.

6. Mã hóa đường truyền (encryption in transit)

Phần tiêu đề “6. Mã hóa đường truyền (encryption in transit)”

Mã hóa object đang nằm trên đĩa (at rest) là một chuyện; dữ liệu đang đi trên đường lại là chuyện khác. Mã hóa đường truyền còn được gọi là encryption in flight, hay SSL/TLS.

  • Amazon S3 công bố hai endpoint: HTTP endpoint (không mã hóa) và HTTPS endpoint (có mã hóa đường truyền).
  • HTTPS được khuyến nghị.
  • HTTPS là bắt buộc với SSE-C.
  • Hầu hết client đều dùng HTTPS endpoint theo mặc định.

Khuyến nghị không đủ mạnh khi bạn cần đảm bảo. Bạn có thể dùng Bucket Policy với điều kiện aws:SecureTransport để chặn mọi request đi qua http và chỉ cho phép https — kể cả request đến từ user của một account khác.

  • SSE-S3 được tự động áp dụng cho object mới lưu vào bucket.
  • Ngoài ra, bạn có thể “force encryption” bằng bucket policy, từ chối mọi lệnh gọi API PUT object mà không có header mã hóa (SSE-KMS hoặc SSE-C).
  • Lưu ý thứ tự đánh giá: Bucket Policy được đánh giá TRƯỚC “Default Encryption”.

CORS = Cross-Origin Resource Sharing. Đây là một cơ chế của trình duyệt web cho phép trang web ở origin này gửi request tới một origin khác.

Origin = scheme (protocol) + host (domain) + port. Ví dụ https://www.example.com (port mặc định là 443 cho HTTPS, 80 cho HTTP).

  • Cùng origin: http://example.com/app1http://example.com/app2.
  • Khác origin: http://www.example.comhttp://other.example.com.
  • Request sẽ không được thực hiện trừ khi origin bên kia cho phép, thông qua các CORS header (ví dụ Access-Control-Allow-Origin).

Luồng hoạt động của trình duyệt gồm hai bước. Trước tiên trình duyệt gửi một Preflight Request dạng OPTIONS tới origin đích, kèm header Origin. Server đích trả về Preflight Response với các header cho phép, ví dụ:

Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Methods: GET, PUT, DELETE

Sau khi origin gốc đã nhận được CORS header, trình duyệt mới thực sự gửi request (GET /) tới origin kia.

  • Nếu client gửi một cross-origin request tới S3 bucket của bạn, bạn phải bật đúng các CORS header trên bucket đó.
  • Đây là câu hỏi thi rất phổ biến.
  • Bạn có thể cho phép một origin cụ thể hoặc * (mọi origin).

MFA (Multi-Factor Authentication) buộc người dùng phải nhập một mã sinh trên thiết bị (thường là điện thoại hoặc thiết bị phần cứng, ví dụ Google Authenticator hay MFA Hardware Device) trước khi thực hiện các thao tác quan trọng trên S3. Mục đích: tránh việc một khóa truy cập bị lộ dẫn tới xóa sạch dữ liệu.

MFA sẽ được yêu cầu khi:

  • Xóa vĩnh viễn một object version.
  • Suspend Versioning trên bucket.

MFA KHÔNG được yêu cầu khi:

  • Bật Versioning.
  • Liệt kê các version đã bị xóa.

Hai điều kiện quan trọng: muốn dùng MFA Delete thì Versioning phải được bật trên bucket, và chỉ chủ bucket (root account) mới có thể bật/tắt MFA Delete.

Cho mục đích audit, bạn có thể ghi lại toàn bộ truy cập vào S3 bucket.

  • Mọi request tới S3, từ bất kỳ account nào, dù được cho phép hay bị từ chối, đều được ghi log vào một S3 bucket khác.
  • Dữ liệu log đó có thể được phân tích bằng các công cụ phân tích dữ liệu.
  • Bucket nhận log phải ở cùng AWS region với bucket được theo dõi.

Bucket riêng tư nhưng bạn vẫn muốn cho một người cụ thể tải một file cụ thể trong một khoảng thời gian ngắn — không tạo IAM user, không mở public. Đó là việc của Pre-Signed URL: một đường link có sẵn chữ ký và có hạn sử dụng.

  • Sinh pre-signed URL bằng S3 Console, AWS CLI hoặc SDK.
  • Thời hạn của URL:
    • S3 Console – từ 1 phút tới 720 phút (12 giờ).
    • AWS CLI – cấu hình bằng tham số --expires-in tính theo giây (mặc định 3600 giây, tối đa 604800 giây ≈ 168 giờ).
  • Người nhận pre-signed URL thừa hưởng quyền của user đã sinh ra URL đó cho thao tác GET / PUT.

Các ví dụ sử dụng:

  • Chỉ cho phép user đã đăng nhập tải một video premium từ bucket.
  • Cho phép một danh sách người dùng luôn thay đổi tải file, bằng cách sinh URL động.
  • Cho phép tạm thời một user upload file vào đúng một vị trí trong bucket.

Một số quy định pháp lý yêu cầu dữ liệu không được sửa, không được xóa trong một khoảng thời gian — mô hình WORM (Write Once Read Many). S3 có hai cơ chế cho việc này.

  • Áp dụng mô hình WORM.
  • Tạo một Vault Lock Policy.
  • Khóa (lock) policy lại để không sửa được trong tương lai — sau khi lock thì không thể thay đổi hay xóa policy nữa.
  • Hữu ích cho compliancelưu giữ dữ liệu (data retention).

Yêu cầu tiên quyết: Versioning phải được bật. Object Lock chặn việc xóa một object version trong một khoảng thời gian xác định, với hai retention mode:

Compliance Governance
Ai có thể ghi đè/xóa version Không ai, kể cả root user Phần lớn user không thể; một số user có quyền đặc biệt thì được
Thay đổi retention Không thể đổi mode, không thể rút ngắn retention period Các user có quyền đặc biệt có thể đổi retention hoặc xóa object

Hai khái niệm đi kèm:

  • Retention Period: bảo vệ object trong một khoảng thời gian cố định; khoảng này có thể gia hạn (extend).
  • Legal Hold: bảo vệ object vô thời hạn, độc lập với retention period; có thể đặt và bỏ tự do bằng quyền IAM s3:PutObjectLegalHold.

Khi một bucket phục vụ nhiều nhóm người dùng với các prefix khác nhau, bucket policy sẽ phình lên thành một khối JSON khổng lồ, khó đọc và khó audit. S3 Access Points tách khối đó ra thành nhiều “cửa vào” riêng, mỗi cửa có policy riêng.

  • Access Points đơn giản hóa việc quản lý bảo mật cho S3 bucket.
  • Mỗi Access Point có:
    • DNS name riêng (Internet Origin hoặc VPC Origin).
    • Một access point policy (tương tự bucket policy) — quản lý bảo mật ở quy mô lớn.

Ví dụ: một bucket có các prefix /finance/…/sales/…. Bucket policy được giữ đơn giản, còn quyền chi tiết nằm ở từng Access Point: Finance Access Point cấp quyền đọc/ghi lên prefix /finance, Sales Access Point cấp quyền đọc/ghi lên prefix /sales, Analytics Access Point chỉ cấp quyền đọc trên toàn bucket. Mỗi nhóm user đi qua đúng Access Point của mình.

Bạn có thể định nghĩa Access Point chỉ truy cập được từ bên trong VPC:

  • Phải tạo một VPC Endpoint để tới được Access Point (Gateway hoặc Interface Endpoint).
  • VPC Endpoint Policy phải cho phép truy cập tới bucket đích và tới Access Point.

Nghĩa là request từ một EC2 instance sẽ lần lượt đi qua ba tầng chính sách: VPC Endpoint PolicyAccess Point PolicyBucket Policy.

Đôi khi các ứng dụng khác nhau cần cùng một object nhưng ở dạng khác nhau: bộ phận analytics cần dữ liệu đã bị che thông tin cá nhân, bộ phận marketing cần dữ liệu đã được làm giàu thêm. Cách cũ là nhân bản dữ liệu thành nhiều bucket. S3 Object Lambda cho phép dùng AWS Lambda Function để thay đổi object trước khi nó được trả về cho ứng dụng gọi.

  • Chỉ cần một S3 bucket duy nhất; bên trên đó bạn tạo S3 Access Point và các S3 Object Lambda Access Point.
  • Mỗi Object Lambda Access Point gắn với một Lambda function riêng — ví dụ một Redacting Lambda Function (che dữ liệu) trả về Redacted Object cho ứng dụng Analytics, và một Enriching Lambda Function (làm giàu dữ liệu, có thể tra thêm từ Customer Loyalty Database) trả về Enriched Object cho ứng dụng Marketing, trong khi ứng dụng E-Commerce đọc Original Object.

Các use case tiêu biểu:

  • Redact (che) thông tin nhận dạng cá nhân cho môi trường analytics hoặc non-production.
  • Chuyển đổi định dạng dữ liệu, ví dụ từ XML sang JSON.
  • Resize và chèn watermark cho ảnh ngay lúc truy xuất, dựa trên thông tin của người gọi — ví dụ user nào đang yêu cầu object đó.
Chủ đề Phải nhớ
SSE-S3 Khóa của AWS, AES-256, header x-amz-server-side-encryption: AES256, bật mặc định
SSE-KMS Khóa trong KMS, kiểm soát + audit bằng CloudTrail, header aws:kms; chịu KMS quota (5.500 / 10.000 / 30.000 req/s tùy region)
SSE-C Khách hàng tự giữ khóa ngoài AWS, S3 không lưu khóa, bắt buộc HTTPS, khóa gửi theo mọi request
Client-Side Client tự mã hóa/giải mã, khách hàng quản lý toàn bộ chu trình
In transit Hai endpoint HTTP/HTTPS; bắt buộc HTTPS bằng bucket policy với aws:SecureTransport
Default Encryption SSE-S3 tự áp cho object mới; Bucket Policy được đánh giá trước Default Encryption
CORS Cơ chế của trình duyệt; preflight OPTIONSAccess-Control-Allow-Origin / -Methods; cho phép origin cụ thể hoặc *
MFA Delete Cần cho xóa vĩnh viễn versionsuspend versioning; yêu cầu Versioning bật; chỉ root account bật/tắt được
Access Logs Ghi mọi request vào bucket khác cùng region; tuyệt đối tránh logging loop
Pre-Signed URL Console 1–720 phút; CLI --expires-in mặc định 3600 s, tối đa 604800 s; người nhận thừa hưởng quyền người tạo
Object Lock WORM, cần Versioning; Compliance (root cũng không xóa) vs Governance (có user ngoại lệ); Legal Hold vô thời hạn
Glacier Vault Lock WORM bằng Vault Lock Policy, lock rồi là không sửa/xóa được
Access Points DNS riêng + policy riêng cho từng nhóm/prefix; VPC Origin cần VPC Endpoint và VPC Endpoint Policy
Object Lambda Lambda biến đổi object lúc đọc; chỉ một bucket; redact PII, đổi XML→JSON, resize/watermark ảnh