我正在使用 S3 REST API 端點作為 CloudFront 分佈的來源。為什麼會收到「403 存取遭拒」錯誤?

4 分的閱讀內容
0

我正在使用 Amazon Simple Storage Service (Amazon S3) 儲存貯體作為 Amazon CloudFront 分佈的來源。我正在使用 S3 REST API 端點作為原始網域名稱。CloudFront 從 Amazon S3 傳回「403 存取遭拒」錯誤。

簡短描述

若要對「存取遭拒」錯誤進行疑難排解,請確定分佈的原始網域名稱是 S3 網站端點還是 S3 REST API 端點。請依照下列步驟尋找端點類型:

1.    開啟 CloudFront 主控台

2.    選擇您的 CloudFront 分佈。然後,選擇分佈設定

3.    選擇源和源群組標籤。

4.    檢閱源網域名稱和路徑下的網域名稱。然後,根據網域名稱的格式確定端點類型。REST API 端點使用下列格式:

DOC-EXAMPLE-BUCKET.s3.region.amazonaws.com
DOC-EXAMPLE-BUCKET.s3.amazonaws.com

**重要:**格式 bucket-name.s3.amazonaws.com 不適用於 2019 或更高版本中啟動的區域。靜態網站端點使用以下格式:

DOC-EXAMPLE-BUCKET.s3-website-us-east-1.amazonaws.com

如果您的分佈使用 S3 靜態網站端點,您可能會收到「403 存取遭拒」錯誤。如需詳細資訊,請參閱我使用 S3 網站端點作為 CloudFront 分佈的來源。為什麼會收到「403 存取遭拒」錯誤?

如果您的分佈使用 REST API 端點,請確認您的組態是否符合下列需求,以避免「存取遭拒」錯誤:

  • 如果您未設定原始存取控制 (OAC)原始存取身分 (OAI),則物件必須可公開存取。或者,您必須請求使用 AWS 第 4 版簽署程序的物件。
  • 如果 S3 儲存貯體包含 AWS Key Management Service (AWS KMS) 加密的物件,則應使用 OAC 代替 OAI。
  • S3 儲存貯體政策必須允許存取 s3:GetObject
  • 如果儲存貯體政策授予存取權,則擁有 S3 儲存貯體的 AWS 帳戶也必須擁有該物件。
  • 請求的物件必須存在於 S3 儲存貯體中。
  • 如果用戶端請求分佈的根目錄,則必須定義預設根物件。
  • 如果您設定了 OAI,OAI 必須包含在 S3 儲存貯體政策中。
  • 如果您設定了 OAC,CloudFront 服務主體必須包含在 S3 儲存貯體政策中。如果您設定了 OAI,OAI 必須包含在 S3 儲存貯體政策中。
  • 如果您未設定 OAC 或 OAI,則必須在儲存貯體上關閉「Amazon S3 封鎖公開存取」。

解決方法

如果您未設定 OAC 或 OAI,則物件必須可公開存取,或使用 AWS 第 4 版簽署程序提出請求。

若要判斷 S3 儲存貯體中的物件是否可公開存取,請在 Web 瀏覽器中開啟 S3 物件的 URL。或者,在 URL 上執行 curl 命令。

以下是 S3 物件的範例 URL:

https://DOC-EXAMPLE-BUCKET.s3.amazonaws.com/index.html

如果 Web 瀏覽器或 curl 命令傳回「存取遭拒」錯誤,則該物件無法公開存取。如果物件無法公開存取,請使用下列其中一個組態:

AWS Key Management Service (AWS KMS) 加密的物件

如果 s3 儲存貯體包含 AWS Key Management Service (AWS KMS) 加密的物件,則應使用 OAC 代替 OAI。

透過設定 OAC,可以使用 CloudFront 提供 AWS KMS 加密的物件。為此,請在 AWS KMS 金鑰政策中新增陳述式,以授予 CloudFront 服務主體使用金鑰的許可。若要在不設定 OAC 的情況下提供 AWS KMS 加密的物件,請使用 Lambda@Edge 提供從 S3 儲存貯體加密的 AWS KMS 金鑰

請使用下列其中一種方式來檢查儲存貯體中的物件是否已經 AWS KMS 加密:

  • 使用 Amazon S3 主控台檢視物件的屬性。檢閱「加密」對話方塊。如果選取了 AWS KMS,則該物件已經 AWS KMS 加密。
  • 使用 AWS Command Line Interface (AWS CLI) 執行 ](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/head-object.html)head-object[ 命令。如果該命令以 aws:kms 傳回 ServerSideEncryption,則表示該物件已經 AWS KMS 加密。如果您在執行 AWS CLI 命令時收到錯誤,請確定您使用的是最新版本的 AWS CLI
    **注意:**OAI 不支援提供 AWS KMS 加密的物件。

S3 儲存貯體政策必須允許存取 s3:GetObject

若要使用具有 S3 REST API 端點的分佈,您的儲存貯體政策必須允許 s3:GetObject 給公共使用者或 CloudFront 的 OAI。即使您的儲存貯體政策中有 s3:GetObject 的明確允許陳述式,請確認沒有衝突的明確拒絕陳述式。明確的拒絕陳述式總是會覆寫明確的允許陳述式。

請依照下列步驟檢閱 s3:GetObject 的儲存貯體政策:

1.    從 Amazon S3 主控台開啟 S3 儲存貯體。

2.    選擇「許可」標籤。

3.    選擇「儲存貯體政策」。

4.    檢閱具有 "Action": "s3:GetObject""Action": "s3:*" 的陳述式的儲存貯體政策。下面的範例政策包含授予 CloudFront OAC 存取 s3:GetObject 的允許陳述式。它還包括授予 CloudFront OAI 存取 s3:GetObject 的陳述式,以及授予公開存取 s3:GetObject 的允許陳述式。但是,s3:GetObject 具有明確的拒絕陳述式,除非請求來自特定的 Amazon Virtual Private Cloud (Amazon VPC),否則會阻止存取:

{
  "Version": "2012-10-17",
  "Id":
    "PolicyForCloudFrontPrivateContent",
  "Statement": [{
      "Sid": "Allow-OAC-Access-To-Bucket",
        "Effect": "Allow",
        "Principal":
    {
            "Service": "cloudfront.amazonaws.com"
        },
        "Action": "s3:GetObject",

    "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*",
        "Condition": {
            "StringEquals": {

    "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/EDFDVBD6EXAMPLE"
            }
        }
      },

    {
      "Sid": "Allow-OAI-Access-To-Bucket",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::cloudfront:user/CloudFront
    Origin Access Identity EAF5XXXXXXXXX"
      },
      "Action": "s3:GetObject",
      "Resource": [
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"

    ]
    },
    {
      "Sid": "Allow-Public-Access-To-Bucket",
      "Effect": "Allow",
      "Principal": "*",

    "Action": "s3:GetObject",
      "Resource": [
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
      ]
    },
    {

    "Sid": "Access-to-specific-VPCE-only",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource":
    [
        "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
      ],
      "Condition": {
        "StringNotEquals": {

    "aws:sourceVpce": "vpce-1a2b3c4d"
        }
      }
    }
  ]
}

5.    修改儲存貯體政策以移除或編輯阻止 CloudFront OAI 存取或公開存取 s3:GetObject 的陳述式

**注意:**CloudFront 會快取「存取遭拒」錯誤的結果,最多可快取五分鐘。從儲存貯體政策中移除拒絕陳述式後,您可以對分佈執行失效以從快取中移除物件。

S3 儲存貯體和物件的所有權

若要套用儲存貯體政策至外部帳戶或服務,擁有該儲存貯體的 AWS 帳戶也必須擁有這些物件。儲存貯體或物件由建立儲存貯體或物件之 AWS Identity and Access Management (IAM) 身分的帳戶所擁有。

**注意:**物件所有權要求適用於儲存貯體政策授予的存取權。它不適用於物件的存取控制清單 (ACL) 授予的存取權。

請依照下列步驟檢查儲存貯體和物件是否具有相同的擁有者:

1.    執行此 AWS CLI 命令以取得儲存貯體擁有者的 S3 標準 ID:

aws s3api list-buckets --query Owner.ID

2.    執行此命令以取得物件擁有者的 S3 標準 ID:

**注意:**此範例顯示單一物件,但您可以使用 list 命令來檢查多個物件。

aws s3api list-objects --bucket DOC-EXAMPLE-BUCKET --prefix index.html

3.    如果標準 ID 不相符,則表示儲存貯體和物件具有不同的擁有者。

**注意:**您也可以使用 Amazon S3 主控台來檢查儲存貯體和物件擁有者。擁有者可以在相應的儲存貯體或物件的「許可」標籤中找到。

請依照下列步驟將物件的擁有者變更為儲存貯體擁有者:

1.    從物件擁有者的 AWS 帳戶中,執行此命令以擷取指派給物件的存取控制清單 (ACL) 許可:

aws s3api get-object-acl --bucket DOC-EXAMPLE-BUCKET --key object-name

2.    如果物件具有儲存貯體擁有者完全控制 ACL 許可,請跳至步驟 3。如果物件沒有儲存貯體擁有者完全控制 ACL 許可,請從物件擁有者的帳戶執行下列命令:

aws s3api put-object-acl --bucket DOC-EXAMPLE-BUCKET
    --key object-name --acl bucket-owner-full-control

3.    從儲存貯體擁有者的帳戶執行此命令,透過將物件複製到自身來變更物件的擁有者:

aws s3 cp s3://DOC-EXAMPLE-BUCKET/index.html
    s3://DOC-EXAMPLE-BUCKET/index.html --storage-class STANDARD

**注意:**確定將範例命令中的 --storage-class 值變更為適用於您使用案例的儲存類別。

請求的物件必須存在於儲存貯體中

如果使用者沒有 s3:ListBucket 許可,則使用者對遺失的物件會收到「存取遭拒」錯誤,而不是「404 找不到」錯誤。執行 head-object AWS CLI 命令,檢查儲存貯體中是否存在物件。

**注意:**確認傳送至 CloudFront 的物件請求是否完全符合 S3 物件名稱。S3 物件名稱區分大小寫。如果請求沒有正確的物件名稱,Amazon S3 的回應就像物件遺失一樣。若要識別 CloudFront 從 Amazon S3 請求哪些物件,請使用伺服器存取記錄

如果物件存在於儲存貯體中,則「存取遭拒」錯誤不會遮罩「404 找不到」錯誤。檢查其他組態需求,以解決「存取遭拒」錯誤。

如果物件不存在於儲存貯體中,則「存取遭拒」錯誤將會遮罩「404 找不到」錯誤。解決遺失物件相關問題。

**注意:**允許公開存取 s3:ListBucket 不是安全最佳實務。允許公開存取 s3:ListBucket 可讓使用者查看和列出儲存貯體中的所有物件。這樣即便使用者沒有下載物件的許可,也會向使用者顯示物件中繼資料詳細資訊,例如金鑰和大小。

如果用戶端請求分佈的根目錄,您必須定義預設根物件

如果您的分佈沒有定義預設根物件,且請求者沒有 s3:ListBucket 存取權,則請求者會收到「存取遭拒」錯誤。請求者在請求分佈的根目錄時會收到此錯誤,而不是「404 找不到」錯誤。

若要定義預設根物件,請參閱指定預設根物件

**注意:**允許公開存取 s3:ListBucket 不是安全最佳實務。允許公開存取 s3:ListBucket 可讓使用者查看和列出儲存貯體中的所有物件。這樣即便使用者沒有下載物件的許可,也會向使用者顯示物件中繼資料詳細資訊,例如金鑰和大小。

OAC 或 OAI 的許可

如果您設定了 OAC,則 CloudFront 服務主體必須包含在 S3 儲存貯體政策中。如果您設定了 OAI,則 OAI 必須包含在 S3 儲存貯體政策中

若要驗證您的儲存貯體政策是否允許 OAI,請在 Amazon S3 主控台中開啟 S3 儲存貯體。然後,選擇「許可」標籤並檢閱儲存貯體政策。在下面的範例政策中,設定 OAC 時,第一個陳述式是 CloudFront 服務主體的允許陳述式。第二個陳述式是 OAI 的允許陳述式:

{
      "Sid": "Allow-OAC-Access-To-Bucket",
        "Effect": "Allow",
        "Principal": {

    "Service": "cloudfront.amazonaws.com"
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*",

    "Condition": {
            "StringEquals": {
                "AWS:SourceArn": "arn:aws:cloudfront::111122223333:distribution/EDFDVBD6EXAMPLE"

    }
     }
      },

{
  "Sid": "1",
  "Effect": "Allow",
  "Principal": {
    "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin
    Access Identity EAF5XXXXXXXXX"
  },
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::DOC-EXAMPLE-BUCKET/*"
}

若要使用 CloudFront 主控台更新儲存貯體政策,請完成下列步驟:

1.    開啟 CloudFront 主控台,然後選擇您的分佈。

2.    選擇源和源群組標籤。

3.    選取S3 原始伺服器,然後選擇編輯

4.    對於限制儲存貯體存取,選擇

5.    對於原始存取身分,選擇現有的身分或建立新的身分。

6.    對於授與對儲存貯體的讀取許可中,選擇是,更新儲存貯體政策

7.    選擇是,編輯

允許公開存取分佈,而無需 OAC 或 OAI

如果您的分佈不使用 OAC 或 OAI,且 AWS 第 4 版簽署程序未請求物件,您必須允許對物件的公開存取。這是因為具有 REST API 端點的分佈僅支援公開可讀物件。在這種情況下,您必須確認沒有套用任何 Amazon S3 封鎖公開存取設定至儲存貯體。這些設定將覆寫允許公開讀取存取權。Amazon S3 封鎖公開存取設定可套用至個別儲存貯體或 AWS 帳戶。


相關資訊

對來源的錯誤回應進行疑難排解

如何對來自 Amazon S3 的「403 存取遭拒」錯誤進行疑難排解?

AWS 官方
AWS 官方已更新 1 年前