Study Notes - AWS S3


S3 全名是 Simple Storage Service,故縮寫 S3,它是 AWS 在 2006 年推出的 第二個 SaaS 服務,有很長的歷史。雖然名字有個 Simple,但其實它非常複雜,本文整理研讀官方文件、以及工作上遇到的問題,整理以下的筆記:

  • 一、基本概念 (Concepts)
  • 二、核心功能 (Core Functions)
  • 三、存取權限 (Access Control)
  • 四、資料保護 (Data Protection)
  • 五、服務限制 (Limitation)
  • 六、開發 (Development)
  • 七、成本 (Cost)
  • 八、應用場景 (User Scenarios)
  • 九、常見問答 (FAQ)
  • 十、最佳實踐 (Best Practice)

一、基本概念 (Concepts)

整理幾個 S3 的核心概念:

  • Buckets
  • Objects
  • Keys
  • Resions
  • Data Consistency Model

Bucket

Bucket 中文可以翻譯成水桶、籃子,是容器 (Container) 的概念,也就是可以放東西的容器。

在 S3 裡的 Bucket 名稱是 唯一的、而且是全域 (Global)、跨 Account、跨 Region 的,換言之,不管是哪一個 AWS 的使用者,Bucket Name 都不能與其他人重複。雖然 Bucket 名稱是唯一的識別,但是建立 Bucket 時要選擇 Region,表示實際上資料 Region Level 的,換言之,如果在乎存取的延遲時間,就要注意 Region 的位置。

Bucket Name 與 Static WebSite 的關係後面段落詳細說明。

Bucket 名稱的命名規則

底下是 AWS 官方建議的命名注意事項:

  • 命名要符合 DNS 命名規範,例如不可以用底線 (_, underscore)、大寫字母 (uppercase, 2018/03 後)
    • 因為這名稱會被拿區當作 DNS 名稱,DNS 命名不允許有底線。
  • 長度至少 3 個字元,最多 63 個字元
  • 名稱開始要小寫字母或者數字
  • 不要使用 IP address 當作名稱
  • 名稱不要包含點 . 當作段落的切割字元。
    • 目前可以使用,沒有阻擋。
    • 如果要使用 Transfer Acceleration,那 bucket name 不可以包含點

Bucket Name 命名建議格式:{ACCOUNT_NAME}-{REGION}-{PURPOSE}

  • 建議使用 AWS Account Name 做開頭,避免與其他使用者衝突。在 IAM 的首頁可以設定,這個名稱也被當來 IAM Login 的 URL,例如:https://{AWS_ACCOUNT_NAME}.signin.aws.amazon.com/console
  • 例如我的一個 AWS Account Name 叫做 gtlab01,那麼 bucket name 的開頭就是 gtlab01-us-west-2-s3-lab,如此不會與其他人衝突,也可以區分不同 region 的 bucket。
  • 命名格式後面可以自行延伸,主要就是前置 ({ACCOUNT_NAME}-{REGION}) 與切割符號 (我使用 -) 要注意,後面可以延續其他實際的用途,像是環境、服務名稱 … etc.

功能全貌

每個 Bucket 除了儲存的物件之外,都會有三大主要的功能區塊,展開有以下:

  • Properties
    • Versioning: 物件的版本管理
    • Server Access Logging: 存取紀錄
    • Staitc Website Hosting: 靜態資料網站
    • Object-level Logging: 紀錄 API 存取的紀錄,主要配合 CloudTrail
    • Default Encryption: 預設的加密方式
    • Advanced: Object Lock、Tags、Transfer Acceleration、Events、Requester Pays … 等,後面分段描述。
  • Permission: Block Public Access, Access Control List, Bucket Policy, CORS
  • Management: Lifecycle、Replication、Analytics、Metric、Inventory

詳細介紹整理在後面。

Objects

S3 是一個 Object Store,存放在 S3 Bucket 裡的東西都稱為 Object (物件),一個 Object 由以下組成:

  • Key: 有時候會稱 Object Key、Key Name,在 Bucket 裡的唯一識別
  • Version Id: 在 Bucket 裡,Key 和 Version ID 的組成,識別出一個 Object。S3 以此做到 Object Versioning 功能。
  • Value: 就是實際儲存的資料內容。單一資料最大 5TB。
  • Metadata: 是一個 Key-Value 的資料結構,儲存物件的控制資訊。分成 User-definied MetadataSystem-defined Metadata 兩大類。
  • Subresources: 定義 Bucket 與 Object 關係的。
  • Access Control Information

整理下圖描述整個 Object 的組成:

Object Keys

也稱做 Object Key、Key Name,在 Bucket 裡是唯一識別,由 (Prefix + Delimiter) + Key Name 組成。整理概念如下圖:

Prefix 可以想像成目錄 (Folder) 的概念,透過 Delimiter (/) 隔開。以此規則,例如:

  • Bucket Name: www.abc.com
  • Key:
    • dev/design.md
    • dev/seq-flow.md
    • marketing/rel/purchese.pdf
    • index.html

這四個都是 Key,只是 index.html 沒有 prefix,其他則有。在 S3 Console 就會看到目錄的結構。

Version Id

S3 支援 Object 的版本管理,稱為 Versioning。每個物件都有屬於自己的 Version Id 用來區別版本。詳細後面描述。

Object Metadata

Object Metadata 由 Key-Value 組成的資料結構,分成兩個部分: System-defined Metadata (SDM)User-defined Metadata (UDM),整理概念如下圖:

SDM 主要是 S3 用來系統資訊和控制屬性的。系統資訊像是時間、日期、MD5 … 等;控制屬性像是 server-side encryption 的是否開啟、version-id、Storage Class。大概分成可以修改與不可以修改兩大部分。下圖摘自官方文件的詳細列表:

放一個 Object,並指定 UDM:

1
2
3
4
5
6
7
8
9
10
11
12
13
aws s3api put-object \
--acl private \
--body s3-permission-control-flow.png \
--bucket gtcafe-dev-us-west-2-lab-s3 \
--key pic/s3-permission-control-flow.png \
--metadata type=picture,ttatus=Release,version=1 \
--tagging date=20190614,team=operation

# return result
{
"ETag": "\"74977eb17855dee8451f477f9e9c04c8\"",
"VersionId": "5iVAfsiL3CLRPq9UAFuTVpxiwjz1xUmn"
}

取得 Object:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
aws s3api head-object \
--bucket gtcafe-dev-us-west-2-lab-s3 \
--key pic/s3-permission-control-flow.png

# return result
{
"AcceptRanges": "bytes",
"LastModified": "Fri, 14 Jun 2019 06:43:51 GMT",
"ContentLength": 175470,
"ETag": "\"74977eb17855dee8451f477f9e9c04c8\"",
"VersionId": "5iVAfsiL3CLRPq9UAFuTVpxiwjz1xUmn",
"ContentType": "binary/octet-stream",
"Metadata": {
"version": "1",
"status": "Release",
"type": "picture"
}
}

Storage Classes

儲存在 S3 上的物件,依照使用情境與需求,分成幾種 儲存類型 (Storage Classes),這些類型也會反映在 SLA (可用性、持久性)成本效能之上。下表是 官方文件 的提供的資訊:

Regions

建立 Bucket 的時候,除了名稱要考慮唯一性之外,也要選擇 Bucket 的位置。官方文件描述,只要物件存在 Region 之內,就不會再離開,除非使用者自行傳輸到其他地方。所以當應用程式需要考量傳輸效能時,在規劃 Bucket 時也要同時考慮地理位置,避免因為網路傳輸的問題,影響效能。

Data Consistency Model (資料一致性模式)

  • 所有的 Region 的支援 PUTS and DELETES 操作的 最終一致性模型
  • 寫入新的 Object 而且立刻 list bucket: 新的 Object 不會顯示在 list ,直到更改傳遞到所有的 servers
    • PUTS: read-after-write consistency
  • 更新既有的物件,同時立刻讀取:S3 可能會傳回前一個物件,直到更改傳遞到所有的 servers
  • 刪除既有物件,同時立刻讀取:S3 可能回傳要刪除的物件,直到更改傳遞到所有的 servers
  • 刪除既有物件,同時 list bucket 裡的 keys: S3 可能還是會顯示刪除的 object,直到更改傳遞到所有的 servers
  • 目前 S3 不支援 Object Locking

下表描述 Eventually Consistent Read (最終一致性讀取) & Consistent Read (一致性讀取) 的差異:

更多關於 最終一致性 的概念,參閱 Eventually Consistent 與 Dynamo NWR 模型


二、核心功能 (Core Functions)

S3 除了存資料之外,有很多因應而生的功能,這些功能都很實用,也是很多人選擇 S3 的主因。

以下整理一些我個人認為的核心功能,我把他們分成兩大類:

  • 應用功能:應用服務使用的功能,主要是提供 Feature、創造價值,屬於進攻。
  • 管理功能:維運管理功能,主要是針對資安、節省成本,屬於防守。

Static Website Hosting

有以下幾種方法可以讓 S3 當作靜態網頁服務:

  1. 使用 S3 Bucket 的 Static Website Hosting 功能 (沒有 HTTPS)
  2. 整合 Route 53 Alias + S3 Bucket (沒有 HTTPS)
  3. 整合 CloudFront + Route 53 Alias + S3 Bucket (有 HTTPS)

S3 Bucket + Route53

  1. 建立 S3 Bucket
    • 使用 Domain Name 當作 S3 Bucket Name,例如:website1.gtcafe.com,此例子放在 us-west-2
    • 開啟 Static Website Hosting 功能,一定要開啟,否則功能不會正常(如下訊息)。
    • 權限:
      • 關閉 Block public access,預設是開啟的。因為太多資安事件,後來新增的預設功能。
      • 用 Bucket Policy 或 Object ACL ,後面描述
    • 放一個 index.html
  2. 設定 Route 53
    • 新增一筆 A Record
    • 開啟 Alias,選擇已經建立好的 S3 Bucket,或者填入:s3-website-us-west-2.amazonaws.com.。 如果 AutoComplete 沒有 S3 Bucket 可以選,表示沒有開啟 Static Website Hosting,如果已經開啟卻沒得選,重新載入 Route53 Console。如下圖:
  3. 權限設定:要讓使用者可以瀏覽靜態資料

    • Bucket Policy:好處是 Object 上傳後,不需要額外的權限設定。底下是範例:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      {
      "Version": "2012-10-17",
      "Statement": [
      {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::website1.gtcafe.com/*"
      }
      ]
      }
    • Object ACL:開啟個別 Object 的 Permission,方法有以下:

      • 在 S3 Console,選擇 Object -> “Make Public”
      • 在 S3 Console:點選 Object -> 右邊 Properties -> Permission -> Public access -> 開啟 Read Object
      • 透過 SDK / API 操作(如下),指定 ACL 為 public-read
        1
        2
        3
        4
        5
        6
        7
        aws s3api put-object \
        --acl public-read \
        --body s3-permission-control-flow.png \
        --bucket website1.gtcafe.com \
        --key images/s3-permission-control-flow.png \
        --content-type image/png \
        --content-disposition "inline; filename=s3-permission-control-flow.png"

權限兩種方法都可以,如果要安全性高一點,選擇 Object ACL 控制,透過程式控制;如果是開放資料,像是文件,則可以使用 Bucket Policy 控制。

Endpoints of Path-Style and Virtual-Hosted Style

S3 支援兩種存取格式的 Endpoints,格式如下:

  1. Path-Style (v1):
    • Bucket in us-east-1: https://s3.amazonaws.com/{BUCKET_NAME}/{OBJECT_KEY_NAME}
    • Bucket in other regions: https://s3-{REGION_CODE}.amazonaws.com/{BUCKET_NAME}/{OBJECT_KEY_NAME}
  2. Virtual-Hosted Style (v2)
    • Bucket in us-east-1: 同下
    • Bucket in other regions: http://{BUCKET_NAME}.s3-website-{REGION_CODE}.amazonaws.com/{OBJECT_KEY_NAME}

為了方便說明,我建立兩個 Bucket 當範例:

  1. website.gtcafe.com -> region 在 us-east-1 (N. Virginia)
  2. website1.gtcafe.com -> region 在 us-west-2 (Oregon)

Path-Style 是第一代 (1) 的格式,選擇一個 Object,下圖是 Overview,這是放在 Virginia 的 Object URL:

下圖是放在 Oregon 的 Object URL,有包含 REGION_CODE: us-west-2

不難發現,Path-Style 就是以 Region 為主要的 Hostname,然後把 Bucket Name 當作 URL 路徑看待,而且支援 HTTPS。另外 Virginia 因為是第一個 region,所以預設的 S3 Domain Name 就是給他用,其他則有個別的 Domain Name.

Virtual-Hosted Style 是第二代 (v2) 的格式,主要就是以 Bucket Name 作為 Hostname。同樣的用 us-east-1、us-west-2 做範例,如下圖,在 Bucket -> Properties -> Static Website Hosting 找存取的 Endpoint:


要注意的是:Path-Style 支援 HTTPS,但是 Virtual-Hosted Style 並不支援,如果要 HTTPS 需要依賴 CloudFront。

相關新聞:

Event Notifications

Events: SNS, SQS, Lambda

Lifecycle Management

Monitoring

Others

其他本文尚未整理的功能。

  • Batch
  • Transfer Acceleration: Spped up data uploads using CloudFront in reverse.
  • BitTorrent

三、存取權限 (Access Control)

S3 存取的授權方式有兩種:Resource-based policiesUser Policies。底下整理自 Overview of Managing Access

Resource-based Policies

概念如下圖 (取自 官方文件),分成針對 Bucket 的 Bucket PolicyBucket ACL,以及針對 S3 Object 的 Object ACLs

Bucket ACLs / Object ACLs: 每個 Bucket 和 Object 都有一個 ACL 的關聯。ACLs 用來針對特定 識別 發放權限。像是可以發放給另一個 AWS Account 權限。可以透過設定 Account Canonical User ID ,讓另一個帳號可以存取 Bucket(但是不會在 Bucket List 上出現)。可設定的資訊如下:

  • Canonical User ID: 是個 Long String,大概像這樣:7ae3d7f85d42d21d250ff1c13b3b8ec92189bedbd648252984ba6526a3b071d1,可以在 S3 Bucket ACL 裡找到。
  • Bucket ACLs:
    • List Objects、Write Objects、Read Bucket Permissions、Write Bucket Permissions
  • Object ACLS:
    • Read Objects、Read Object Permissions、Write Object Permissions
    • 注意:沒有 Write Objects

Bucket ACLs 以 XML 呈現,新版的 S3 Console 透過 GUI 設定即可。舊版的 Console 則需要自行設定 XML,格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Owner>
<ID>*** Owner-Canonical-User-ID ***</ID>
<DisplayName>owner-display-name</DisplayName>
</Owner>
<AccessControlList>
<Grant>
<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="Canonical User">
<ID>*** Owner-Canonical-User-ID ***</ID>
<DisplayName>display-name</DisplayName>
</Grantee>
<Permission>FULL_CONTROL</Permission>
</Grant>
</AccessControlList>
</AccessControlPolicy>

Bucket Policy: 主要發放權限給 AWS Account 或者 IAM Users,整個 Bucket 與 Object 都會應用 Policy。Policy 的設定同 IAM Policy 的設計,每個 Statement 主要有必要的 Effect、Principal、Action、Resource 以及選擇性的 Condition。

Principal 用來授權給哪一個 AWS Account 或者 特定的 Canonical User ID。AWS Account 使用的就是 ARN 格式,例如:

1
2
3
4
5
6
"Principal": {
"AWS": [
"arn:aws:iam::AccountNumber-WithoutHyphens:root",
"arn:aws:iam::AccountNumber-WithoutHyphens:user/user1"
]
}

Canonical User ID 範例:

1
2
3
"Principal": {
"CanonicalUser": "64-digit-alphanumeric-value"
}

Condition 通常用來篩選條件,像是控制來源 IP、特定的 http header … etc。底下範例是授權特定來源 IP 存取的範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::examplebucket/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "192.168.143.0/24"
},
"NotIpAddress": {
"aws:SourceIp": "192.168.143.188/32"
}
}
}
]
}

User policy

這個 User 指的是 AWS IAM,包含 IAM users、groups、roles,概念如 官方文件 的圖:

IAM 相關概念請參閱 Study Notes - Identity and Access Management (IAM) 的整理

S3 如何處理授權請求?

官方文件: How Amazon S3 Authorizes a Request 針對 Bucket Operation 和 Object Operation 有兩張圖,比較複雜,下圖是我自己簡化的整理。主要以 IAM User 的角度出發,分成三個驗證步驟:

  1. 確認是否符合 Bucket ACL,主要確認是不是 CanonicalUser
  2. 是否符合 Bucket Policy 的條件,預設 Bucket Policy 是空的。
  3. 如果 2) 不符合,那麼看看是否符合 IAM Policy

CORS

https://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<CORSConfiguration>
<CORSRule>
<AllowedOrigin>http://www.example1.com</AllowedOrigin>

<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>

<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>http://www.example2.com</AllowedOrigin>

<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>

<AllowedHeader>*</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
</CORSRule>
</CORSConfiguration>

四、資料保護 (Data Protection)

Data Encryption

SSE-S3 (AES-256), SSE-C, SSE-KMS, Client-Side (PGP, GPG)

Versioning

Object Lock


五、服務限制 (Limitiation)

Bucket Restrictions and Limitation

https://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html
https://aws.amazon.com/tw/about-aws/whats-new/2018/07/amazon-s3-announces-increased-request-rate-performance/


六、開發 (Development)

Amazon S3 REST API Introduction

  • Static Website: {BUCKET_NAME}.s3-website-{REGION_CODE}.amazonaws.com

    REST API:

  • Path-Style:
    • us-east-1: https://s3.amazonaws.com/{BUCKET_NAME}/
    • other regions: https://s3-{REGION_CODE}.amazonaws.com/{BUCKET_NAME}/
  • Virtual-Hosted Style: https://{BUCKET_NAME}.s3-{REGION_CODE}.amazonaws.com


註記:


七、成本 (Cost)

Storage Classes


八、應用場景 (User Scenarios)

應用場景我分成兩大類:解決方案、功能特性。解決方案通常會整合其他 AWS Services,整體也比較複雜;功能特性會著重在 S3 自身的功能應用。

  • 解決方案 (Solution)
    • 靜態資料傳遞:搭配 CloudFront
    • 非同步批次處理:搭配 Lambda
    • Log 儲存與分析:搭配 Kinesis Firehose、Athena
    • 跨區資料備份與同步
  • 功能特性
    • Pre-signed URL
    • 在 EC2 使用 S3 當作延伸磁碟
    • 如何跨帳號存取 S3 Bucket

跨帳號存取 S3 Bucket

AWS Account A 有一個 Bucket 叫做: Acc-A-Bucket1,AWS Account B 有個 User 叫做 user1,想要存取此 Bucket。

  1. 取得 Account B 的 Canonical User Id,然後到 Acc-A-Bucket1 Permissions -> ACLs -> Access for other AWS accounts,加入 CU ID.
  2. 驗證:使用 user1 的 profile 下 CLI

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ## List Bucket and Object
    ~$ aws s3 ls s3://Acc-A-Bucket1/
    2019-06-10 22:53:22 0
    2019-06-10 22:53:52 38201 AccessControlAuthorizationFlowBucketResource.png
    2019-06-10 22:53:52 50491 AccessControlAuthorizationFlowObjectResource.png
    2019-06-10 22:53:58 1410705 Amazon-S3.png
    2019-06-10 22:53:52 23472 resource-based-policy.png
    2019-06-10 22:53:51 18793 user-policy.png

    ## 複製檔案:無法存取
    ~$ aws s3 cp s3://Acc-A-Bucket1/user-policy.png .
    fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
  3. 設定 Acc-A-Bucket1 的 Bucket Policy,如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Principal": {
    "AWS": "arn:aws:iam::1234567890123:user/user1"
    },
    "Action": "s3:*",
    "Resource": "arn:aws:s3:::Acc-A-Bucket1/*"
    }
    ]
    }
  4. 驗證:使用 user1 的 profile 下 CLI:

    1
    2
    ~$ aws s3 cp s3://Acc-A-Bucket1/user-policy.png .
    download: s3://Acc-A-Bucket1/user-policy.png to ./user-policy.png

結論:

  • 跨帳號授權,必須在目標 Bucket 上設定同時 ACL 與 Bukcet Policy
  • 原 IAM USer 的 IAM Policy 不需要額外設定權限。

在 EC2 使用 S3 當作延伸磁碟

Storage Gateway

Pre-signed URL

https://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html

https://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURL.html


九、常見問答 (FAQ)

Q: 使用 S3 當靜態網站,能支援 HTTPS?

目前 S3 website endpoint 不支援 HTTPS,通常會搭配 CloudFront + ACM。參見 Website Endpoints

Q: 使用 S3 當靜態網站,能限定來源 IP?或者特定 VPC?

Q: 存放在 S3 上的資料,檔案名稱 (Object Key) 是否要分散成亂數?例如使用 UUID 命名?

https://aws.amazon.com/blogs/aws/amazon-s3-performance-tips-tricks-seattle-hiring-event/

Q: 每個 Object 的 Metadata 上有一個 ETag 是做什麼的?

The entity tag is a hash of the object. The ETag reflects changes only to the contents of an object, not its metadata. The ETag may or may not be an MD5 digest of the object data. Whether or not it is depends on how the object was created and how it is encrypted as described below:

https://docs.aws.amazon.com/AmazonS3/latest/API/RESTCommonResponseHeaders.html
https://teppen.io/2018/06/23/aws_s3_etags/

Q: S3 可以當 FTP 站嗎?

Q: S3 的授權有分 Resource-based Policy 和 User Policies,應該使用哪一種存取方法?

Q: Static Web Hosting 有沒有 Access Log 可以查?

https://docs.aws.amazon.com/AmazonS3/latest/dev/LoggingWebsiteTraffic.html

Q: 如果沒有給 IAM Policy 的權限,但有 Bucket Policy,那麼同一個 Account 底下的 IAM User 可以存取 Bucket?

可以。底下是一個 Bucket Policy 範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::123456689012:user/user1",
"arn:aws:iam::123456689012:user/user2"
]
},
"Action": [
"s3:GetObject",
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::image.abc.com/*",
"arn:aws:s3:::image.abc.com"
]
}
]
}

Q: CloudFront 與 S3 整合的時候,需要開啟 Static Website Hosting?

Q: S3 Bucket 做 Static Web Hosting,可否限制特定網站存取?

可以。確認 Browser 送出的 Request 會包含 http referer,然後透過 Bucket Policy 的 Condition,限制 Referer 的 Domain Name 即可,底下範例是首頁放在 bucket www.abc.com,圖檔放在 bucket image.abc.com,這個 Bucket Policy 設定在 image.abc.com:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"Version": "2012-10-17",
"Id": "image.abc.com",
"Statement": [
{
"Sid": "Allow get requests originating from www.abc.com and abc.com.",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::image.abc.com/*",
"Condition": {
"StringLike": {
"aws:Referer": [
"http://www.abc.com/*",
"http://abc.com/*"
]
}
}
}
]
}

Q: AWS CLI 提供 s3 和 s3api,這兩個有什麼差別?

s3 是 high-level commands,s3api 則是 low-level commands,差異就是可控性。想要控制細緻的參數,像是 max_concurrent_requests、max_queue_size、max_bandwidth、multipart_threshold … 等效能的調教與除錯,那麼就要使用 s3api,詳細的配置參閱 AWS CLI S3 Configuration

Q: Virtual-Hosted Style 提到 S3 Bucket Name 會變成 Hostname,如果名稱有很多點 . 會不會有問題?

實測 bucket name: a.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9.0.1.2.3.4.5.6.7.8.9.0.1,長度 63,結果是可以運行的,如下圖。依據 wikipeida 上對 DNS 的描述,節點數最多可以到 127 個,但是這個規範並沒有被定義在 RFC 裡。

Q: 有一些 AWS 服務建立的 Bucket (elasticbeanstalk-ap-northeast-1-{AWS_ACCOUNT_ID}) 無法刪除,可以刪?

通常是因為被 Bucket Policy 鎖住了,清空後就可以依照一般程序刪除 bucket 了。底下是其中一個由 EB 建立的 Policy,裡面有 Deny DeleteBucket:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "eb-ad78f54a-f239-4c90-adda-49e5f56cb51e",
"Effect": "Allow",
"Principal": {
"AWS": "AROAILKGB6ZL4XGFMJBBY"
},
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::elasticbeanstalk-us-east-1-123456789012/resources/environments/logs/*"
},
{
"Sid": "eb-58950a8c-feb6-11e2-89e0-0800277d041b",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:DeleteBucket",
"Resource": "arn:aws:s3:::elasticbeanstalk-us-east-1-123456789012"
},
{
"Sid": "eb-af163bf3-d27b-4712-b795-d1e33e331ca4",
"Effect": "Allow",
"Principal": {
"AWS": [
"AROAILKGB6ZL4XGFMJBBY",
"AROAI3S3HFNQTDLUITG52"
]
},
"Action": [
"s3:ListBucket",
"s3:ListBucketVersions",
"s3:GetObject",
"s3:GetObjectVersion"
],
"Resource": [
"arn:aws:s3:::elasticbeanstalk-us-east-1-123456789012",
"arn:aws:s3:::elasticbeanstalk-us-east-1-123456789012/resources/environments/*"
]
}
]
}


十、最佳實踐 (Best Practice)

保護 S3 資料的方法

  • IAM Policy
  • Encryption: Client and Server Sides
  • Bucket Versioning
  • MFA Delete

延伸閱讀

站內延伸

官方文件

Deep Dive and Whitepapers

更新紀錄

  • 2019/06/11: 重構文章結構,分成數個部分。
  • 2017/09/03: 更新 S3 + CloudFront 整合

Comments